From 1e07dbec63bced51857e67b00941b91ca86a7f77 Mon Sep 17 00:00:00 2001 From: Tavares André Date: Thu, 11 Jun 2015 20:25:12 +0200 Subject: Reports - Add Users activities --- .../Localization/Server/server.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 49a912012..3f28e90ea 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1448,6 +1448,7 @@ "OptionReportList": "List View", "OptionReportStatistics": "Statistics", "OptionReportGrouping": "Grouping", + "OptionReportActivities": "Activities Log", "HeaderExport": "Export", "HeaderColumns": "Columns", "ButtonReset": "Reset", @@ -1455,5 +1456,9 @@ "ButtonUnlockGuide": "Unlock Guide", "LabelEnableFullScreen": "Enable fullscreen mode", "LabelEnableChromecastAc3Passthrough": "Enable Chromecast AC3 Passthrough", - "LabelSyncPath": "Synced content path:" + "LabelSyncPath": "Synced content path:", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity" } -- cgit v1.2.3 From 0fa55fd6de42b683bcdcc0c632f4db1436bca36d Mon Sep 17 00:00:00 2001 From: Tavares André Date: Tue, 30 Jun 2015 20:38:09 +0200 Subject: Reports - icons and people fix --- .../Reports/Activities/ReportActivitiesBuilder.cs | 12 +- MediaBrowser.Api/Reports/ReportsService.cs | 2348 ++++++++++---------- MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs | 464 ++-- .../Localization/Server/server.json | 7 +- 4 files changed, 1493 insertions(+), 1338 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs b/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs index 4e2e85846..34115812e 100644 --- a/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs +++ b/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs @@ -159,7 +159,17 @@ namespace MediaBrowser.Api.Reports break; case HeaderMetadata.UserPrimaryImageTag: - option.Column = (i, r) => i.UserPrimaryImageTag; + //option.Column = (i, r) => i.UserPrimaryImageTag; + option.Column = (i, r) => + { + if (!string.IsNullOrEmpty(i.UserId)) + { + MediaBrowser.Controller.Entities.User user = _userManager.GetUserById(i.UserId); + if (user != null) + return user.PrimaryImagePath; + } + return string.Empty; + }; option.Header.SortField = ""; break; case HeaderMetadata.Severity: diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs index ebf5183c5..2c0728719 100644 --- a/MediaBrowser.Api/Reports/ReportsService.cs +++ b/MediaBrowser.Api/Reports/ReportsService.cs @@ -24,1139 +24,1219 @@ using System.Text; namespace MediaBrowser.Api.Reports { - /// The reports service. - /// - public class ReportsService : BaseApiService - { - - - /// Manager for user. - private readonly IUserManager _userManager; - - /// Manager for library. - private readonly ILibraryManager _libraryManager; - /// The localization. - private readonly ILocalizationManager _localization; - - /// - /// Initializes a new instance of the MediaBrowser.Api.Reports.ReportsService class. - /// Manager for user. - /// Manager for library. - /// The localization. - public ReportsService(IUserManager userManager, ILibraryManager libraryManager, ILocalizationManager localization) - { - _userManager = userManager; - _libraryManager = libraryManager; - _localization = localization; - } - - /// Gets the given request. - /// The request. - /// A Task<object> - public async Task Get(GetReportHeaders request) - { - if (string.IsNullOrEmpty(request.IncludeItemTypes)) - return null; - - ReportViewType reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); - ReportBuilder reportBuilder = new ReportBuilder(_libraryManager); - var reportResult = reportBuilder.GetReportHeaders(reportRowType, request); - - return ToOptimizedResult(reportResult); - - } - - /// Gets the given request. - /// The request. - /// A Task<object> - public async Task Get(GetItemReport request) - { - if (string.IsNullOrEmpty(request.IncludeItemTypes)) - return null; - - var reportResult = await GetReportResult(request); - - return ToOptimizedResult(reportResult); - } - - /// Gets the given request. - /// The request. - /// A Task<object> - public async Task Get(GetReportDownload request) - { - if (string.IsNullOrEmpty(request.IncludeItemTypes)) - return null; - - var headers = new Dictionary(); - string fileExtension = "csv"; - string contentType = "text/plain;charset='utf-8'"; - - switch (request.ExportType) - { - case ReportExportType.CSV: - break; - case ReportExportType.Excel: - contentType = "application/vnd.ms-excel"; - fileExtension = "xls"; - break; - } - - var filename = "ReportExport." + fileExtension; - headers["Content-Disposition"] = string.Format("attachment; filename=\"{0}\"", filename); - headers["Content-Encoding"] = "UTF-8"; - - ReportViewType reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); - ReportBuilder reportBuilder = new ReportBuilder(_libraryManager); - QueryResult queryResult = await GetQueryResult(request).ConfigureAwait(false); - ReportResult reportResult = reportBuilder.GetReportResult(queryResult.Items, reportRowType, request); - - reportResult.TotalRecordCount = queryResult.TotalRecordCount; - - string result = string.Empty; - switch (request.ExportType) - { - case ReportExportType.CSV: - result = new ReportExport().ExportToCsv(reportResult); - break; - case ReportExportType.Excel: - result = new ReportExport().ExportToExcel(reportResult); - break; - } - - object ro = ResultFactory.GetResult(result, contentType, headers); - return ro; - } - - /// Gets the given request. - /// The request. - /// A Task<object> - public async Task Get(GetReportStatistics request) - { - if (string.IsNullOrEmpty(request.IncludeItemTypes)) - return null; - var reportResult = await GetReportStatistic(request); - - return ToOptimizedResult(reportResult); - } - - /// Gets report statistic. - /// The request. - /// The report statistic. - private async Task GetReportStatistic(GetReportStatistics request) - { - ReportViewType reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); - QueryResult queryResult = await GetQueryResult(request).ConfigureAwait(false); - - ReportStatBuilder reportBuilder = new ReportStatBuilder(_libraryManager); - ReportStatResult reportResult = reportBuilder.GetReportStatResult(queryResult.Items, ReportHelper.GetRowType(request.IncludeItemTypes), request.TopItems ?? 5); - reportResult.TotalRecordCount = reportResult.Groups.Count(); - return reportResult; - } - - /// Gets report result. - /// The request. - /// The report result. - private async Task GetReportResult(GetItemReport request) - { - - ReportViewType reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); - ReportBuilder reportBuilder = new ReportBuilder(_libraryManager); - QueryResult queryResult = await GetQueryResult(request).ConfigureAwait(false); - ReportResult reportResult = reportBuilder.GetReportResult(queryResult.Items, reportRowType, request); - reportResult.TotalRecordCount = queryResult.TotalRecordCount; - - return reportResult; - } - - /// Gets query result. - /// The request. - /// The query result. - private async Task> GetQueryResult(BaseReportRequest request) - { - // Placeholder in case needed later - request.Recursive = true; - var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; - request.Fields = "MediaSources,DateCreated,Settings,Studios,SyncInfo,ItemCounts"; - - var parentItem = string.IsNullOrEmpty(request.ParentId) ? - (user == null ? _libraryManager.RootFolder : user.RootFolder) : - _libraryManager.GetItemById(request.ParentId); - - var item = string.IsNullOrEmpty(request.ParentId) ? - user == null ? _libraryManager.RootFolder : user.RootFolder : - parentItem; - - IEnumerable items; - - if (request.Recursive) - { - var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); - return result; - } - else - { - if (user == null) - { - var result = await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); - return result; - } - - var userRoot = item as UserRootFolder; - - if (userRoot == null) - { - var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); - - return result; - } - - items = ((Folder)item).GetChildren(user, true); - } - - return new QueryResult { Items = items.ToArray() }; - - } - - /// Gets items query. - /// The request. - /// The user. - /// The items query. - private InternalItemsQuery GetItemsQuery(BaseReportRequest request, User user) - { - var query = new InternalItemsQuery - { - User = user, - IsPlayed = request.IsPlayed, - MediaTypes = request.GetMediaTypes(), - IncludeItemTypes = request.GetIncludeItemTypes(), - ExcludeItemTypes = request.GetExcludeItemTypes(), - Recursive = true, - SortBy = request.GetOrderBy(), - SortOrder = request.SortOrder ?? SortOrder.Ascending, - - Filter = i => ApplyAdditionalFilters(request, i, user, true, _libraryManager), - StartIndex = request.StartIndex, - IsMissing = request.IsMissing, - IsVirtualUnaired = request.IsVirtualUnaired, - IsUnaired = request.IsUnaired, - CollapseBoxSetItems = request.CollapseBoxSetItems, - NameLessThan = request.NameLessThan, - NameStartsWith = request.NameStartsWith, - NameStartsWithOrGreater = request.NameStartsWithOrGreater, - HasImdbId = request.HasImdbId, - IsYearMismatched = request.IsYearMismatched, - IsUnidentified = request.IsUnidentified, - IsPlaceHolder = request.IsPlaceHolder, - IsLocked = request.IsLocked, - IsInBoxSet = request.IsInBoxSet, - IsHD = request.IsHD, - Is3D = request.Is3D, - HasTvdbId = request.HasTvdbId, - HasTmdbId = request.HasTmdbId, - HasOverview = request.HasOverview, - HasOfficialRating = request.HasOfficialRating, - HasParentalRating = request.HasParentalRating, - HasSpecialFeature = request.HasSpecialFeature, - HasSubtitles = request.HasSubtitles, - HasThemeSong = request.HasThemeSong, - HasThemeVideo = request.HasThemeVideo, - HasTrailer = request.HasTrailer, - Tags = request.GetTags(), - OfficialRatings = request.GetOfficialRatings(), - Genres = request.GetGenres(), - Studios = request.GetStudios(), - StudioIds = request.GetStudioIds(), - Person = request.Person, - PersonIds = request.GetPersonIds(), - PersonTypes = request.GetPersonTypes(), - Years = request.GetYears(), - ImageTypes = request.GetImageTypes().ToArray(), - VideoTypes = request.GetVideoTypes().ToArray(), - AdjacentTo = request.AdjacentTo - }; - - if (!string.IsNullOrWhiteSpace(request.Ids)) - { - query.CollapseBoxSetItems = false; - } - - foreach (var filter in request.GetFilters()) - { - switch (filter) - { - case ItemFilter.Dislikes: - query.IsLiked = false; - break; - case ItemFilter.IsFavorite: - query.IsFavorite = true; - break; - case ItemFilter.IsFavoriteOrLikes: - query.IsFavoriteOrLiked = true; - break; - case ItemFilter.IsFolder: - query.IsFolder = true; - break; - case ItemFilter.IsNotFolder: - query.IsFolder = false; - break; - case ItemFilter.IsPlayed: - query.IsPlayed = true; - break; - case ItemFilter.IsRecentlyAdded: - break; - case ItemFilter.IsResumable: - query.IsResumable = true; - break; - case ItemFilter.IsUnplayed: - query.IsPlayed = false; - break; - case ItemFilter.Likes: - query.IsLiked = true; - break; - } - } - - if (request.HasQueryLimit) - query.Limit = request.Limit; - return query; - } - - /// Applies filtering. - /// The items. - /// The filter. - /// The user. - /// The repository. - /// IEnumerable{BaseItem}. - internal static IEnumerable ApplyFilter(IEnumerable items, ItemFilter filter, User user, IUserDataManager repository) - { - // Avoid implicitly captured closure - var currentUser = user; - - switch (filter) - { - case ItemFilter.IsFavoriteOrLikes: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - if (userdata == null) - { - return false; - } - - var likes = userdata.Likes ?? false; - var favorite = userdata.IsFavorite; - - return likes || favorite; - }); - - case ItemFilter.Likes: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value; - }); - - case ItemFilter.Dislikes: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value; - }); - - case ItemFilter.IsFavorite: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.IsFavorite; - }); - - case ItemFilter.IsResumable: - return items.Where(item => - { - var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); - - return userdata != null && userdata.PlaybackPositionTicks > 0; - }); - - case ItemFilter.IsPlayed: - return items.Where(item => item.IsPlayed(currentUser)); - - case ItemFilter.IsUnplayed: - return items.Where(item => item.IsUnplayed(currentUser)); - - case ItemFilter.IsFolder: - return items.Where(item => item.IsFolder); - - case ItemFilter.IsNotFolder: - return items.Where(item => !item.IsFolder); - - case ItemFilter.IsRecentlyAdded: - return items.Where(item => (DateTime.UtcNow - item.DateCreated).TotalDays <= 10); - } - - return items; - } - - /// Applies the additional filters. - /// The request. - /// Zero-based index of the. - /// The user. - /// true if this object is pre filtered. - /// Manager for library. - /// true if it succeeds, false if it fails. + /// The reports service. + /// + public class ReportsService : BaseApiService + { + #region [Constructors] + + /// + /// Initializes a new instance of the MediaBrowser.Api.Reports.ReportsService class. + /// Manager for user. + /// Manager for library. + /// The localization. + /// Manager for activity. + public ReportsService(IUserManager userManager, ILibraryManager libraryManager, ILocalizationManager localization, IActivityManager activityManager, IActivityRepository repo) + { + _userManager = userManager; + _libraryManager = libraryManager; + _localization = localization; + _activityManager = activityManager; + _repo = repo; + } + + #endregion + + #region [Private Fields] + + private readonly IActivityManager _activityManager; ///< Manager for activity + + /// Manager for library. + private readonly ILibraryManager _libraryManager; ///< Manager for library + /// The localization. + + private readonly ILocalizationManager _localization; ///< The localization + + private readonly IActivityRepository _repo; + + /// Manager for user. + private readonly IUserManager _userManager; ///< Manager for user + + #endregion + + #region [Public Methods] + + /// Gets the given request. + /// The request. + /// A Task<object> + public async Task Get(GetActivityLogs request) + { + ReportResult result = await GetReportActivities(request).ConfigureAwait(false); + return ToOptimizedResult(result); + } + + /// Gets the given request. + /// The request. + /// A Task<object> + public async Task Get(GetReportHeaders request) + { + if (string.IsNullOrEmpty(request.IncludeItemTypes)) + return null; + + ReportViewType reportViewType = ReportHelper.GetReportViewType(request.ReportView); + ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); + + List result = new List(); + switch (reportViewType) + { + case ReportViewType.ReportData: + 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); + break; + } + + return ToOptimizedResult(result); + + } + + /// Gets the given request. + /// The request. + /// A Task<object> + public async Task Get(GetItemReport request) + { + if (string.IsNullOrEmpty(request.IncludeItemTypes)) + return null; + + var reportResult = await GetReportResult(request); + + 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; + var reportResult = await GetReportStatistic(request); + + return ToOptimizedResult(reportResult); + } + + /// Gets the given request. + /// The request. + /// A Task<object> + public async Task Get(GetReportDownload request) + { + if (string.IsNullOrEmpty(request.IncludeItemTypes)) + return null; + + ReportViewType reportViewType = ReportHelper.GetReportViewType(request.ReportView); + var headers = new Dictionary(); + string fileExtension = "csv"; + string contentType = "text/plain;charset='utf-8'"; + + switch (request.ExportType) + { + case ReportExportType.CSV: + break; + case ReportExportType.Excel: + contentType = "application/vnd.ms-excel"; + fileExtension = "xls"; + break; + } + + var filename = "ReportExport." + fileExtension; + headers["Content-Disposition"] = string.Format("attachment; filename=\"{0}\"", filename); + headers["Content-Encoding"] = "UTF-8"; + + ReportResult result = null; + switch (reportViewType) + { + case ReportViewType.ReportStatistics: + case ReportViewType.ReportData: + ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); + ReportBuilder dataBuilder = new ReportBuilder(_libraryManager); + QueryResult queryResult = await GetQueryResult(request).ConfigureAwait(false); + result = dataBuilder.GetResult(queryResult.Items, request); + result.TotalRecordCount = queryResult.TotalRecordCount; + break; + case ReportViewType.ReportActivities: + result = await GetReportActivities(request).ConfigureAwait(false); + break; + } + + string returnResult = string.Empty; + switch (request.ExportType) + { + case ReportExportType.CSV: + returnResult = new ReportExport().ExportToCsv(result); + break; + case ReportExportType.Excel: + returnResult = new ReportExport().ExportToExcel(result); + break; + } + + object ro = ResultFactory.GetResult(returnResult, contentType, headers); + return ro; + } + + #endregion + + #region [Internal Methods] + + /// Applies filtering. + /// The items. + /// The filter. + /// The user. + /// The repository. + /// IEnumerable{BaseItem}. + internal static IEnumerable ApplyFilter(IEnumerable items, ItemFilter filter, User user, IUserDataManager repository) + { + // Avoid implicitly captured closure + var currentUser = user; + + switch (filter) + { + case ItemFilter.IsFavoriteOrLikes: + return items.Where(item => + { + var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); + + if (userdata == null) + { + return false; + } + + var likes = userdata.Likes ?? false; + var favorite = userdata.IsFavorite; + + return likes || favorite; + }); + + case ItemFilter.Likes: + return items.Where(item => + { + var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); + + return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value; + }); + + case ItemFilter.Dislikes: + return items.Where(item => + { + var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); + + return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value; + }); + + case ItemFilter.IsFavorite: + return items.Where(item => + { + var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); + + return userdata != null && userdata.IsFavorite; + }); + + case ItemFilter.IsResumable: + return items.Where(item => + { + var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()); + + return userdata != null && userdata.PlaybackPositionTicks > 0; + }); + + case ItemFilter.IsPlayed: + return items.Where(item => item.IsPlayed(currentUser)); + + case ItemFilter.IsUnplayed: + return items.Where(item => item.IsUnplayed(currentUser)); + + case ItemFilter.IsFolder: + return items.Where(item => item.IsFolder); + + case ItemFilter.IsNotFolder: + return items.Where(item => !item.IsFolder); + + case ItemFilter.IsRecentlyAdded: + return items.Where(item => (DateTime.UtcNow - item.DateCreated).TotalDays <= 10); + } + + return items; + } + + #endregion + + #region [Private Methods] + + /// Applies the additional filters. + /// The request. + /// Zero-based index of the. + /// The user. + /// true if this object is pre filtered. + /// Manager for library. + /// true if it succeeds, false if it fails. private bool ApplyAdditionalFilters(BaseReportRequest request, BaseItem i, User user, bool isPreFiltered, ILibraryManager libraryManager) - { - var video = i as Video; - - if (!isPreFiltered) - { - var mediaTypes = request.GetMediaTypes(); - if (mediaTypes.Length > 0) - { - if (!(!string.IsNullOrEmpty(i.MediaType) && mediaTypes.Contains(i.MediaType, StringComparer.OrdinalIgnoreCase))) - { - return false; - } - } - - if (request.IsPlayed.HasValue) - { - var val = request.IsPlayed.Value; - if (i.IsPlayed(user) != val) - { - return false; - } - } - - // Exclude item types - var excluteItemTypes = request.GetExcludeItemTypes(); - if (excluteItemTypes.Length > 0 && excluteItemTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - - // Include item types - var includeItemTypes = request.GetIncludeItemTypes(); - if (includeItemTypes.Length > 0 && !includeItemTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - - if (request.IsInBoxSet.HasValue) - { - var val = request.IsInBoxSet.Value; - if (i.Parents.OfType().Any() != val) - { - return false; - } - } - - // Filter by Video3DFormat - if (request.Is3D.HasValue) - { - var val = request.Is3D.Value; - - if (video == null || val != video.Video3DFormat.HasValue) - { - return false; - } - } - - if (request.IsHD.HasValue) - { - var val = request.IsHD.Value; - - if (video == null || val != video.IsHD) - { - return false; - } - } - - if (request.IsUnidentified.HasValue) - { - var val = request.IsUnidentified.Value; - if (i.IsUnidentified != val) - { - return false; - } - } - - if (request.IsLocked.HasValue) - { - var val = request.IsLocked.Value; - if (i.IsLocked != val) - { - return false; - } - } - - if (request.HasOverview.HasValue) - { - var filterValue = request.HasOverview.Value; - - var hasValue = !string.IsNullOrEmpty(i.Overview); - - if (hasValue != filterValue) - { - return false; - } - } - - if (request.HasImdbId.HasValue) - { - var filterValue = request.HasImdbId.Value; - - var hasValue = !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Imdb)); - - if (hasValue != filterValue) - { - return false; - } - } - - if (request.HasTmdbId.HasValue) - { - var filterValue = request.HasTmdbId.Value; - - var hasValue = !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb)); - - if (hasValue != filterValue) - { - return false; - } - } - - if (request.HasTvdbId.HasValue) - { - var filterValue = request.HasTvdbId.Value; - - var hasValue = !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb)); - - if (hasValue != filterValue) - { - return false; - } - } - - if (request.IsYearMismatched.HasValue) - { - var filterValue = request.IsYearMismatched.Value; - - if (UserViewBuilder.IsYearMismatched(i, libraryManager) != filterValue) - { - return false; - } - } - - if (request.HasOfficialRating.HasValue) - { - var filterValue = request.HasOfficialRating.Value; - - var hasValue = !string.IsNullOrEmpty(i.OfficialRating); - - if (hasValue != filterValue) - { - return false; - } - } - - if (request.IsPlaceHolder.HasValue) - { - var filterValue = request.IsPlaceHolder.Value; - - var isPlaceHolder = false; - - var hasPlaceHolder = i as ISupportsPlaceHolders; - - if (hasPlaceHolder != null) - { - isPlaceHolder = hasPlaceHolder.IsPlaceHolder; - } - - if (isPlaceHolder != filterValue) - { - return false; - } - } - - if (request.HasSpecialFeature.HasValue) - { - var filterValue = request.HasSpecialFeature.Value; - - var movie = i as IHasSpecialFeatures; - - if (movie != null) - { - var ok = filterValue - ? movie.SpecialFeatureIds.Count > 0 - : movie.SpecialFeatureIds.Count == 0; - - if (!ok) - { - return false; - } - } - else - { - return false; - } - } - - if (request.HasSubtitles.HasValue) - { - var val = request.HasSubtitles.Value; - - if (video == null || val != video.HasSubtitles) - { - return false; - } - } - - if (request.HasParentalRating.HasValue) - { - var val = request.HasParentalRating.Value; - - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (val) - { - if (string.IsNullOrEmpty(rating)) - { - return false; - } - } - else - { - if (!string.IsNullOrEmpty(rating)) - { - return false; - } - } - } - - if (request.HasTrailer.HasValue) - { - var val = request.HasTrailer.Value; - var trailerCount = 0; - - var hasTrailers = i as IHasTrailers; - if (hasTrailers != null) - { - trailerCount = hasTrailers.GetTrailerIds().Count; - } - - var ok = val ? trailerCount > 0 : trailerCount == 0; - - if (!ok) - { - return false; - } - } - - if (request.HasThemeSong.HasValue) - { - var filterValue = request.HasThemeSong.Value; - - var themeCount = 0; - var iHasThemeMedia = i as IHasThemeMedia; - - if (iHasThemeMedia != null) - { - themeCount = iHasThemeMedia.ThemeSongIds.Count; - } - var ok = filterValue ? themeCount > 0 : themeCount == 0; - - if (!ok) - { - return false; - } - } - - if (request.HasThemeVideo.HasValue) - { - var filterValue = request.HasThemeVideo.Value; - - var themeCount = 0; - var iHasThemeMedia = i as IHasThemeMedia; - - if (iHasThemeMedia != null) - { - themeCount = iHasThemeMedia.ThemeVideoIds.Count; - } - var ok = filterValue ? themeCount > 0 : themeCount == 0; - - if (!ok) - { - return false; - } - } - - // Apply tag filter - var tags = request.GetTags(); - if (tags.Length > 0) - { - var hasTags = i as IHasTags; - if (hasTags == null) - { - return false; - } - if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))) - { - return false; - } - } - - // Apply official rating filter - var officialRatings = request.GetOfficialRatings(); - if (officialRatings.Length > 0 && !officialRatings.Contains(i.OfficialRating ?? string.Empty)) - { - return false; - } - - // Apply genre filter - var genres = request.GetGenres(); - if (genres.Length > 0 && !(genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))) - { - return false; - } - - // Filter by VideoType - var videoTypes = request.GetVideoTypes(); - if (videoTypes.Length > 0 && (video == null || !videoTypes.Contains(video.VideoType))) - { - return false; - } - - var imageTypes = request.GetImageTypes().ToList(); - if (imageTypes.Count > 0) - { - if (!(imageTypes.Any(i.HasImage))) - { - return false; - } - } - - // Apply studio filter - var studios = request.GetStudios(); - if (studios.Length > 0 && !studios.Any(v => i.Studios.Contains(v, StringComparer.OrdinalIgnoreCase))) - { - return false; - } - - // Apply studio filter - var studioIds = request.GetStudioIds(); - if (studioIds.Length > 0 && !studioIds.Any(id => - { - var studioItem = libraryManager.GetItemById(id); - return studioItem != null && i.Studios.Contains(studioItem.Name, StringComparer.OrdinalIgnoreCase); - })) - { - return false; - } - - // Apply year filter - var years = request.GetYears(); - if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value))) - { - return false; - } - - // Apply person filter - var personIds = request.GetPersonIds(); - if (personIds.Length > 0) - { - var names = personIds - .Select(libraryManager.GetItemById) - .Select(p => p == null ? "-1" : p.Name) - .ToList(); - - if (!(names.Any(v => _libraryManager.GetPeople(i).Select(p => p.Name).Contains(v, StringComparer.OrdinalIgnoreCase)))) - { - return false; - } - } - - // Apply person filter - if (!string.IsNullOrEmpty(request.Person)) - { - var personTypes = request.GetPersonTypes(); - - if (personTypes.Length == 0) - { - if (!(_libraryManager.GetPeople(i).Any(p => string.Equals(p.Name, request.Person, StringComparison.OrdinalIgnoreCase)))) - { - return false; - } - } - else - { - var types = personTypes; - - var ok = new[] { i }.Any(item => - _libraryManager.GetPeople(i).Any(p => - p.Name.Equals(request.Person, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase)))); - - if (!ok) - { - return false; - } - } - } - } - - if (request.MinCommunityRating.HasValue) - { - var val = request.MinCommunityRating.Value; - - if (!(i.CommunityRating.HasValue && i.CommunityRating >= val)) - { - return false; - } - } - - if (request.MinCriticRating.HasValue) - { - var val = request.MinCriticRating.Value; - - var hasCriticRating = i as IHasCriticRating; - - if (hasCriticRating != null) - { - if (!(hasCriticRating.CriticRating.HasValue && hasCriticRating.CriticRating >= val)) - { - return false; - } - } - else - { - return false; - } - } - - // Artists - if (!string.IsNullOrEmpty(request.ArtistIds)) - { - var artistIds = request.ArtistIds.Split('|'); - - var audio = i as IHasArtist; - - if (!(audio != null && artistIds.Any(id => - { - var artistItem = libraryManager.GetItemById(id); - return artistItem != null && audio.HasAnyArtist(artistItem.Name); - }))) - { - return false; - } - } - - // Artists - if (!string.IsNullOrEmpty(request.Artists)) - { - var artists = request.Artists.Split('|'); - - var audio = i as IHasArtist; - - if (!(audio != null && artists.Any(audio.HasAnyArtist))) - { - return false; - } - } - - // Albums - if (!string.IsNullOrEmpty(request.Albums)) - { - var albums = request.Albums.Split('|'); - - var audio = i as Audio; - - if (audio != null) - { - if (!albums.Any(a => string.Equals(a, audio.Album, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - var album = i as MusicAlbum; - - if (album != null) - { - if (!albums.Any(a => string.Equals(a, album.Name, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - var musicVideo = i as MusicVideo; - - if (musicVideo != null) - { - if (!albums.Any(a => string.Equals(a, musicVideo.Album, StringComparison.OrdinalIgnoreCase))) - { - return false; - } - } - - return false; - } - - // Min index number - if (request.MinIndexNumber.HasValue) - { - if (!(i.IndexNumber.HasValue && i.IndexNumber.Value >= request.MinIndexNumber.Value)) - { - return false; - } - } - - // Min official rating - if (!string.IsNullOrEmpty(request.MinOfficialRating)) - { - var level = _localization.GetRatingLevel(request.MinOfficialRating); - - if (level.HasValue) - { - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (!string.IsNullOrEmpty(rating)) - { - var itemLevel = _localization.GetRatingLevel(rating); - - if (!(!itemLevel.HasValue || itemLevel.Value >= level.Value)) - { - return false; - } - } - } - } - - // Max official rating - if (!string.IsNullOrEmpty(request.MaxOfficialRating)) - { - var level = _localization.GetRatingLevel(request.MaxOfficialRating); - - if (level.HasValue) - { - var rating = i.CustomRating; - - if (string.IsNullOrEmpty(rating)) - { - rating = i.OfficialRating; - } - - if (!string.IsNullOrEmpty(rating)) - { - var itemLevel = _localization.GetRatingLevel(rating); - - if (!(!itemLevel.HasValue || itemLevel.Value <= level.Value)) - { - return false; - } - } - } - } - - // LocationTypes - if (!string.IsNullOrEmpty(request.LocationTypes)) - { - var vals = request.LocationTypes.Split(','); - if (!vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - // ExcludeLocationTypes - if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) - { - var vals = request.ExcludeLocationTypes.Split(','); - if (vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(request.AlbumArtistStartsWithOrGreater)) - { - var ok = new[] { i }.OfType() - .Any(p => string.Compare(request.AlbumArtistStartsWithOrGreater, p.AlbumArtists.FirstOrDefault(), StringComparison.CurrentCultureIgnoreCase) < 1); - - if (!ok) - { - return false; - } - } - - // Filter by Series Status - if (!string.IsNullOrEmpty(request.SeriesStatus)) - { - var vals = request.SeriesStatus.Split(','); - - var ok = new[] { i }.OfType().Any(p => p.Status.HasValue && vals.Contains(p.Status.Value.ToString(), StringComparer.OrdinalIgnoreCase)); - - if (!ok) - { - return false; - } - } - - // Filter by Series AirDays - if (!string.IsNullOrEmpty(request.AirDays)) - { - var days = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)); - - var ok = new[] { i }.OfType().Any(p => p.AirDays != null && days.Any(d => p.AirDays.Contains(d))); - - if (!ok) - { - return false; - } - } - - if (request.MinPlayers.HasValue) - { - var filterValue = request.MinPlayers.Value; - - var game = i as Game; - - if (game != null) - { - var players = game.PlayersSupported ?? 1; - - var ok = players >= filterValue; - - if (!ok) - { - return false; - } - } - else - { - return false; - } - } - - if (request.MaxPlayers.HasValue) - { - var filterValue = request.MaxPlayers.Value; - - var game = i as Game; - - if (game != null) - { - var players = game.PlayersSupported ?? 1; - - var ok = players <= filterValue; - - if (!ok) - { - return false; - } - } - else - { - return false; - } - } - - if (request.ParentIndexNumber.HasValue) - { - var filterValue = request.ParentIndexNumber.Value; - - var episode = i as Episode; - - if (episode != null) - { - if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - - var song = i as Audio; - - if (song != null) - { - if (song.ParentIndexNumber.HasValue && song.ParentIndexNumber.Value != filterValue) - { - return false; - } - } - } - - if (request.AiredDuringSeason.HasValue) - { - var episode = i as Episode; - - if (episode == null) - { - return false; - } - - if (!Series.FilterEpisodesBySeason(new[] { episode }, request.AiredDuringSeason.Value, true).Any()) - { - return false; - } - } - - if (!string.IsNullOrEmpty(request.MinPremiereDate)) - { - var date = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); - - if (!(i.PremiereDate.HasValue && i.PremiereDate.Value >= date)) - { - return false; - } - } - - if (!string.IsNullOrEmpty(request.MaxPremiereDate)) - { - var date = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); - - if (!(i.PremiereDate.HasValue && i.PremiereDate.Value <= date)) - { - return false; - } - } - - return true; - } - - /// Applies the paging. - /// The request. - /// The items. - /// IEnumerable{BaseItem}. - private IEnumerable ApplyPaging(GetItems request, IEnumerable items) - { - // Start at - if (request.StartIndex.HasValue) - { - items = items.Skip(request.StartIndex.Value); - } - - // Return limit - if (request.Limit.HasValue) - { - items = items.Take(request.Limit.Value); - } - - return items; - } - - } + { + var video = i as Video; + + if (!isPreFiltered) + { + var mediaTypes = request.GetMediaTypes(); + if (mediaTypes.Length > 0) + { + if (!(!string.IsNullOrEmpty(i.MediaType) && mediaTypes.Contains(i.MediaType, StringComparer.OrdinalIgnoreCase))) + { + return false; + } + } + + if (request.IsPlayed.HasValue) + { + var val = request.IsPlayed.Value; + if (i.IsPlayed(user) != val) + { + return false; + } + } + + // Exclude item types + var excluteItemTypes = request.GetExcludeItemTypes(); + if (excluteItemTypes.Length > 0 && excluteItemTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + // Include item types + var includeItemTypes = request.GetIncludeItemTypes(); + if (includeItemTypes.Length > 0 && !includeItemTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + + if (request.IsInBoxSet.HasValue) + { + var val = request.IsInBoxSet.Value; + if (i.Parents.OfType().Any() != val) + { + return false; + } + } + + // Filter by Video3DFormat + if (request.Is3D.HasValue) + { + var val = request.Is3D.Value; + + if (video == null || val != video.Video3DFormat.HasValue) + { + return false; + } + } + + if (request.IsHD.HasValue) + { + var val = request.IsHD.Value; + + if (video == null || val != video.IsHD) + { + return false; + } + } + + if (request.IsUnidentified.HasValue) + { + var val = request.IsUnidentified.Value; + if (i.IsUnidentified != val) + { + return false; + } + } + + if (request.IsLocked.HasValue) + { + var val = request.IsLocked.Value; + if (i.IsLocked != val) + { + return false; + } + } + + if (request.HasOverview.HasValue) + { + var filterValue = request.HasOverview.Value; + + var hasValue = !string.IsNullOrEmpty(i.Overview); + + if (hasValue != filterValue) + { + return false; + } + } + + if (request.HasImdbId.HasValue) + { + var filterValue = request.HasImdbId.Value; + + var hasValue = !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Imdb)); + + if (hasValue != filterValue) + { + return false; + } + } + + if (request.HasTmdbId.HasValue) + { + var filterValue = request.HasTmdbId.Value; + + var hasValue = !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb)); + + if (hasValue != filterValue) + { + return false; + } + } + + if (request.HasTvdbId.HasValue) + { + var filterValue = request.HasTvdbId.Value; + + var hasValue = !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb)); + + if (hasValue != filterValue) + { + return false; + } + } + + if (request.IsYearMismatched.HasValue) + { + var filterValue = request.IsYearMismatched.Value; + + if (UserViewBuilder.IsYearMismatched(i, libraryManager) != filterValue) + { + return false; + } + } + + if (request.HasOfficialRating.HasValue) + { + var filterValue = request.HasOfficialRating.Value; + + var hasValue = !string.IsNullOrEmpty(i.OfficialRating); + + if (hasValue != filterValue) + { + return false; + } + } + + if (request.IsPlaceHolder.HasValue) + { + var filterValue = request.IsPlaceHolder.Value; + + var isPlaceHolder = false; + + var hasPlaceHolder = i as ISupportsPlaceHolders; + + if (hasPlaceHolder != null) + { + isPlaceHolder = hasPlaceHolder.IsPlaceHolder; + } + + if (isPlaceHolder != filterValue) + { + return false; + } + } + + if (request.HasSpecialFeature.HasValue) + { + var filterValue = request.HasSpecialFeature.Value; + + var movie = i as IHasSpecialFeatures; + + if (movie != null) + { + var ok = filterValue + ? movie.SpecialFeatureIds.Count > 0 + : movie.SpecialFeatureIds.Count == 0; + + if (!ok) + { + return false; + } + } + else + { + return false; + } + } + + if (request.HasSubtitles.HasValue) + { + var val = request.HasSubtitles.Value; + + if (video == null || val != video.HasSubtitles) + { + return false; + } + } + + if (request.HasParentalRating.HasValue) + { + var val = request.HasParentalRating.Value; + + var rating = i.CustomRating; + + if (string.IsNullOrEmpty(rating)) + { + rating = i.OfficialRating; + } + + if (val) + { + if (string.IsNullOrEmpty(rating)) + { + return false; + } + } + else + { + if (!string.IsNullOrEmpty(rating)) + { + return false; + } + } + } + + if (request.HasTrailer.HasValue) + { + var val = request.HasTrailer.Value; + var trailerCount = 0; + + var hasTrailers = i as IHasTrailers; + if (hasTrailers != null) + { + trailerCount = hasTrailers.GetTrailerIds().Count; + } + + var ok = val ? trailerCount > 0 : trailerCount == 0; + + if (!ok) + { + return false; + } + } + + if (request.HasThemeSong.HasValue) + { + var filterValue = request.HasThemeSong.Value; + + var themeCount = 0; + var iHasThemeMedia = i as IHasThemeMedia; + + if (iHasThemeMedia != null) + { + themeCount = iHasThemeMedia.ThemeSongIds.Count; + } + var ok = filterValue ? themeCount > 0 : themeCount == 0; + + if (!ok) + { + return false; + } + } + + if (request.HasThemeVideo.HasValue) + { + var filterValue = request.HasThemeVideo.Value; + + var themeCount = 0; + var iHasThemeMedia = i as IHasThemeMedia; + + if (iHasThemeMedia != null) + { + themeCount = iHasThemeMedia.ThemeVideoIds.Count; + } + var ok = filterValue ? themeCount > 0 : themeCount == 0; + + if (!ok) + { + return false; + } + } + + // Apply tag filter + var tags = request.GetTags(); + if (tags.Length > 0) + { + var hasTags = i as IHasTags; + if (hasTags == null) + { + return false; + } + if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))) + { + return false; + } + } + + // Apply official rating filter + var officialRatings = request.GetOfficialRatings(); + if (officialRatings.Length > 0 && !officialRatings.Contains(i.OfficialRating ?? string.Empty)) + { + return false; + } + + // Apply genre filter + var genres = request.GetGenres(); + if (genres.Length > 0 && !(genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))) + { + return false; + } + + // Filter by VideoType + var videoTypes = request.GetVideoTypes(); + if (videoTypes.Length > 0 && (video == null || !videoTypes.Contains(video.VideoType))) + { + return false; + } + + var imageTypes = request.GetImageTypes().ToList(); + if (imageTypes.Count > 0) + { + if (!(imageTypes.Any(i.HasImage))) + { + return false; + } + } + + // Apply studio filter + var studios = request.GetStudios(); + if (studios.Length > 0 && !studios.Any(v => i.Studios.Contains(v, StringComparer.OrdinalIgnoreCase))) + { + return false; + } + + // Apply studio filter + var studioIds = request.GetStudioIds(); + if (studioIds.Length > 0 && !studioIds.Any(id => + { + var studioItem = libraryManager.GetItemById(id); + return studioItem != null && i.Studios.Contains(studioItem.Name, StringComparer.OrdinalIgnoreCase); + })) + { + return false; + } + + // Apply year filter + var years = request.GetYears(); + if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value))) + { + return false; + } + + // Apply person filter + var personIds = request.GetPersonIds(); + if (personIds.Length > 0) + { + var names = personIds + .Select(libraryManager.GetItemById) + .Select(p => p == null ? "-1" : p.Name) + .ToList(); + + if (!(names.Any(v => i.People.Select(p => p.Name).Contains(v, StringComparer.OrdinalIgnoreCase)))) + { + return false; + } + } + + // Apply person filter + if (!string.IsNullOrEmpty(request.Person)) + { + var personTypes = request.GetPersonTypes(); + + if (personTypes.Length == 0) + { + if (!(i.People.Any(p => string.Equals(p.Name, request.Person, StringComparison.OrdinalIgnoreCase)))) + { + return false; + } + } + else + { + var types = personTypes; + + var ok = new[] { i }.Any(item => + item.People != null && + item.People.Any(p => + p.Name.Equals(request.Person, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase)))); + + if (!ok) + { + return false; + } + } + } + } + + if (request.MinCommunityRating.HasValue) + { + var val = request.MinCommunityRating.Value; + + if (!(i.CommunityRating.HasValue && i.CommunityRating >= val)) + { + return false; + } + } + + if (request.MinCriticRating.HasValue) + { + var val = request.MinCriticRating.Value; + + var hasCriticRating = i as IHasCriticRating; + + if (hasCriticRating != null) + { + if (!(hasCriticRating.CriticRating.HasValue && hasCriticRating.CriticRating >= val)) + { + return false; + } + } + else + { + return false; + } + } + + // Artists + if (!string.IsNullOrEmpty(request.ArtistIds)) + { + var artistIds = request.ArtistIds.Split('|'); + + var audio = i as IHasArtist; + + if (!(audio != null && artistIds.Any(id => + { + var artistItem = libraryManager.GetItemById(id); + return artistItem != null && audio.HasAnyArtist(artistItem.Name); + }))) + { + return false; + } + } + + // Artists + if (!string.IsNullOrEmpty(request.Artists)) + { + var artists = request.Artists.Split('|'); + + var audio = i as IHasArtist; + + if (!(audio != null && artists.Any(audio.HasAnyArtist))) + { + return false; + } + } + + // Albums + if (!string.IsNullOrEmpty(request.Albums)) + { + var albums = request.Albums.Split('|'); + + var audio = i as Audio; + + if (audio != null) + { + if (!albums.Any(a => string.Equals(a, audio.Album, StringComparison.OrdinalIgnoreCase))) + { + return false; + } + } + + var album = i as MusicAlbum; + + if (album != null) + { + if (!albums.Any(a => string.Equals(a, album.Name, StringComparison.OrdinalIgnoreCase))) + { + return false; + } + } + + var musicVideo = i as MusicVideo; + + if (musicVideo != null) + { + if (!albums.Any(a => string.Equals(a, musicVideo.Album, StringComparison.OrdinalIgnoreCase))) + { + return false; + } + } + + return false; + } + + // Min index number + if (request.MinIndexNumber.HasValue) + { + if (!(i.IndexNumber.HasValue && i.IndexNumber.Value >= request.MinIndexNumber.Value)) + { + return false; + } + } + + // Min official rating + if (!string.IsNullOrEmpty(request.MinOfficialRating)) + { + var level = _localization.GetRatingLevel(request.MinOfficialRating); + + if (level.HasValue) + { + var rating = i.CustomRating; + + if (string.IsNullOrEmpty(rating)) + { + rating = i.OfficialRating; + } + + if (!string.IsNullOrEmpty(rating)) + { + var itemLevel = _localization.GetRatingLevel(rating); + + if (!(!itemLevel.HasValue || itemLevel.Value >= level.Value)) + { + return false; + } + } + } + } + + // Max official rating + if (!string.IsNullOrEmpty(request.MaxOfficialRating)) + { + var level = _localization.GetRatingLevel(request.MaxOfficialRating); + + if (level.HasValue) + { + var rating = i.CustomRating; + + if (string.IsNullOrEmpty(rating)) + { + rating = i.OfficialRating; + } + + if (!string.IsNullOrEmpty(rating)) + { + var itemLevel = _localization.GetRatingLevel(rating); + + if (!(!itemLevel.HasValue || itemLevel.Value <= level.Value)) + { + return false; + } + } + } + } + + // LocationTypes + if (!string.IsNullOrEmpty(request.LocationTypes)) + { + var vals = request.LocationTypes.Split(','); + if (!vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + + // ExcludeLocationTypes + if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) + { + var vals = request.ExcludeLocationTypes.Split(','); + if (vals.Contains(i.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + + if (!string.IsNullOrEmpty(request.AlbumArtistStartsWithOrGreater)) + { + var ok = new[] { i }.OfType() + .Any(p => string.Compare(request.AlbumArtistStartsWithOrGreater, p.AlbumArtists.FirstOrDefault(), StringComparison.CurrentCultureIgnoreCase) < 1); + + if (!ok) + { + return false; + } + } + + // Filter by Series Status + if (!string.IsNullOrEmpty(request.SeriesStatus)) + { + var vals = request.SeriesStatus.Split(','); + + var ok = new[] { i }.OfType().Any(p => p.Status.HasValue && vals.Contains(p.Status.Value.ToString(), StringComparer.OrdinalIgnoreCase)); + + if (!ok) + { + return false; + } + } + + // Filter by Series AirDays + if (!string.IsNullOrEmpty(request.AirDays)) + { + var days = request.AirDays.Split(',').Select(d => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), d, true)); + + var ok = new[] { i }.OfType().Any(p => p.AirDays != null && days.Any(d => p.AirDays.Contains(d))); + + if (!ok) + { + return false; + } + } + + if (request.MinPlayers.HasValue) + { + var filterValue = request.MinPlayers.Value; + + var game = i as Game; + + if (game != null) + { + var players = game.PlayersSupported ?? 1; + + var ok = players >= filterValue; + + if (!ok) + { + return false; + } + } + else + { + return false; + } + } + + if (request.MaxPlayers.HasValue) + { + var filterValue = request.MaxPlayers.Value; + + var game = i as Game; + + if (game != null) + { + var players = game.PlayersSupported ?? 1; + + var ok = players <= filterValue; + + if (!ok) + { + return false; + } + } + else + { + return false; + } + } + + if (request.ParentIndexNumber.HasValue) + { + var filterValue = request.ParentIndexNumber.Value; + + var episode = i as Episode; + + if (episode != null) + { + if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value != filterValue) + { + return false; + } + } + + var song = i as Audio; + + if (song != null) + { + if (song.ParentIndexNumber.HasValue && song.ParentIndexNumber.Value != filterValue) + { + return false; + } + } + } + + if (request.AiredDuringSeason.HasValue) + { + var episode = i as Episode; + + if (episode == null) + { + return false; + } + + if (!Series.FilterEpisodesBySeason(new[] { episode }, request.AiredDuringSeason.Value, true).Any()) + { + return false; + } + } + + if (!string.IsNullOrEmpty(request.MinPremiereDate)) + { + var date = DateTime.Parse(request.MinPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); + + if (!(i.PremiereDate.HasValue && i.PremiereDate.Value >= date)) + { + return false; + } + } + + if (!string.IsNullOrEmpty(request.MaxPremiereDate)) + { + var date = DateTime.Parse(request.MaxPremiereDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); + + if (!(i.PremiereDate.HasValue && i.PremiereDate.Value <= date)) + { + return false; + } + } + + return true; + } + + /// Applies the paging. + /// The request. + /// The items. + /// IEnumerable{BaseItem}. + private IEnumerable ApplyPaging(GetItems request, IEnumerable items) + { + // Start at + if (request.StartIndex.HasValue) + { + items = items.Skip(request.StartIndex.Value); + } + + // Return limit + if (request.Limit.HasValue) + { + items = items.Take(request.Limit.Value); + } + + return items; + } + + /// Gets items query. + /// The request. + /// The user. + /// The items query. + private InternalItemsQuery GetItemsQuery(BaseReportRequest request, User user) + { + var query = new InternalItemsQuery + { + User = user, + IsPlayed = request.IsPlayed, + MediaTypes = request.GetMediaTypes(), + IncludeItemTypes = request.GetIncludeItemTypes(), + ExcludeItemTypes = request.GetExcludeItemTypes(), + Recursive = true, + SortBy = request.GetOrderBy(), + SortOrder = request.SortOrder ?? SortOrder.Ascending, + + Filter = i => ApplyAdditionalFilters(request, i, user, true, _libraryManager), + StartIndex = request.StartIndex, + IsMissing = request.IsMissing, + IsVirtualUnaired = request.IsVirtualUnaired, + IsUnaired = request.IsUnaired, + CollapseBoxSetItems = request.CollapseBoxSetItems, + NameLessThan = request.NameLessThan, + NameStartsWith = request.NameStartsWith, + NameStartsWithOrGreater = request.NameStartsWithOrGreater, + HasImdbId = request.HasImdbId, + IsYearMismatched = request.IsYearMismatched, + IsUnidentified = request.IsUnidentified, + IsPlaceHolder = request.IsPlaceHolder, + IsLocked = request.IsLocked, + IsInBoxSet = request.IsInBoxSet, + IsHD = request.IsHD, + Is3D = request.Is3D, + HasTvdbId = request.HasTvdbId, + HasTmdbId = request.HasTmdbId, + HasOverview = request.HasOverview, + HasOfficialRating = request.HasOfficialRating, + HasParentalRating = request.HasParentalRating, + HasSpecialFeature = request.HasSpecialFeature, + HasSubtitles = request.HasSubtitles, + HasThemeSong = request.HasThemeSong, + HasThemeVideo = request.HasThemeVideo, + HasTrailer = request.HasTrailer, + Tags = request.GetTags(), + OfficialRatings = request.GetOfficialRatings(), + Genres = request.GetGenres(), + Studios = request.GetStudios(), + StudioIds = request.GetStudioIds(), + Person = request.Person, + PersonIds = request.GetPersonIds(), + PersonTypes = request.GetPersonTypes(), + Years = request.GetYears(), + ImageTypes = request.GetImageTypes().ToArray(), + VideoTypes = request.GetVideoTypes().ToArray(), + AdjacentTo = request.AdjacentTo + }; + + if (!string.IsNullOrWhiteSpace(request.Ids)) + { + query.CollapseBoxSetItems = false; + } + + foreach (var filter in request.GetFilters()) + { + switch (filter) + { + case ItemFilter.Dislikes: + query.IsLiked = false; + break; + case ItemFilter.IsFavorite: + query.IsFavorite = true; + break; + case ItemFilter.IsFavoriteOrLikes: + query.IsFavoriteOrLiked = true; + break; + case ItemFilter.IsFolder: + query.IsFolder = true; + break; + case ItemFilter.IsNotFolder: + query.IsFolder = false; + break; + case ItemFilter.IsPlayed: + query.IsPlayed = true; + break; + case ItemFilter.IsRecentlyAdded: + break; + case ItemFilter.IsResumable: + query.IsResumable = true; + break; + case ItemFilter.IsUnplayed: + query.IsPlayed = false; + break; + case ItemFilter.Likes: + query.IsLiked = true; + break; + } + } + + if (request.HasQueryLimit) + query.Limit = request.Limit; + return query; + } + + /// Gets query result. + /// The request. + /// The query result. + private async Task> GetQueryResult(BaseReportRequest request) + { + // Placeholder in case needed later + request.Recursive = true; + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + request.Fields = "MediaSources,DateCreated,Settings,Studios,SyncInfo,ItemCounts"; + + var parentItem = string.IsNullOrEmpty(request.ParentId) ? + (user == null ? _libraryManager.RootFolder : user.RootFolder) : + _libraryManager.GetItemById(request.ParentId); + + var item = string.IsNullOrEmpty(request.ParentId) ? + user == null ? _libraryManager.RootFolder : user.RootFolder : + parentItem; + + IEnumerable items; + + if (request.Recursive) + { + var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); + return result; + } + else + { + if (user == null) + { + var result = await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); + return result; + } + + var userRoot = item as UserRootFolder; + + if (userRoot == null) + { + var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); + + return result; + } + + items = ((Folder)item).GetChildren(user, true); + } + + return new QueryResult { Items = items.ToArray() }; + + } + + /// Gets report activities. + /// The request. + /// The report activities. + private Task GetReportActivities(IReportsDownload request) + { + return Task.Run(() => + { + DateTime? minDate = string.IsNullOrWhiteSpace(request.MinDate) ? + (DateTime?)null : + DateTime.Parse(request.MinDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); + var queryResult = _repo.GetActivityLogEntries(minDate, request.StartIndex, request.Limit); + //var queryResult = _activityManager.GetActivityLogEntries(minDate, request.StartIndex, request.Limit); + + ReportActivitiesBuilder builder = new ReportActivitiesBuilder(_libraryManager, _userManager); + var result = builder.GetResult(queryResult, request); + result.TotalRecordCount = queryResult.TotalRecordCount; + return result; + + }); + + } + + /// Gets report result. + /// The request. + /// The report result. + private async Task GetReportResult(GetItemReport request) + { + ReportBuilder reportBuilder = new ReportBuilder(_libraryManager); + QueryResult queryResult = await GetQueryResult(request).ConfigureAwait(false); + ReportResult reportResult = reportBuilder.GetResult(queryResult.Items, request); + reportResult.TotalRecordCount = queryResult.TotalRecordCount; + + return reportResult; + } + + /// Gets report statistic. + /// The request. + /// The report statistic. + private async Task GetReportStatistic(GetReportStatistics request) + { + ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); + QueryResult queryResult = await GetQueryResult(request).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.Api/Reports/Stat/ReportStatBuilder.cs b/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs index 541bb92d9..8cb57c030 100644 --- a/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs +++ b/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs @@ -9,206 +9,266 @@ using System.Threading.Tasks; namespace MediaBrowser.Api.Reports { - /// A report stat builder. - /// - public class ReportStatBuilder : ReportBuilderBase - { - /// - /// Initializes a new instance of the MediaBrowser.Api.Reports.ReportStatBuilder class. - /// Manager for library. - public ReportStatBuilder(ILibraryManager libraryManager) - : base(libraryManager) - { - } - - /// Gets report stat result. - /// The items. - /// Type of the report row. - /// The top item. - /// The report stat result. - public ReportStatResult GetReportStatResult(BaseItem[] items, ReportViewType reportRowType, int topItem = 5) - { - ReportStatResult result = new ReportStatResult(); - result = this.GetResultGenres(result, items, topItem); - result = this.GetResultStudios(result, items, topItem); - result = this.GetResultPersons(result, items, topItem); - result = this.GetResultProductionYears(result, items, topItem); - result = this.GetResulProductionLocations(result, items, topItem); - result = this.GetResultCommunityRatings(result, items, topItem); - result = this.GetResultParentalRatings(result, items, topItem); - - switch (reportRowType) - { - case ReportViewType.Season: - case ReportViewType.Series: - case ReportViewType.MusicAlbum: - case ReportViewType.MusicArtist: - case ReportViewType.Game: - break; - case ReportViewType.Movie: - case ReportViewType.BoxSet: - - break; - case ReportViewType.Book: - case ReportViewType.Episode: - case ReportViewType.Video: - case ReportViewType.MusicVideo: - case ReportViewType.Trailer: - case ReportViewType.Audio: - case ReportViewType.BaseItem: - default: - break; - } - - result.Groups = result.Groups.OrderByDescending(n => n.Items.Count()).ToList(); - - return result; - } - - private ReportStatResult GetResultGenres(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderGenres"), topItem, - items.SelectMany(x => x.Genres) - .GroupBy(x => x) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key, - Value = x.Count().ToString(), - Id = GetGenreID(x.Key) - })); - return result; - - } - - private ReportStatResult GetResultStudios(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderStudios"), topItem, - items.SelectMany(x => x.Studios) - .GroupBy(x => x) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key, - Value = x.Count().ToString(), - Id = GetStudioID(x.Key) - }) - ); - - return result; - - } - - private ReportStatResult GetResultPersons(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - List t = new List { PersonType.Actor, PersonType.Composer, PersonType.Director, PersonType.GuestStar, PersonType.Producer, PersonType.Writer, "Artist", "AlbumArtist" }; - foreach (var item in t) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("Option" + item), topItem, - items.SelectMany(x => _libraryManager.GetPeople(x)) - .Where(n => n.Type == item) - .GroupBy(x => x.Name) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key, - Value = x.Count().ToString(), - Id = GetPersonID(x.Key) - }) - ); - } - - return result; - } - - private ReportStatResult GetResultCommunityRatings(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("LabelCommunityRating"), topItem, - items.Where(x => x.CommunityRating != null && x.CommunityRating > 0) - .GroupBy(x => x.CommunityRating) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key.ToString(), - Value = x.Count().ToString() - }) - ); - - return result; - } - - private ReportStatResult GetResultParentalRatings(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderParentalRatings"), topItem, - items.Where(x => x.OfficialRating != null) - .GroupBy(x => x.OfficialRating) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key.ToString(), - Value = x.Count().ToString() - }) - ); - - return result; - } - - - private ReportStatResult GetResultProductionYears(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderYears"), topItem, - items.Where(x => x.ProductionYear != null && x.ProductionYear > 0) - .GroupBy(x => x.ProductionYear) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key.ToString(), - Value = x.Count().ToString() - }) - ); - - return result; - } - - private ReportStatResult GetResulProductionLocations(ReportStatResult result, BaseItem[] items, int topItem = 5) - { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderCountries"), topItem, - items.OfType() - .Where(x => x.ProductionLocations != null) - .SelectMany(x => x.ProductionLocations) - .GroupBy(x => x) - .OrderByDescending(x => x.Count()) - .Take(topItem) - .Select(x => new ReportStatItem - { - Name = x.Key.ToString(), - Value = x.Count().ToString() - }) - ); - - return result; - } - - - /// Gets the groups. - /// The result. - /// The header. - /// The top item. - /// The top. - private void GetGroups(ReportStatResult result, string header, int topItem, IEnumerable top) - { - if (top.Count() > 0) - { - var group = new ReportStatGroup { Header = ReportStatGroup.FormatedHeader(header, topItem) }; - group.Items.AddRange(top); - result.Groups.Add(group); - } - } - } + /// A report stat builder. + /// + public class ReportStatBuilder : ReportBuilderBase + { + #region [Constructors] + + /// + /// Initializes a new instance of the MediaBrowser.Api.Reports.ReportStatBuilder class. + /// Manager for library. + public ReportStatBuilder(ILibraryManager libraryManager) + : base(libraryManager) + { + } + + #endregion + + #region [Public Methods] + + /// Gets report stat result. + /// The items. + /// List of types of the report include items. + /// The top item. + /// The report stat result. + public ReportStatResult GetResult(BaseItem[] items, ReportIncludeItemTypes reportIncludeItemTypes, int topItem = 5) + { + ReportStatResult result = new ReportStatResult(); + result = this.GetResultGenres(result, items, topItem); + result = this.GetResultStudios(result, items, topItem); + result = this.GetResultPersons(result, items, topItem); + result = this.GetResultProductionYears(result, items, topItem); + result = this.GetResulProductionLocations(result, items, topItem); + result = this.GetResultCommunityRatings(result, items, topItem); + result = this.GetResultParentalRatings(result, items, topItem); + + switch (reportIncludeItemTypes) + { + case ReportIncludeItemTypes.Season: + case ReportIncludeItemTypes.Series: + case ReportIncludeItemTypes.MusicAlbum: + case ReportIncludeItemTypes.MusicArtist: + case ReportIncludeItemTypes.Game: + break; + case ReportIncludeItemTypes.Movie: + case ReportIncludeItemTypes.BoxSet: + + break; + case ReportIncludeItemTypes.Book: + case ReportIncludeItemTypes.Episode: + case ReportIncludeItemTypes.Video: + case ReportIncludeItemTypes.MusicVideo: + case ReportIncludeItemTypes.Trailer: + case ReportIncludeItemTypes.Audio: + case ReportIncludeItemTypes.BaseItem: + default: + break; + } + + result.Groups = result.Groups.OrderByDescending(n => n.Items.Count()).ToList(); + + return result; + } + + #endregion + + #region [Protected Internal Methods] + /// Gets the headers. + /// Type of the header. + /// The request. + /// The headers. + /// + protected internal override List GetHeaders(H request) + { + throw new NotImplementedException(); + } + + #endregion + + #region [Private Methods] + + /// Gets the groups. + /// The result. + /// The header. + /// The top item. + /// The top. + private void GetGroups(ReportStatResult result, string header, int topItem, IEnumerable top) + { + if (top != null && top.Count() > 0) + { + var group = new ReportStatGroup { Header = ReportStatGroup.FormatedHeader(header, topItem) }; + group.Items.AddRange(top); + result.Groups.Add(group); + } + } + + /// Gets resul production locations. + /// The result. + /// The items. + /// The top item. + /// The resul production locations. + private ReportStatResult GetResulProductionLocations(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderCountries"), topItem, + items.OfType() + .Where(x => x.ProductionLocations != null) + .SelectMany(x => x.ProductionLocations) + .GroupBy(x => x) + .OrderByDescending(x => x.Count()) + .Take(topItem) + .Select(x => new ReportStatItem + { + Name = x.Key.ToString(), + Value = x.Count().ToString() + }) + ); + + return result; + } + + /// Gets result community ratings. + /// The result. + /// The items. + /// The top item. + /// The result community ratings. + private ReportStatResult GetResultCommunityRatings(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + this.GetGroups(result, ReportHelper.GetServerLocalizedString("LabelCommunityRating"), topItem, + items.Where(x => x.CommunityRating != null && x.CommunityRating > 0) + .GroupBy(x => x.CommunityRating) + .OrderByDescending(x => x.Count()) + .Take(topItem) + .Select(x => new ReportStatItem + { + Name = x.Key.ToString(), + Value = x.Count().ToString() + }) + ); + + return result; + } + + /// Gets result genres. + /// The result. + /// The items. + /// The top item. + /// The result genres. + private ReportStatResult GetResultGenres(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderGenres"), topItem, + items.SelectMany(x => x.Genres) + .GroupBy(x => x) + .OrderByDescending(x => x.Count()) + .Take(topItem) + .Select(x => new ReportStatItem + { + Name = x.Key, + Value = x.Count().ToString(), + Id = GetGenreID(x.Key) + })); + return result; + + } + + /// Gets result parental ratings. + /// The result. + /// The items. + /// The top item. + /// The result parental ratings. + private ReportStatResult GetResultParentalRatings(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderParentalRatings"), topItem, + items.Where(x => x.OfficialRating != null) + .GroupBy(x => x.OfficialRating) + .OrderByDescending(x => x.Count()) + .Take(topItem) + .Select(x => new ReportStatItem + { + Name = x.Key.ToString(), + Value = x.Count().ToString() + }) + ); + + return result; + } + + /// Gets result persons. + /// The result. + /// The items. + /// The top item. + /// The result persons. + private ReportStatResult GetResultPersons(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + List t = new List { PersonType.Actor, PersonType.Composer, PersonType.Director, PersonType.GuestStar, PersonType.Producer, PersonType.Writer, "Artist", "AlbumArtist" }; + foreach (var item in t) + { + var ps = items.Where(x => x.People != null && x.SupportsPeople).SelectMany(x => x.People) + .Where(n => n.Type == item) + .GroupBy(x => x.Name) + .OrderByDescending(x => x.Count()) + .Take(topItem); + if (ps != null && ps.Count() > 0) + this.GetGroups(result, ReportHelper.GetServerLocalizedString("Option" + item), topItem, + ps.Select(x => new ReportStatItem + { + Name = x.Key, + Value = x.Count().ToString(), + Id = GetPersonID(x.Key) + }) + ); + } + + return result; + } + + /// Gets result production years. + /// The result. + /// The items. + /// The top item. + /// The result production years. + private ReportStatResult GetResultProductionYears(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderYears"), topItem, + items.Where(x => x.ProductionYear != null && x.ProductionYear > 0) + .GroupBy(x => x.ProductionYear) + .OrderByDescending(x => x.Count()) + .Take(topItem) + .Select(x => new ReportStatItem + { + Name = x.Key.ToString(), + Value = x.Count().ToString() + }) + ); + + return result; + } + + /// Gets result studios. + /// The result. + /// The items. + /// The top item. + /// The result studios. + private ReportStatResult GetResultStudios(ReportStatResult result, BaseItem[] items, int topItem = 5) + { + this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderStudios"), topItem, + items.SelectMany(x => x.Studios) + .GroupBy(x => x) + .OrderByDescending(x => x.Count()) + .Take(topItem) + .Select(x => new ReportStatItem + { + Name = x.Key, + Value = x.Count().ToString(), + Id = GetStudioID(x.Key) + }) + ); + + return result; + + } + + #endregion + + } } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index d8628575a..c361e42f6 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1459,5 +1459,10 @@ "LabelUsername": "Username:", "HeaderSignUp": "Sign Up", "LabelPasswordConfirm": "Password (confirm):", - "ButtonAddServer": "Add Server" + "ButtonAddServer": "Add Server", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "OptionReportActivities": "Activities Log" } -- cgit v1.2.3 From fdab56529b522ed0c83ad48f46b1ea65459c02da Mon Sep 17 00:00:00 2001 From: Tavares André Date: Thu, 16 Jul 2015 20:35:53 +0200 Subject: Reports update --- .../Localization/Server/server.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 138c87712..5a1d9f29e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1468,5 +1468,10 @@ "HeaderNavigation": "Navigation", "LegendTheseSettingsShared": "These settings are shared on all devices", "OptionEnableAutomaticServerUpdates": "Enable automatic server updates", - "OptionOtherTrailers": "Include trailers from older movies" + "OptionOtherTrailers": "Include trailers from older movies", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "OptionReportActivities": "Activities Log" } -- cgit v1.2.3 From fe3b4a1230c26d6ace23e97b5f718d209a170302 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 17 Jul 2015 18:32:00 -0400 Subject: add more play buttons --- .../LiveTv/LiveTvManager.cs | 32 ++++++++++++++++++++-- .../FFMpeg/FFMpegDownloadInfo.cs | 16 +++++------ MediaBrowser.WebDashboard/Api/DashboardService.cs | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 9 +++--- 4 files changed, 44 insertions(+), 15 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index f6c69d8d6..9fef0560d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -55,6 +55,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1); + private ConcurrentDictionary _refreshedPrograms = new ConcurrentDictionary(); + public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager) { _config = config; @@ -615,11 +617,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } - _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); + var maxStartDate = DateTime.UtcNow.AddDays(3); + + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions + { + ImageRefreshMode = info.StartDate <= maxStartDate ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly + }); return item; } + private void RefreshIfNeeded(LiveTvProgram program) + { + if (_refreshedPrograms.TryAdd(program.Id, program.Id)) + { + _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions()); + } + } + private async Task CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken) { var isNew = false; @@ -720,6 +735,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var program = GetInternalProgram(id); + RefreshIfNeeded(program); + var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user); await AddRecordingInfo(new[] { dto }, cancellationToken).ConfigureAwait(false); @@ -786,7 +803,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv } var returnArray = returnPrograms - .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user)) + .Select(i => + { + RefreshIfNeeded(i); + return _dtoService.GetBaseItemDto(i, new DtoOptions(), user); + }) .ToArray(); await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); @@ -851,6 +872,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv var returnArray = programList.ToArray(); + foreach (var program in returnArray) + { + RefreshIfNeeded(program); + } + var result = new QueryResult { Items = returnArray, @@ -1038,6 +1064,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false); await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false); + _refreshedPrograms.Clear(); + // Load these now which will prefetch metadata var dtoOptions = new DtoOptions(); dtoOptions.Fields.Remove(ItemFields.SyncInfo); diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs index 8a7d10bd7..5c5bc10e7 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg case OperatingSystem.Linux: info.ArchiveType = "7z"; - info.Version = "20150331"; + info.Version = "20150717"; break; case OperatingSystem.Osx: @@ -54,7 +54,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20150331"; + info.Version = "20150717"; info.ArchiveType = "7z"; switch (environment.SystemArchitecture) @@ -83,14 +83,14 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg case Architecture.X86_X64: return new[] { - "http://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20150331-git-5cba529-win64-static.7z", - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150331-git-5cba529-win64-static.7z" + "http://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20150717-git-8250943-win64-static.7z", + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150717-git-8250943-win64-static.7z" }; case Architecture.X86: return new[] { - "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20150331-git-5cba529-win32-static.7z", - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150331-git-5cba529-win32-static.7z" + "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20150717-git-8250943-win32-static.7z", + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150717-git-8250943-win32-static.7z" }; } break; @@ -119,12 +119,12 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.6.1-64bit-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.7.1-64bit-static.7z" }; case Architecture.X86: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.6.1-32bit-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.7.1-32bit-static.7z" }; } break; diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index d6adfc68e..adf4ce895 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -136,7 +136,7 @@ namespace MediaBrowser.WebDashboard.Api { var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); - return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(page.GetHtmlStream(), null, null, false)); + return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(page.GetHtmlStream(), null, _appHost.ApplicationVersion.ToString(), null, false)); } /// diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index f50147552..7f7aa4a2d 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -63,7 +63,7 @@ namespace MediaBrowser.WebDashboard.Api { if (IsCoreHtml(path)) { - resourceStream = await ModifyHtml(resourceStream, mode, localizationCulture, enableMinification).ConfigureAwait(false); + resourceStream = await ModifyHtml(resourceStream, mode, appVersion, localizationCulture, enableMinification).ConfigureAwait(false); } } else if (IsFormat(path, "js")) @@ -243,10 +243,11 @@ namespace MediaBrowser.WebDashboard.Api /// /// The source stream. /// The mode. + /// The application version. /// The localization culture. /// if set to true [enable minification]. /// Task{Stream}. - public async Task ModifyHtml(Stream sourceStream, string mode, string localizationCulture, bool enableMinification) + public async Task ModifyHtml(Stream sourceStream, string mode, string appVersion, string localizationCulture, bool enableMinification) { using (sourceStream) { @@ -305,9 +306,9 @@ namespace MediaBrowser.WebDashboard.Api var version = GetType().Assembly.GetName().Version; - var imports = new string[] + var imports = new[] { - "vulcanize-out.html" + "vulcanize-out.html?v=" + appVersion }; var importsHtml = string.Join("", imports.Select(i => "").ToArray()); -- cgit v1.2.3 From 1279c6d8b5179017efb3fb9503d6937dcd84bc97 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 17 Jul 2015 22:52:27 -0400 Subject: fix roku live tv stream closing --- MediaBrowser.Api/MediaBrowser.Api.csproj | 7 ------- MediaBrowser.Providers/Manager/ProviderManager.cs | 3 +++ MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs | 7 +++++-- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 249d10a12..e1235c935 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -208,13 +208,6 @@ - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - "); - if (enableMinification) { try @@ -300,6 +297,9 @@ namespace MediaBrowser.WebDashboard.Api _logger.ErrorException("Error minifying html", ex); } } + + html = html.Replace("", "
"); } var versionString = !string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) ? "?v=" + appVersion : string.Empty; @@ -316,7 +316,7 @@ namespace MediaBrowser.WebDashboard.Api html = html.Replace("", "" + GetMetaTags(mode) + GetCommonCss(mode, appVersion)); - html = html.Replace("", GetInitialJavascript(mode, appVersion) + importsHtml + GetCommonJavascript(mode, appVersion)) + ""; + html = html.Replace("", GetInitialJavascript(mode, appVersion) + importsHtml + GetCommonJavascript(mode, appVersion) + ""); var bytes = Encoding.UTF8.GetBytes(html); -- cgit v1.2.3 From 162d6dd917e6d6e966a83e65c4ec1d340e602540 Mon Sep 17 00:00:00 2001 From: Tavares André Date: Tue, 28 Jul 2015 13:32:08 +0200 Subject: Reports - update localization --- .../Reports/Activities/ReportActivitiesBuilder.cs | 1 + MediaBrowser.Api/Reports/Common/HeaderMetadata.cs | 11 +++++ .../Reports/Common/ReportBuilderBase.cs | 4 +- MediaBrowser.Api/Reports/Common/ReportHelper.cs | 14 ++---- MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs | 28 ++++++++---- .../Localization/Core/core.json | 52 +++++++++++++++++++++- 6 files changed, 86 insertions(+), 24 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs b/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs index 33d36f11b..83816c6e3 100644 --- a/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs +++ b/MediaBrowser.Api/Reports/Activities/ReportActivitiesBuilder.cs @@ -130,6 +130,7 @@ namespace MediaBrowser.Api.Reports { case HeaderMetadata.Name: option.Column = (i, r) => i.Name; + option.Header.SortField = ""; break; case HeaderMetadata.Overview: option.Column = (i, r) => i.Overview; diff --git a/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs b/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs index 74fcdd149..af5abf46a 100644 --- a/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs +++ b/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs @@ -47,6 +47,17 @@ namespace MediaBrowser.Api.Reports ImagePrimary, ImageBackdrop, ImageLogo, + Actor, + Studios, + Composer, + Director, + GuestStar, + Producer, + Writer, + Artist, + Years, + ParentalRatings, + CommunityRatings, //Activity logs Overview, diff --git a/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs b/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs index 81b441a07..6e1dd8d35 100644 --- a/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs +++ b/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs @@ -155,9 +155,7 @@ namespace MediaBrowser.Api.Reports if (internalHeader != HeaderMetadata.None) { string localHeader = "Header" + internalHeader.ToString(); - headerName = internalHeader != HeaderMetadata.None ? ReportHelper.GetJavaScriptLocalizedString(localHeader) : ""; - if (string.Compare(localHeader, headerName, StringComparison.CurrentCultureIgnoreCase) == 0) - headerName = ReportHelper.GetServerLocalizedString(localHeader); + headerName = ReportHelper.GetCoreLocalizedString(localHeader); } return headerName; } diff --git a/MediaBrowser.Api/Reports/Common/ReportHelper.cs b/MediaBrowser.Api/Reports/Common/ReportHelper.cs index c70cedf61..9dc4fbd51 100644 --- a/MediaBrowser.Api/Reports/Common/ReportHelper.cs +++ b/MediaBrowser.Api/Reports/Common/ReportHelper.cs @@ -76,14 +76,6 @@ namespace MediaBrowser.Api.Reports return rType; } - /// Gets java script localized string. - /// The phrase. - /// The java script localized string. - public static string GetJavaScriptLocalizedString(string phrase) - { - return BaseItem.LocalizationManager.GetLocalizedString(phrase); - } - /// Gets report view type. /// The type. /// The report view type. @@ -132,10 +124,10 @@ namespace MediaBrowser.Api.Reports return rType; } - /// Gets server localized string. + /// Gets core localized string. /// The phrase. - /// The server localized string. - public static string GetServerLocalizedString(string phrase) + /// The core localized string. + public static string GetCoreLocalizedString(string phrase) { return BaseItem.LocalizationManager.GetLocalizedString(phrase); } diff --git a/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs b/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs index 8cb57c030..c9ee6337f 100644 --- a/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs +++ b/MediaBrowser.Api/Reports/Stat/ReportStatBuilder.cs @@ -110,7 +110,7 @@ namespace MediaBrowser.Api.Reports /// The resul production locations. private ReportStatResult GetResulProductionLocations(ReportStatResult result, BaseItem[] items, int topItem = 5) { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderCountries"), topItem, + this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.Countries), topItem, items.OfType() .Where(x => x.ProductionLocations != null) .SelectMany(x => x.ProductionLocations) @@ -134,7 +134,7 @@ namespace MediaBrowser.Api.Reports /// The result community ratings. private ReportStatResult GetResultCommunityRatings(ReportStatResult result, BaseItem[] items, int topItem = 5) { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("LabelCommunityRating"), topItem, + this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.CommunityRating), topItem, items.Where(x => x.CommunityRating != null && x.CommunityRating > 0) .GroupBy(x => x.CommunityRating) .OrderByDescending(x => x.Count()) @@ -156,7 +156,7 @@ namespace MediaBrowser.Api.Reports /// The result genres. private ReportStatResult GetResultGenres(ReportStatResult result, BaseItem[] items, int topItem = 5) { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderGenres"), topItem, + this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.Genres), topItem, items.SelectMany(x => x.Genres) .GroupBy(x => x) .OrderByDescending(x => x.Count()) @@ -178,7 +178,7 @@ namespace MediaBrowser.Api.Reports /// The result parental ratings. private ReportStatResult GetResultParentalRatings(ReportStatResult result, BaseItem[] items, int topItem = 5) { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderParentalRatings"), topItem, + this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.ParentalRatings), topItem, items.Where(x => x.OfficialRating != null) .GroupBy(x => x.OfficialRating) .OrderByDescending(x => x.Count()) @@ -200,16 +200,26 @@ namespace MediaBrowser.Api.Reports /// The result persons. private ReportStatResult GetResultPersons(ReportStatResult result, BaseItem[] items, int topItem = 5) { - List t = new List { PersonType.Actor, PersonType.Composer, PersonType.Director, PersonType.GuestStar, PersonType.Producer, PersonType.Writer, "Artist", "AlbumArtist" }; + List t = new List + { + HeaderMetadata.Actor, + HeaderMetadata.Composer, + HeaderMetadata.Director, + HeaderMetadata.GuestStar, + HeaderMetadata.Producer, + HeaderMetadata.Writer, + HeaderMetadata.Artist, + HeaderMetadata.AlbumArtist + }; foreach (var item in t) { var ps = items.Where(x => x.People != null && x.SupportsPeople).SelectMany(x => x.People) - .Where(n => n.Type == item) + .Where(n => n.Type == item.ToString()) .GroupBy(x => x.Name) .OrderByDescending(x => x.Count()) .Take(topItem); if (ps != null && ps.Count() > 0) - this.GetGroups(result, ReportHelper.GetServerLocalizedString("Option" + item), topItem, + this.GetGroups(result, GetLocalizedHeader(item), topItem, ps.Select(x => new ReportStatItem { Name = x.Key, @@ -229,7 +239,7 @@ namespace MediaBrowser.Api.Reports /// The result production years. private ReportStatResult GetResultProductionYears(ReportStatResult result, BaseItem[] items, int topItem = 5) { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderYears"), topItem, + this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.Year), topItem, items.Where(x => x.ProductionYear != null && x.ProductionYear > 0) .GroupBy(x => x.ProductionYear) .OrderByDescending(x => x.Count()) @@ -251,7 +261,7 @@ namespace MediaBrowser.Api.Reports /// The result studios. private ReportStatResult GetResultStudios(ReportStatResult result, BaseItem[] items, int topItem = 5) { - this.GetGroups(result, ReportHelper.GetServerLocalizedString("HeaderStudios"), topItem, + this.GetGroups(result, GetLocalizedHeader(HeaderMetadata.Studios), topItem, items.SelectMany(x => x.Studios) .GroupBy(x => x) .OrderByDescending(x => x.Count()) diff --git a/MediaBrowser.Server.Implementations/Localization/Core/core.json b/MediaBrowser.Server.Implementations/Localization/Core/core.json index 607436054..44a10f0a9 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/core.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/core.json @@ -125,5 +125,55 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings", + + } -- cgit v1.2.3 From 3799ad594080f6476119e59e8d4631c4354ee598 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jul 2015 08:33:30 -0400 Subject: update task triggers --- .../ScheduledTasks/ScheduledTaskWorker.cs | 4 +- .../ScheduledTasks/Tasks/DeleteCacheFileTask.cs | 3 - .../ScheduledTasks/Tasks/DeleteLogFileTask.cs | 3 - MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs | 8 ++- MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs | 8 ++- .../ScheduledTasks/IntervalTrigger.cs | 24 ++++++-- .../ScheduledTasks/StartupTrigger.cs | 8 ++- .../ScheduledTasks/SystemEventTrigger.cs | 7 ++- .../ScheduledTasks/WeeklyTrigger.cs | 4 +- MediaBrowser.Controller/Entities/BaseItem.cs | 12 ++++ .../Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Library/ILibraryManager.cs | 2 +- .../Channels/RefreshChannelsScheduledTask.cs | 4 -- .../LiveTv/LiveTvManager.cs | 44 +++++++------- .../LiveTv/RefreshChannelsScheduledTask.cs | 9 +-- .../Persistence/SqliteItemRepository.cs | 70 +++++++++++++--------- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 3 - .../Sync/SyncConvertScheduledTask.cs | 3 +- .../UserViews/DynamicImageProvider.cs | 4 -- 19 files changed, 127 insertions(+), 94 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index c2551731f..cbd1c1ac5 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -312,7 +312,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks trigger.Triggered -= trigger_Triggered; trigger.Triggered += trigger_Triggered; - trigger.Start(isApplicationStartup); + trigger.Start(LastExecutionResult, isApplicationStartup); } } @@ -340,7 +340,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks await Task.Delay(1000).ConfigureAwait(false); - trigger.Start(false); + trigger.Start(LastExecutionResult, false); } private Task _currentTask; diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index eb2b46c22..d9c178d8b 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs @@ -45,9 +45,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks // Until we can vary these default triggers per server and MBT, we need something that makes sense for both return new ITaskTrigger[] { - // At startup - new StartupTrigger {DelayMs = 60000}, - // Every so often new IntervalTrigger { Interval = TimeSpan.FromHours(24)} }; diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs index 6b9bcbfc1..b2759c52a 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs @@ -42,9 +42,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks // Until we can vary these default triggers per server and MBT, we need something that makes sense for both return new ITaskTrigger[] { - // At startup - new StartupTrigger {DelayMs = 30000}, - // Every so often new IntervalTrigger { Interval = TimeSpan.FromHours(24)} }; diff --git a/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs b/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs index 2f935607b..382a41255 100644 --- a/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/DailyTrigger.cs @@ -1,6 +1,7 @@ -using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; using System.Threading; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -32,8 +33,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { DisposeTimer(); diff --git a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs index d30111316..8c87f8f38 100644 --- a/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/ITaskTrigger.cs @@ -1,5 +1,6 @@ -using System; -using MediaBrowser.Model.Events; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; namespace MediaBrowser.Common.ScheduledTasks { @@ -16,8 +17,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - void Start(bool isApplicationStartup); + void Start(TaskResult lastResult, bool isApplicationStartup); /// /// Stops waiting for the trigger action diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index 455a70d7e..41073516a 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -1,6 +1,7 @@ -using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; using System.Threading; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -32,12 +33,27 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { DisposeTimer(); - Timer = new Timer(state => OnTriggered(), null, Interval, TimeSpan.FromMilliseconds(-1)); + var triggerDate = lastResult != null ? + lastResult.EndTimeUtc.Add(Interval) : + DateTime.UtcNow.Add(Interval); + + if (DateTime.UtcNow > triggerDate) + { + triggerDate = DateTime.UtcNow; + + if (isApplicationStartup) + { + triggerDate = triggerDate.AddMinutes(1); + } + } + + Timer = new Timer(state => OnTriggered(), null, triggerDate - DateTime.UtcNow, TimeSpan.FromMilliseconds(-1)); } /// diff --git a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs index a58fa22b9..1d82dc76a 100644 --- a/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/StartupTrigger.cs @@ -1,6 +1,7 @@ -using System; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; +using System; using System.Threading.Tasks; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -27,8 +28,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public async void Start(bool isApplicationStartup) + public async void Start(TaskResult lastResult, bool isApplicationStartup) { if (isApplicationStartup) { diff --git a/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs b/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs index a40dc6b5c..eaf4afc75 100644 --- a/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/SystemEventTrigger.cs @@ -1,8 +1,8 @@ -using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; using Microsoft.Win32; using System; using System.Threading.Tasks; -using MediaBrowser.Model.Events; namespace MediaBrowser.Common.ScheduledTasks { @@ -28,8 +28,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { switch (SystemEvent) { diff --git a/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs b/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs index a3818f83f..2e38264b2 100644 --- a/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/WeeklyTrigger.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using MediaBrowser.Model.Events; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Common.ScheduledTasks { @@ -38,8 +39,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// /// Stars waiting for the trigger action /// + /// The last result. /// if set to true [is application startup]. - public void Start(bool isApplicationStartup) + public void Start(TaskResult lastResult, bool isApplicationStartup) { DisposeTimer(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d9dbf265f..3062c00e7 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1115,6 +1115,18 @@ namespace MediaBrowser.Controller.Entities return value.Value <= maxAllowedRating.Value; } + public int? GetParentalRatingValue() + { + var rating = CustomRatingForComparison; + + if (string.IsNullOrWhiteSpace(rating)) + { + rating = OfficialRatingForComparison; + } + + return LocalizationManager.GetRatingLevel(rating); + } + private bool IsVisibleViaTags(User user) { var hasTags = this as IHasTags; diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 3702716f9..c9603c7e3 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -94,6 +94,7 @@ namespace MediaBrowser.Controller.Entities public string[] ChannelIds { get; set; } internal List ItemIdsFromPersonFilters { get; set; } + public int? MaxParentalRating { get; set; } public InternalItemsQuery() { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index f0bfaaf66..77c07dfd4 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -5,12 +5,12 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Library { diff --git a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index c6ecfc250..b1491d594 100644 --- a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -42,10 +42,6 @@ namespace MediaBrowser.Server.Implementations.Channels { return new ITaskTrigger[] { - new StartupTrigger{DelayMs = 10000}, - - new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - new IntervalTrigger{ Interval = TimeSpan.FromHours(24)} }; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d8e60be5a..d8954724a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -13,6 +13,7 @@ using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; @@ -772,9 +773,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv MaxStartDate = query.MaxStartDate, ChannelIds = query.ChannelIds, IsMovie = query.IsMovie, - IsSports = query.IsSports + IsSports = query.IsSports, + Genres = query.Genres }; + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); + if (user != null) + { + internalQuery.MaxParentalRating = user.Policy.MaxParentalRating; + + if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) + { + internalQuery.HasParentalRating = true; + } + } + if (query.HasAired.HasValue) { if (query.HasAired.Value) @@ -789,20 +802,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); - // Apply genre filter - if (query.Genres.Length > 0) - { - programs = programs.Where(p => p.Genres.Any(g => query.Genres.Contains(g, StringComparer.OrdinalIgnoreCase))); - } - - var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); - if (user != null) - { - // Avoid implicitly captured closure - var currentUser = user; - programs = programs.Where(i => i.IsVisible(currentUser)); - } - programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending) .Cast(); @@ -860,13 +859,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); - var user = _userManager.GetUserById(query.UserId); + if (user != null) + { + internalQuery.MaxParentalRating = user.Policy.MaxParentalRating; - // Avoid implicitly captured closure - var currentUser = user; - programs = programs.Where(i => i.IsVisible(currentUser)); + if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram)) + { + internalQuery.HasParentalRating = true; + } + } + + IEnumerable programs = _libraryManager.GetItems(internalQuery).Items.Cast(); var programList = programs.ToList(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs index fa1a8b3e7..d8d91c2f9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs @@ -2,7 +2,6 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; using System.Linq; @@ -47,11 +46,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { return new ITaskTrigger[] { - new StartupTrigger(), - - new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - - new IntervalTrigger{ Interval = TimeSpan.FromHours(4)} + new IntervalTrigger{ Interval = TimeSpan.FromHours(12)} }; } @@ -59,7 +54,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { return _config.GetConfiguration("livetv"); } - + public bool IsHidden { get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Count(i => i.IsEnabled) == 0; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9ce239eb9..3ec45c4de 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -157,6 +157,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "PremiereDate", "DATETIME"); _connection.AddColumn(_logger, "TypedBaseItems", "ProductionYear", "INT"); _connection.AddColumn(_logger, "TypedBaseItems", "ParentId", "GUID"); + _connection.AddColumn(_logger, "TypedBaseItems", "Genres", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "ParentalRatingValue", "INT"); PrepareStatements(); @@ -197,10 +199,12 @@ namespace MediaBrowser.Server.Implementations.Persistence "ParentIndexNumber", "PremiereDate", "ProductionYear", - "ParentId" + "ParentId", + "Genres", + "ParentalRatingValue" }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24)"; for (var i = 1; i <= saveColumns.Count; i++) { _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); @@ -343,6 +347,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.ParentId; } + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); + _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue(); + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -937,7 +944,39 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("Name like @NameContains"); cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%"; } - + + if (query.Genres.Length > 0) + { + var genres = new List(); + var index = 0; + foreach (var genre in query.Genres) + { + genres.Add("Genres like @Genres" + index); + cmd.Parameters.Add(cmd, "@Genres" + index, DbType.String).Value = "%" + genre + "%"; + index++; + } + var genreCaluse = "(" + string.Join(" OR ", genres.ToArray()) + ")"; + whereClauses.Add(genreCaluse); + } + + if (query.MaxParentalRating.HasValue) + { + whereClauses.Add("(ParentalRatingValue is NULL OR ParentalRatingValue<=@MaxParentalRating)"); + cmd.Parameters.Add(cmd, "@MaxParentalRating", DbType.Int32).Value = query.MaxParentalRating.Value; + } + + if (query.HasParentalRating.HasValue) + { + if (query.HasParentalRating.Value) + { + whereClauses.Add("ParentalRatingValue NOT NULL"); + } + else + { + whereClauses.Add("ParentalRatingValue IS NULL"); + } + } + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -1021,31 +1060,6 @@ namespace MediaBrowser.Server.Implementations.Persistence return new[] { value }; } - public IEnumerable GetItemIdsOfType(Type type) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - CheckDisposed(); - - using (var cmd = _connection.CreateCommand()) - { - cmd.CommandText = "select guid from TypedBaseItems where type = @type"; - - cmd.Parameters.Add(cmd, "@type", DbType.String).Value = type.FullName; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) - { - yield return reader.GetGuid(0); - } - } - } - } - public async Task DeleteItem(Guid id, CancellationToken cancellationToken) { if (id == Guid.Empty) diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index 0ac53c987..824d859f3 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Tasks; using MediaBrowser.Server.Implementations.Library; using System; using System.Collections.Generic; @@ -38,8 +37,6 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks new StartupTrigger(), - new SystemEventTrigger{ SystemEvent = SystemEvent.WakeFromSleep}, - new IntervalTrigger{ Interval = TimeSpan.FromHours(6)} }; } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs index 913d50e9d..5347e1d83 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs @@ -70,8 +70,7 @@ namespace MediaBrowser.Server.Implementations.Sync { return new ITaskTrigger[] { - new IntervalTrigger { Interval = TimeSpan.FromHours(3) }, - new StartupTrigger{ DelayMs = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalMilliseconds)} + new IntervalTrigger { Interval = TimeSpan.FromHours(3) } }; } diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 3d77f831e..0162b8802 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -143,7 +143,6 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.TvFavoriteEpisodes, SpecialFolder.TvFavoriteSeries, SpecialFolder.TvGenres, - SpecialFolder.TvGenre, SpecialFolder.TvLatest, SpecialFolder.TvNextUp, SpecialFolder.TvResume, @@ -152,14 +151,12 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.MovieCollections, SpecialFolder.MovieFavorites, SpecialFolder.MovieGenres, - SpecialFolder.MovieGenre, SpecialFolder.MovieLatest, SpecialFolder.MovieMovies, SpecialFolder.MovieResume, SpecialFolder.GameFavorites, SpecialFolder.GameGenres, - SpecialFolder.GameGenre, SpecialFolder.GameSystems, SpecialFolder.LatestGames, SpecialFolder.RecentlyPlayedGames, @@ -168,7 +165,6 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.MusicAlbumArtists, SpecialFolder.MusicAlbums, SpecialFolder.MusicGenres, - SpecialFolder.MusicGenre, SpecialFolder.MusicLatest, SpecialFolder.MusicPlaylists, SpecialFolder.MusicSongs, -- cgit v1.2.3 From d95057f13bb6d8bfe04ce20138f8cd2fc66c3519 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jul 2015 15:42:24 -0400 Subject: rework settings page --- MediaBrowser.Controller/Entities/BaseItem.cs | 5 +++++ MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 4 ++-- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 14 ++++++++++++++ .../MediaEncoding/ISubtitleEncoder.cs | 18 ------------------ .../Subtitles/SubtitleEncoder.cs | 17 +++++------------ .../IO/LibraryMonitor.cs | 16 ++++++++++++++-- .../Library/LibraryManager.cs | 15 +++++++++------ .../Localization/Core/core.json | 4 +--- .../MediaBrowser.WebDashboard.csproj | 1 + 9 files changed, 51 insertions(+), 43 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 3062c00e7..c4917b0d1 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1124,6 +1124,11 @@ namespace MediaBrowser.Controller.Entities rating = OfficialRatingForComparison; } + if (string.IsNullOrWhiteSpace(rating)) + { + return null; + } + return LocalizationManager.GetRatingLevel(rating); } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index c9603c7e3..227a6bd0e 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 8232c5c7a..b54a7aaee 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -227,5 +227,19 @@ namespace MediaBrowser.Controller.LiveTv info.IsMovie = IsMovie; return info; } + + public override bool SupportsPeople + { + get + { + // Optimization + if (IsNews || IsSports) + { + return false; + } + + return base.SupportsPeople; + } + } } } diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index e4a2cd007..826711e51 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -7,24 +7,6 @@ namespace MediaBrowser.Controller.MediaEncoding { public interface ISubtitleEncoder { - /// - /// Converts the subtitles. - /// - /// The stream. - /// The input format. - /// The output format. - /// The start time ticks. - /// The end time ticks. - /// The cancellation token. - /// Task{Stream}. - Task ConvertSubtitles( - Stream stream, - string inputFormat, - string outputFormat, - long startTimeTicks, - long? endTimeTicks, - CancellationToken cancellationToken); - /// /// Gets the subtitles. /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 60b70ad08..fe616c63e 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } - public async Task ConvertSubtitles(Stream stream, + private async Task ConvertSubtitles(Stream stream, string inputFormat, string outputFormat, long startTimeTicks, @@ -64,7 +64,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { - var trackInfo = await GetTrackInfo(stream, inputFormat, cancellationToken).ConfigureAwait(false); + var reader = GetReader(inputFormat, true); + + var trackInfo = reader.Parse(stream, cancellationToken); FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false); @@ -190,7 +192,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { throw new ArgumentNullException("charset"); } - + try { return Encoding.GetEncoding(charset); @@ -257,15 +259,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles return new Tuple(subtitleStream.Path, protocol, currentFormat, true); } - private async Task GetTrackInfo(Stream stream, - string inputFormat, - CancellationToken cancellationToken) - { - var reader = GetReader(inputFormat, true); - - return reader.Parse(stream, cancellationToken); - } - private ISubtitleParser GetReader(string format, bool throwIfMissing) { if (string.IsNullOrEmpty(format)) diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index d6a1be962..26ccdfc9a 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.IO; +using System.ComponentModel; +using MediaBrowser.Common.IO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -338,7 +339,7 @@ namespace MediaBrowser.Server.Implementations.IO } catch { - + } finally { @@ -370,6 +371,17 @@ namespace MediaBrowser.Server.Implementations.IO Logger.ErrorException("Error in Directory watcher for: " + dw.Path, ex); DisposeWatcher(dw); + + if (ex is Win32Exception) + { + Logger.Info("Disabling realtime monitor to prevent future instability"); + + if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto) + { + ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled; + Stop(); + } + } } /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 8d51e3e92..497a198fd 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -2071,14 +2071,17 @@ namespace MediaBrowser.Server.Implementations.Library public List GetPeople(BaseItem item) { - var people = GetPeople(new InternalPeopleQuery + if (item.SupportsPeople) { - ItemId = item.Id - }); + var people = GetPeople(new InternalPeopleQuery + { + ItemId = item.Id + }); - if (people.Count > 0) - { - return people; + if (people.Count > 0) + { + return people; + } } return item.People ?? new List(); diff --git a/MediaBrowser.Server.Implementations/Localization/Core/core.json b/MediaBrowser.Server.Implementations/Localization/Core/core.json index 44a10f0a9..4eb66929d 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/core.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/core.json @@ -173,7 +173,5 @@ "HeaderProducer": "Producers", "HeaderWriter": "Writers", "HeaderParentalRatings": "Parental Ratings", - "HeaderCommunityRatings": "Community ratings", - - + "HeaderCommunityRatings": "Community ratings" } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index f585a7c26..3e67540d8 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -204,6 +204,7 @@ PreserveNewest + PreserveNewest -- cgit v1.2.3 From a28feadfac025368d52c4fa6839360f24f86b165 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jul 2015 15:53:57 -0400 Subject: update translations --- .../Localization/Core/ar.json | 50 ++++++++++++++++++- .../Localization/Core/bg-BG.json | 50 ++++++++++++++++++- .../Localization/Core/ca.json | 50 ++++++++++++++++++- .../Localization/Core/cs.json | 50 ++++++++++++++++++- .../Localization/Core/da.json | 50 ++++++++++++++++++- .../Localization/Core/de.json | 56 +++++++++++++++++++-- .../Localization/Core/el.json | 50 ++++++++++++++++++- .../Localization/Core/en-GB.json | 50 ++++++++++++++++++- .../Localization/Core/en-US.json | 50 ++++++++++++++++++- .../Localization/Core/es-AR.json | 50 ++++++++++++++++++- .../Localization/Core/es-MX.json | 56 +++++++++++++++++++-- .../Localization/Core/es.json | 50 ++++++++++++++++++- .../Localization/Core/fi.json | 50 ++++++++++++++++++- .../Localization/Core/fr.json | 50 ++++++++++++++++++- .../Localization/Core/gsw.json | 50 ++++++++++++++++++- .../Localization/Core/he.json | 50 ++++++++++++++++++- .../Localization/Core/hr.json | 50 ++++++++++++++++++- .../Localization/Core/it.json | 50 ++++++++++++++++++- .../Localization/Core/kk.json | 50 ++++++++++++++++++- .../Localization/Core/ko.json | 50 ++++++++++++++++++- .../Localization/Core/ms.json | 50 ++++++++++++++++++- .../Localization/Core/nb.json | 50 ++++++++++++++++++- .../Localization/Core/nl.json | 50 ++++++++++++++++++- .../Localization/Core/pl.json | 50 ++++++++++++++++++- .../Localization/Core/pt-BR.json | 56 +++++++++++++++++++-- .../Localization/Core/pt-PT.json | 50 ++++++++++++++++++- .../Localization/Core/ro.json | 50 ++++++++++++++++++- .../Localization/Core/ru.json | 58 ++++++++++++++++++++-- .../Localization/Core/sl-SI.json | 50 ++++++++++++++++++- .../Localization/Core/sv.json | 50 ++++++++++++++++++- .../Localization/Core/tr.json | 50 ++++++++++++++++++- .../Localization/Core/uk.json | 50 ++++++++++++++++++- .../Localization/Core/vi.json | 50 ++++++++++++++++++- .../Localization/Core/zh-CN.json | 50 ++++++++++++++++++- .../Localization/Core/zh-TW.json | 50 ++++++++++++++++++- .../MediaBrowser.WebDashboard.csproj | 13 ++--- 36 files changed, 1733 insertions(+), 56 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ar.json b/MediaBrowser.Server.Implementations/Localization/Core/ar.json index 96fcf8151..3d15d7b2e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ar.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ar.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json b/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json index 479084e56..8854611a0 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/bg-BG.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e", + "HeaderVideo": "\u0412\u0438\u0434\u0435\u043e", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435:", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ca.json b/MediaBrowser.Server.Implementations/Localization/Core/ca.json index 623d71dac..35f2bafb8 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ca.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/cs.json b/MediaBrowser.Server.Implementations/Localization/Core/cs.json index 3fe981725..ee30a6028 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/cs.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/cs.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "U\u017eivatel", + "HeaderName": "N\u00e1zev", + "HeaderDate": "Datum", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Zvuk", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Titulky", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Stav", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/da.json b/MediaBrowser.Server.Implementations/Localization/Core/da.json index d7a593380..21d7e9e14 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/da.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/da.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "Bruger", + "HeaderName": "Navn", + "HeaderDate": "Dato", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Udgivelsesdato", + "HeaderRuntime": "Varighed", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "S\u00e6son", + "HeaderSeasonNumber": "S\u00e6sonnummer", + "HeaderSeries": "Series:", + "HeaderNetwork": "Netv\u00e6rk", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "F\u00e6llesskabsvurdering", + "HeaderTrailers": "Trailere", + "HeaderSpecials": "S\u00e6rudsendelser", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disk", + "HeaderTrack": "Spor", + "HeaderAudio": "Lyd", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Indlejret billede", + "HeaderResolution": "Opl\u00f8sning", + "HeaderSubtitles": "Undertekster", + "HeaderGenres": "Genrer", + "HeaderCountries": "Lande", + "HeaderStatus": "Status", + "HeaderTracks": "Spor", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studier", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Aldersgr\u00e6nser", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/de.json b/MediaBrowser.Server.Implementations/Localization/Core/de.json index f594e53d0..f61988628 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/de.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/de.json @@ -120,9 +120,57 @@ "UserStartedPlayingItemWithValues": "{0} hat die Wiedergabe von {1} gestartet", "UserStoppedPlayingItemWithValues": "{0} hat die Wiedergabe von {1} beendet", "SubtitleDownloadFailureForItem": "Download der Untertitel fehlgeschlagen f\u00fcr {0}", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", + "HeaderUnidentified": "Nicht identifiziert", + "HeaderImagePrimary": "Bevorzugt", + "HeaderImageBackdrop": "Hintergrund", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "Benutzerbild", + "HeaderOverview": "\u00dcbersicht", + "HeaderShortOverview": "Kurz\u00fcbersicht", + "HeaderType": "Typ", + "HeaderSeverity": "Severity", + "HeaderUser": "Benutzer", + "HeaderName": "Name", + "HeaderDate": "Datum", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Ver\u00f6ffentlichungsdatum", + "HeaderRuntime": "Laufzeit", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Staffel", + "HeaderSeasonNumber": "Staffel Nummer", + "HeaderSeries": "Series:", + "HeaderNetwork": "Netzwerk", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community Bewertung", + "HeaderTrailers": "Trailer", + "HeaderSpecials": "Extras", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Alben", + "HeaderDisc": "Disc", + "HeaderTrack": "St\u00fcck", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Integriertes Bild", + "HeaderResolution": "Aufl\u00f6sung", + "HeaderSubtitles": "Untertitel", + "HeaderGenres": "Genres", + "HeaderCountries": "L\u00e4nder", + "HeaderStatus": "Status", + "HeaderTracks": "Lieder", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Blockiert", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Altersbeschr\u00e4nkung", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/el.json b/MediaBrowser.Server.Implementations/Localization/Core/el.json index 11bad7d9a..213868042 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/el.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/el.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "\u0389\u03c7\u03bf\u03c2", + "HeaderVideo": "\u0392\u03af\u03bd\u03c4\u03b5\u03bf", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/en-GB.json b/MediaBrowser.Server.Implementations/Localization/Core/en-GB.json index b33e5be85..566d2cf09 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/en-GB.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/en-GB.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/en-US.json b/MediaBrowser.Server.Implementations/Localization/Core/en-US.json index d5d831cef..abe203804 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/en-US.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/en-US.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/es-AR.json b/MediaBrowser.Server.Implementations/Localization/Core/es-AR.json index ca1158fd3..9c1ea6cb9 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/es-AR.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/es-AR.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json b/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json index 76ee89803..9765ed056 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json @@ -120,9 +120,57 @@ "UserStartedPlayingItemWithValues": "{0} ha iniciado la reproducci\u00f3n de {1}", "UserStoppedPlayingItemWithValues": "{0} ha detenido la reproducci\u00f3n de {1}", "SubtitleDownloadFailureForItem": "Fall\u00f3 la descarga de subt\u00edtulos para {0}", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", + "HeaderUnidentified": "No Identificado", + "HeaderImagePrimary": "Principal", + "HeaderImageBackdrop": "Imagen de Fondo", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "Imagen de Usuario", + "HeaderOverview": "Resumen", + "HeaderShortOverview": "Sinopsis corta:", + "HeaderType": "Tipo", + "HeaderSeverity": "Severidad", + "HeaderUser": "Usuario", + "HeaderName": "Nombre", + "HeaderDate": "Fecha", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Fecha de estreno", + "HeaderRuntime": "Duraci\u00f3n", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Temporada", + "HeaderSeasonNumber": "N\u00famero de temporada", + "HeaderSeries": "Series:", + "HeaderNetwork": "Cadena", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Calificaci\u00f3n de la comunidad", + "HeaderTrailers": "Tr\u00e1ilers", + "HeaderSpecials": "Especiales", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "\u00c1lbumes", + "HeaderDisc": "Disco", + "HeaderTrack": "Pista", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Im\u00e1gen embebida", + "HeaderResolution": "Resoluci\u00f3n", + "HeaderSubtitles": "Subt\u00edtulos", + "HeaderGenres": "G\u00e9neros", + "HeaderCountries": "Pa\u00edses", + "HeaderStatus": "Estado", + "HeaderTracks": "Pistas", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Bloqueado", + "HeaderStudios": "Estudios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Clasificaci\u00f3n Parental", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/es.json b/MediaBrowser.Server.Implementations/Localization/Core/es.json index 0d3aa19e1..f93fd7219 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/es.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/es.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "Usuario", + "HeaderName": "Nombre", + "HeaderDate": "Fecha", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subt\u00edtulos", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Estado", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/fi.json b/MediaBrowser.Server.Implementations/Localization/Core/fi.json index 5985430da..5df95146c 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/fi.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/fi.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/fr.json b/MediaBrowser.Server.Implementations/Localization/Core/fr.json index 38f3eb6c5..9328c5c5d 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/fr.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primaire", "HeaderImageBackdrop": "Contexte", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "Avatar de l'utilisateur" + "HeaderUserPrimaryImage": "Avatar de l'utilisateur", + "HeaderOverview": "Aper\u00e7u", + "HeaderShortOverview": "Synopsys", + "HeaderType": "Type", + "HeaderSeverity": "S\u00e9v\u00e9rit\u00e9", + "HeaderUser": "Utilisateur", + "HeaderName": "Nom", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Date de sortie ", + "HeaderRuntime": "Dur\u00e9e", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Saison", + "HeaderSeasonNumber": "Num\u00e9ro de saison", + "HeaderSeries": "Series:", + "HeaderNetwork": "R\u00e9seau", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Note de la communaut\u00e9", + "HeaderTrailers": "Bandes-annonces", + "HeaderSpecials": "Episodes sp\u00e9ciaux", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disque", + "HeaderTrack": "Piste", + "HeaderAudio": "Audio", + "HeaderVideo": "Vid\u00e9o", + "HeaderEmbeddedImage": "Image int\u00e9gr\u00e9e", + "HeaderResolution": "R\u00e9solution", + "HeaderSubtitles": "Sous-titres", + "HeaderGenres": "Genres", + "HeaderCountries": "Pays", + "HeaderStatus": "\u00c9tat", + "HeaderTracks": "Pistes", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Verrouill\u00e9", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Note parentale", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/gsw.json b/MediaBrowser.Server.Implementations/Localization/Core/gsw.json index c825b84ab..7334b24ce 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/gsw.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/gsw.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/he.json b/MediaBrowser.Server.Implementations/Localization/Core/he.json index bde605b7e..b3bec3f02 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/he.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/he.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "\u05e9\u05dd", + "HeaderDate": "\u05ea\u05d0\u05e8\u05d9\u05da", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "\u05de\u05e6\u05d1", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/hr.json b/MediaBrowser.Server.Implementations/Localization/Core/hr.json index 9b9797a96..451ff4f36 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/hr.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/hr.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Ime", + "HeaderDate": "Datum", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/it.json b/MediaBrowser.Server.Implementations/Localization/Core/it.json index efc023ad4..90f800634 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/it.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/it.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "Utente", + "HeaderName": "Nome", + "HeaderDate": "Data", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Data Rilascio", + "HeaderRuntime": "Durata", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Stagione", + "HeaderSeasonNumber": "Stagione Numero", + "HeaderSeries": "Series:", + "HeaderNetwork": "Rete", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Voto Comunit\u00e0", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Speciali", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Album", + "HeaderDisc": "Disco", + "HeaderTrack": "Traccia", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Immagine incorporata", + "HeaderResolution": "Risoluzione", + "HeaderSubtitles": "Sottotitoli", + "HeaderGenres": "Generi", + "HeaderCountries": "Paesi", + "HeaderStatus": "Stato", + "HeaderTracks": "Traccia", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Valutazioni genitori", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/kk.json b/MediaBrowser.Server.Implementations/Localization/Core/kk.json index 7a1ef59f3..e33164779 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/kk.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "\u0416\u0430\u043b\u043f\u044b \u0448\u043e\u043b\u0443", + "HeaderShortOverview": "\u049a\u044b\u0441\u049b\u0430\u0448\u0430 \u0448\u043e\u043b\u0443", + "HeaderType": "\u0422\u04af\u0440\u0456", + "HeaderSeverity": "\u0410\u0443\u044b\u0440\u043b\u044b\u0493\u044b", + "HeaderUser": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b", + "HeaderName": "\u0410\u0442\u044b", + "HeaderDate": "\u041a\u04af\u043d\u0456", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "\u0428\u044b\u0493\u0430\u0440\u0443 \u043a\u04af\u043d\u0456", + "HeaderRuntime": "\u04b0\u0437\u0430\u049b\u0442\u044b\u0493\u044b", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "\u041c\u0430\u0443\u0441\u044b\u043c", + "HeaderSeasonNumber": "\u041c\u0430\u0443\u0441\u044b\u043c \u043d\u04e9\u043c\u0456\u0440\u0456", + "HeaderSeries": "Series:", + "HeaderNetwork": "\u0422\u0435\u043b\u0435\u0436\u0435\u043b\u0456", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "\u049a\u0430\u0443\u044b\u043c\u0434\u0430\u0441\u0442\u044b\u049b \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u044b", + "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u043b\u0435\u0440", + "HeaderSpecials": "\u0410\u0440\u043d\u0430\u0439\u044b \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0434\u0430\u0440", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u0434\u0430\u0440", + "HeaderDisc": "\u0414\u0438\u0441\u043a\u0456", + "HeaderTrack": "\u0416\u043e\u043b\u0448\u044b\u049b", + "HeaderAudio": "\u0414\u044b\u0431\u044b\u0441", + "HeaderVideo": "\u0411\u0435\u0439\u043d\u0435", + "HeaderEmbeddedImage": "\u0415\u043d\u0434\u0456\u0440\u0456\u043b\u0433\u0435\u043d \u0441\u0443\u0440\u0435\u0442", + "HeaderResolution": "\u0410\u0436\u044b\u0440\u0430\u0442\u044b\u043c\u0434\u044b\u043b\u044b\u0493\u044b", + "HeaderSubtitles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440", + "HeaderGenres": "\u0416\u0430\u043d\u0440\u043b\u0430\u0440", + "HeaderCountries": "\u0415\u043b\u0434\u0435\u0440", + "HeaderStatus": "\u041a\u04af\u0439", + "HeaderTracks": "\u0416\u043e\u043b\u0448\u044b\u049b\u0442\u0430\u0440", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "\u0421\u0442\u0443\u0434\u0438\u044f\u043b\u0430\u0440", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "\u0416\u0430\u0441\u0442\u0430\u0441 \u0441\u0430\u043d\u0430\u0442\u0442\u0430\u0440", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ko.json b/MediaBrowser.Server.Implementations/Localization/Core/ko.json index fc2ca11b0..8bc5b5672 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ko.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ko.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ms.json b/MediaBrowser.Server.Implementations/Localization/Core/ms.json index 5a2f26c5f..a85f00132 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ms.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ms.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/nb.json b/MediaBrowser.Server.Implementations/Localization/Core/nb.json index 609a45d70..2ab601701 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/nb.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/nb.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "Bruker", + "HeaderName": "Navn", + "HeaderDate": "Dato", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Utgivelsesdato", + "HeaderRuntime": "Spilletid", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Sesong", + "HeaderSeasonNumber": "Sesong nummer", + "HeaderSeries": "Series:", + "HeaderNetwork": "Nettverk", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Fellesskap anmeldelse", + "HeaderTrailers": "Trailere", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albumer", + "HeaderDisc": "Disk", + "HeaderTrack": "Spor", + "HeaderAudio": "Lyd", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "innebygd bilde", + "HeaderResolution": "Oppl\u00f8sning", + "HeaderSubtitles": "Undertekster", + "HeaderGenres": "Sjanger", + "HeaderCountries": "Land", + "HeaderStatus": "Status", + "HeaderTracks": "Spor", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studioer", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Foreldresensur", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/nl.json b/MediaBrowser.Server.Implementations/Localization/Core/nl.json index 5fbda9d88..32d698779 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/nl.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "Gebruiker", + "HeaderName": "Naam", + "HeaderDate": "Datum", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Uitgave datum", + "HeaderRuntime": "Speelduur", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Seizoen", + "HeaderSeasonNumber": "Seizoen nummer", + "HeaderSeries": "Series:", + "HeaderNetwork": "Zender", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Gemeenschap cijfer", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Schijf", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Ingesloten afbeelding", + "HeaderResolution": "Resolutie", + "HeaderSubtitles": "Ondertitels", + "HeaderGenres": "Genres", + "HeaderCountries": "Landen", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studio's", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Ouderlijke toezicht", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/pl.json b/MediaBrowser.Server.Implementations/Localization/Core/pl.json index c08143c90..b7b0e228e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/pl.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/pl.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json b/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json index 32cf9fdfc..58db6d609 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json @@ -120,9 +120,57 @@ "UserStartedPlayingItemWithValues": "{0} come\u00e7ou a reproduzir {1}", "UserStoppedPlayingItemWithValues": "{0} parou de reproduzir {1}", "SubtitleDownloadFailureForItem": "Falha ao baixar legendas para {0}", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", + "HeaderUnidentified": "N\u00e3o-identificado", + "HeaderImagePrimary": "Principal", + "HeaderImageBackdrop": "Imagem de Fundo", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "Imagem do Usu\u00e1rio", + "HeaderOverview": "Sinopse", + "HeaderShortOverview": "Sinopse curta", + "HeaderType": "Tipo", + "HeaderSeverity": "Severidade", + "HeaderUser": "Usu\u00e1rio", + "HeaderName": "Nome", + "HeaderDate": "Data", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Data de lan\u00e7amento", + "HeaderRuntime": "Dura\u00e7\u00e3o", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Temporada", + "HeaderSeasonNumber": "N\u00famero da temporada", + "HeaderSeries": "Series:", + "HeaderNetwork": "Rede de TV", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Avalia\u00e7\u00e3o da Comunidade", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Especiais", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "\u00c1lbuns", + "HeaderDisc": "Disco", + "HeaderTrack": "Faixa", + "HeaderAudio": "\u00c1udio", + "HeaderVideo": "V\u00eddeo", + "HeaderEmbeddedImage": "Imagem incorporada", + "HeaderResolution": "Resolu\u00e7\u00e3o", + "HeaderSubtitles": "Legendas", + "HeaderGenres": "G\u00eaneros", + "HeaderCountries": "Pa\u00edses", + "HeaderStatus": "Status", + "HeaderTracks": "Faixas", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Travado", + "HeaderStudios": "Est\u00fadios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Classifica\u00e7\u00f5es Parentais", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/pt-PT.json b/MediaBrowser.Server.Implementations/Localization/Core/pt-PT.json index 74bfa38e7..5aa832e16 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/pt-PT.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/pt-PT.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Nome", + "HeaderDate": "Data", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "\u00c1udio", + "HeaderVideo": "V\u00eddeo", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Estado", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ro.json b/MediaBrowser.Server.Implementations/Localization/Core/ro.json index d94aeec54..6c945006a 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ro.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ro.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Muzica", + "HeaderVideo": "Filme", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ru.json b/MediaBrowser.Server.Implementations/Localization/Core/ru.json index 88402e3cb..bd9e94ec6 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ru.json @@ -120,9 +120,57 @@ "UserStartedPlayingItemWithValues": "{0} - \u0432\u043e\u0441\u043f\u0440-\u0438\u0435 \u00ab{1}\u00bb \u0437\u0430\u043f-\u043d\u043e", "UserStoppedPlayingItemWithValues": "{0} - \u0432\u043e\u0441\u043f\u0440-\u0438\u0435 \u00ab{1}\u00bb \u043e\u0441\u0442-\u043d\u043e", "SubtitleDownloadFailureForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u043a {0} \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", - "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUnidentified": "\u041d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043e", + "HeaderImagePrimary": "\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439", + "HeaderImageBackdrop": "\u0417\u0430\u0434\u043d\u0438\u043a", + "HeaderImageLogo": "\u041b\u043e\u0433\u043e\u0442\u0438\u043f", + "HeaderUserPrimaryImage": "\u0420\u0438\u0441\u0443\u043d\u043e\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", + "HeaderOverview": "\u041e\u0431\u0437\u043e\u0440", + "HeaderShortOverview": "\u041a\u0440\u0430\u0442\u043a\u0438\u0439 \u043e\u0431\u0437\u043e\u0440", + "HeaderType": "\u0422\u0438\u043f", + "HeaderSeverity": "\u0421\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u044c", + "HeaderUser": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c", + "HeaderName": "\u0418\u043c\u044f (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435)", + "HeaderDate": "\u0414\u0430\u0442\u0430", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "\u0414\u0430\u0442\u0430 \u0432\u044b\u043f.", + "HeaderRuntime": "\u0414\u043b\u0438\u0442.", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "\u0421\u0435\u0437\u043e\u043d", + "HeaderSeasonNumber": "\u041d\u043e\u043c\u0435\u0440 \u0441\u0435\u0437\u043e\u043d\u0430", + "HeaderSeries": "Series:", + "HeaderNetwork": "\u0422\u0435\u043b\u0435\u0441\u0435\u0442\u044c", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "\u041e\u0431\u0449. \u043e\u0446\u0435\u043d\u043a\u0430", + "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b.", + "HeaderSpecials": "\u0421\u043f\u0435\u0446.", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u044b", + "HeaderDisc": "\u0414\u0438\u0441\u043a", + "HeaderTrack": "\u0414\u043e\u0440-\u043a\u0430", + "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e", + "HeaderVideo": "\u0412\u0438\u0434\u0435\u043e", + "HeaderEmbeddedImage": "\u0412\u043d\u0435\u0434\u0440\u0451\u043d\u043d\u044b\u0439 \u0440\u0438\u0441\u0443\u043d\u043e\u043a", + "HeaderResolution": "\u0420\u0430\u0437\u0440.", + "HeaderSubtitles": "\u0421\u0443\u0431\u0442.", + "HeaderGenres": "\u0416\u0430\u043d\u0440\u044b", + "HeaderCountries": "\u0421\u0442\u0440\u0430\u043d\u044b", + "HeaderStatus": "\u0421\u043e\u0441\u0442-\u0438\u0435", + "HeaderTracks": "\u0414\u043e\u0440-\u043a\u0438", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e", + "HeaderStudios": "\u0421\u0442\u0443\u0434\u0438\u0438", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "\u0412\u043e\u0437\u0440\u0430\u0441\u0442\u043d\u0430\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/sl-SI.json b/MediaBrowser.Server.Implementations/Localization/Core/sl-SI.json index d5d831cef..abe203804 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/sl-SI.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/sl-SI.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/sv.json b/MediaBrowser.Server.Implementations/Localization/Core/sv.json index ba7d928a8..3a5a322c6 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/sv.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/sv.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "Anv\u00e4ndare", + "HeaderName": "Namn", + "HeaderDate": "Datum", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Premi\u00e4rdatum:", + "HeaderRuntime": "Speltid", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "S\u00e4song", + "HeaderSeasonNumber": "S\u00e4songsnummer:", + "HeaderSeries": "Series:", + "HeaderNetwork": "TV-bolag", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Anv\u00e4ndaromd\u00f6me", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specialer", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Album", + "HeaderDisc": "Skiva", + "HeaderTrack": "Sp\u00e5r", + "HeaderAudio": "Ljud", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Infogad bild", + "HeaderResolution": "Uppl\u00f6sning", + "HeaderSubtitles": "Undertexter", + "HeaderGenres": "Genrer", + "HeaderCountries": "L\u00e4nder", + "HeaderStatus": "Status", + "HeaderTracks": "Sp\u00e5r", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studior", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/tr.json b/MediaBrowser.Server.Implementations/Localization/Core/tr.json index 3dd559ba4..f127cc816 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/tr.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/tr.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Durum", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/uk.json b/MediaBrowser.Server.Implementations/Localization/Core/uk.json index 39b41127b..ec9ca5a39 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/uk.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/uk.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "\u0421\u0435\u0437\u043e\u043d", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u0438", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u0438", + "HeaderDisc": "\u0414\u0438\u0441\u043a", + "HeaderTrack": "\u0414\u043e\u0440\u0456\u0436\u043a\u0430", + "HeaderAudio": "\u0410\u0443\u0434\u0456\u043e", + "HeaderVideo": "\u0412\u0456\u0434\u0435\u043e", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Status", + "HeaderTracks": "\u0414\u043e\u0440\u0456\u0436\u043a\u0438", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "\u0421\u0442\u0443\u0434\u0456\u0457", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/vi.json b/MediaBrowser.Server.Implementations/Localization/Core/vi.json index 85dfd2bc7..6e0c3ea20 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/vi.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/vi.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "T\u00ean", + "HeaderDate": "Ng\u00e0y", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "Tr\u1ea1ng th\u00e1i", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/zh-CN.json b/MediaBrowser.Server.Implementations/Localization/Core/zh-CN.json index 65171ccc3..54cd7e59b 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/zh-CN.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/zh-CN.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "\u7528\u6237", + "HeaderName": "\u540d\u5b57", + "HeaderDate": "\u65e5\u671f", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "\u53d1\u884c\u65e5\u671f", + "HeaderRuntime": "\u64ad\u653e\u65f6\u95f4", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "\u5b63", + "HeaderSeasonNumber": "\u591a\u5c11\u5b63", + "HeaderSeries": "Series:", + "HeaderNetwork": "\u7f51\u7edc", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "\u516c\u4f17\u8bc4\u5206", + "HeaderTrailers": "\u9884\u544a\u7247", + "HeaderSpecials": "\u7279\u96c6", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "\u4e13\u8f91", + "HeaderDisc": "\u5149\u76d8", + "HeaderTrack": "\u97f3\u8f68", + "HeaderAudio": "\u97f3\u9891", + "HeaderVideo": "\u89c6\u9891", + "HeaderEmbeddedImage": "\u5d4c\u5165\u5f0f\u56fe\u50cf", + "HeaderResolution": "\u5206\u8fa8\u7387", + "HeaderSubtitles": "\u5b57\u5e55", + "HeaderGenres": "\u98ce\u683c", + "HeaderCountries": "\u56fd\u5bb6", + "HeaderStatus": "\u72b6\u6001", + "HeaderTracks": "\u97f3\u8f68", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "\u5de5\u4f5c\u5ba4", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "\u5bb6\u957f\u5206\u7ea7", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json b/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json index a96b1cacc..787508176 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json @@ -124,5 +124,53 @@ "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image" + "HeaderUserPrimaryImage": "User Image", + "HeaderOverview": "Overview", + "HeaderShortOverview": "Short Overview", + "HeaderType": "Type", + "HeaderSeverity": "Severity", + "HeaderUser": "User", + "HeaderName": "Name", + "HeaderDate": "Date", + "HeaderPremiereDate": "Premiere Date", + "HeaderDateAdded": "Date Added", + "HeaderReleaseDate": "Release date", + "HeaderRuntime": "Runtime", + "HeaderPlayCount": "Play Count", + "HeaderSeason": "Season", + "HeaderSeasonNumber": "Season number", + "HeaderSeries": "Series:", + "HeaderNetwork": "Network", + "HeaderYear": "Year:", + "HeaderYears": "Years:", + "HeaderParentalRating": "Parental Rating", + "HeaderCommunityRating": "Community rating", + "HeaderTrailers": "Trailers", + "HeaderSpecials": "Specials", + "HeaderGameSystems": "Game Systems", + "HeaderPlayers": "Players:", + "HeaderAlbumArtists": "Album Artists", + "HeaderAlbums": "Albums", + "HeaderDisc": "Disc", + "HeaderTrack": "Track", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "HeaderEmbeddedImage": "Embedded image", + "HeaderResolution": "Resolution", + "HeaderSubtitles": "Subtitles", + "HeaderGenres": "Genres", + "HeaderCountries": "Countries", + "HeaderStatus": "\u72c0\u614b", + "HeaderTracks": "Tracks", + "HeaderMusicArtist": "Music artist", + "HeaderLocked": "Locked", + "HeaderStudios": "Studios", + "HeaderActor": "Actors", + "HeaderComposer": "Composers", + "HeaderDirector": "Directors", + "HeaderGuestStar": "Guest star", + "HeaderProducer": "Producers", + "HeaderWriter": "Writers", + "HeaderParentalRatings": "Parental Ratings", + "HeaderCommunityRatings": "Community ratings" } \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 3e67540d8..5932dc635 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1751,22 +1751,19 @@ PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - - PreserveNewest - - + PreserveNewest -- cgit v1.2.3 From 7a74213914fd5ca166f148ec47d65c7041082847 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jul 2015 15:54:45 -0400 Subject: update subtitle conversion --- MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 765acd578..87e71e327 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -72,6 +72,12 @@ namespace MediaBrowser.Server.Implementations.Library private bool InternalTextStreamSupportsExternalStream(MediaStream stream) { + // These usually have styles and fonts that won't convert to text very well + if (string.Equals(stream.Codec, "ass", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + return true; } @@ -463,7 +469,7 @@ namespace MediaBrowser.Server.Implementations.Library _liveStreamSemaphore.Release(); } } - + // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message. private const char LiveStreamIdDelimeter = '_'; -- cgit v1.2.3 From 4d7f98361894e9de90ab964c3496fb7f613c28e2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jul 2015 23:42:03 -0400 Subject: update recording scheduler --- MediaBrowser.Controller/LiveTv/RecordingInfo.cs | 6 ++++ .../Channels/ChannelPostScanTask.cs | 2 +- .../Channels/RefreshChannelsScheduledTask.cs | 24 ++++++++----- .../IO/LibraryMonitor.cs | 12 +++---- .../LiveTv/EmbyTV/EmbyTV.cs | 40 +++++++++++++++++----- .../LiveTv/EmbyTV/EntryPoint.cs | 16 +++++++++ .../LiveTv/EmbyTV/RecordingHelper.cs | 9 ++--- .../LiveTv/EmbyTV/TimerManager.cs | 16 ++++++++- .../MediaBrowser.Server.Implementations.csproj | 1 + .../ScheduledTasks/RefreshMediaLibraryTask.cs | 2 +- .../MediaBrowser.WebDashboard.csproj | 6 ---- 11 files changed, 94 insertions(+), 40 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index bf453ccf4..e5817d390 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -16,6 +16,12 @@ namespace MediaBrowser.Controller.LiveTv /// /// The series timer identifier. public string SeriesTimerId { get; set; } + + /// + /// Gets or sets the timer identifier. + /// + /// The timer identifier. + public string TimerId { get; set; } /// /// ChannelId of the recording. diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs index d266cca6c..baf446942 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs @@ -12,7 +12,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Channels { - public class ChannelPostScanTask : ILibraryPostScanTask + public class ChannelPostScanTask { private readonly IChannelManager _channelManager; private readonly IUserManager _userManager; diff --git a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index b1491d594..df94580a5 100644 --- a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Channels; -using MediaBrowser.Model.Tasks; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -9,11 +10,15 @@ namespace MediaBrowser.Server.Implementations.Channels { class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask { - private readonly IChannelManager _manager; + private readonly IChannelManager _channelManager; + private readonly IUserManager _userManager; + private readonly ILogger _logger; - public RefreshChannelsScheduledTask(IChannelManager manager) + public RefreshChannelsScheduledTask(IChannelManager channelManager, IUserManager userManager, ILogger logger) { - _manager = manager; + _channelManager = channelManager; + _userManager = userManager; + _logger = logger; } public string Name @@ -31,11 +36,14 @@ namespace MediaBrowser.Server.Implementations.Channels get { return "Channels"; } } - public Task Execute(System.Threading.CancellationToken cancellationToken, IProgress progress) + public async Task Execute(System.Threading.CancellationToken cancellationToken, IProgress progress) { - var manager = (ChannelManager)_manager; + var manager = (ChannelManager)_channelManager; - return manager.RefreshChannels(progress, cancellationToken); + await manager.RefreshChannels(new Progress(), cancellationToken).ConfigureAwait(false); + + await new ChannelPostScanTask(_channelManager, _userManager, _logger).Run(progress, cancellationToken) + .ConfigureAwait(false); } public IEnumerable GetDefaultTriggers() @@ -48,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Channels public bool IsHidden { - get { return true; } + get { return false; } } public bool IsEnabled diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 26ccdfc9a..e1c529187 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -1,5 +1,4 @@ -using System.ComponentModel; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -372,15 +371,12 @@ namespace MediaBrowser.Server.Implementations.IO DisposeWatcher(dw); - if (ex is Win32Exception) + if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto) { Logger.Info("Disabling realtime monitor to prevent future instability"); - if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto) - { - ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled; - Stop(); - } + ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled; + Stop(); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 0ed87bbff..3374a3cc9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -33,8 +33,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly LiveTvManager _liveTvManager; + public static EmbyTV Current; + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager) { + Current = this; + _appHpst = appHost; _logger = logger; _httpClient = httpClient; @@ -48,6 +52,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _timerProvider.TimerFired += _timerProvider_TimerFired; } + public void Start() + { + _timerProvider.RestartTimers(); + } + public event EventHandler DataSourceChanged; public event EventHandler RecordingStatusChanged; @@ -147,7 +156,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) { - var remove = _seriesTimerProvider.GetAll().SingleOrDefault(r => r.Id == timerId); + var remove = _seriesTimerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase)); if (remove != null) { _seriesTimerProvider.Delete(remove); @@ -157,7 +166,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void CancelTimerInternal(string timerId) { - var remove = _timerProvider.GetAll().SingleOrDefault(r => r.Id == timerId); + var remove = _timerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase)); if (remove != null) { _timerProvider.Delete(remove); @@ -176,11 +185,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return Task.FromResult(true); } - public Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken) + public async Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken) { var remove = _recordingProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, recordingId, StringComparison.OrdinalIgnoreCase)); if (remove != null) { + if (!string.IsNullOrWhiteSpace(remove.TimerId)) + { + var enableDelay = _activeRecordings.ContainsKey(remove.TimerId); + + CancelTimerInternal(remove.TimerId); + + if (enableDelay) + { + // A hack yes, but need to make sure the file is closed before attempting to delete it + await Task.Delay(3000).ConfigureAwait(false); + } + } + try { File.Delete(remove.Path); @@ -195,7 +217,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } _recordingProvider.Delete(remove); } - return Task.FromResult(true); } public Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken) @@ -293,6 +314,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (list.Count > 0) { + SaveEpgDataForChannel(channelId, list); + return list; } } @@ -430,7 +453,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } var mediaStreamInfo = await GetChannelStream(timer.ChannelId, null, CancellationToken.None); - var duration = (timer.EndDate - RecordingHelper.GetStartTime(timer)).TotalSeconds + timer.PrePaddingSeconds; + var duration = (timer.EndDate - DateTime.UtcNow).TotalSeconds + timer.PostPaddingSeconds; HttpRequestOptions httpRequestOptions = new HttpRequestOptions() { @@ -451,14 +474,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recordPath = Path.Combine(recordPath, RecordingHelper.GetRecordingName(timer, info)); Directory.CreateDirectory(Path.GetDirectoryName(recordPath)); - var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.Id, info.Id, StringComparison.OrdinalIgnoreCase)); + var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase)); if (recording == null) { recording = new RecordingInfo() { ChannelId = info.ChannelId, - Id = info.Id, + Id = Guid.NewGuid().ToString("N"), StartDate = info.StartDate, EndDate = info.EndDate, Genres = info.Genres ?? null, @@ -480,7 +503,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV OriginalAirDate = info.OriginalAirDate, Status = RecordingStatus.Scheduled, Overview = info.Overview, - SeriesTimerId = info.Id.Substring(0, 10) + SeriesTimerId = info.Id.Substring(0, 10), + TimerId = timer.Id }; _recordingProvider.Add(recording); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs new file mode 100644 index 000000000..713cb9cd3 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs @@ -0,0 +1,16 @@ +using MediaBrowser.Controller.Plugins; + +namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV +{ + public class EntryPoint : IServerEntryPoint + { + public void Run() + { + EmbyTV.Current.Start(); + } + + public void Dispose() + { + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 0aa1cb244..db89680d2 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -1,11 +1,10 @@ -using System.Text; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Linq; +using System.Text; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { @@ -49,10 +48,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public static DateTime GetStartTime(TimerInfo timer) { - if (timer.StartDate.AddSeconds(-timer.PrePaddingSeconds + 1) < DateTime.UtcNow) - { - return DateTime.UtcNow.AddSeconds(1); - } return timer.StartDate.AddSeconds(-timer.PrePaddingSeconds); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 323197aa5..0c8d2ca2b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -24,6 +24,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public void RestartTimers() { StopTimers(); + + foreach (var item in GetAll().ToList()) + { + AddTimer(item); + } } public void StopTimers() @@ -90,7 +95,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void AddTimer(TimerInfo item) { - var timespan = RecordingHelper.GetStartTime(item) - DateTime.UtcNow; + var startDate = RecordingHelper.GetStartTime(item); + var now = DateTime.UtcNow; + + if (startDate < now) + { + EventHelper.FireEventIfNotNull(TimerFired, this, new GenericEventArgs { Argument = item }, Logger); + return; + } + + var timespan = startDate - now; var timer = new Timer(TimerCallback, item.Id, timespan, TimeSpan.Zero); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 5e0f374e0..7eddf5ed1 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -217,6 +217,7 @@ + diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index 824d859f3..ed284a90d 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks new StartupTrigger(), - new IntervalTrigger{ Interval = TimeSpan.FromHours(6)} + new IntervalTrigger{ Interval = TimeSpan.FromHours(8)} }; } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 16dd97387..a4da8c2b7 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -742,9 +742,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1006,9 +1003,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 1f6b5a8c7c049bea309351dd495d99ec21eb32cb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 29 Jul 2015 13:16:00 -0400 Subject: update live tv recordings --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 26 ++++++++++++- .../LiveTv/EmbyTV/EmbyTV.cs | 36 +++++++++++++++++- .../LiveTv/EmbyTV/RecordingHelper.cs | 39 ------------------- .../LiveTv/Listings/SchedulesDirect.cs | 44 ++++++++++++++-------- .../Sync/SyncHelper.cs | 4 +- .../MediaBrowser.WebDashboard.csproj | 6 --- 6 files changed, 89 insertions(+), 66 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index b0359194c..6814ad751 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -376,17 +377,40 @@ namespace MediaBrowser.Api.LiveTv public string Country { get; set; } } + [Route("/LiveTv/ListingProviders/SchedulesDirect/Countries", "GET", Summary = "Gets available lineups")] + [Authenticated] + public class GetSchedulesDirectCountries + { + } + public class LiveTvService : BaseApiService { private readonly ILiveTvManager _liveTvManager; private readonly IUserManager _userManager; private readonly IConfigurationManager _config; + private readonly IHttpClient _httpClient; - public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IConfigurationManager config) + public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IConfigurationManager config, IHttpClient httpClient) { _liveTvManager = liveTvManager; _userManager = userManager; _config = config; + _httpClient = httpClient; + } + + public async Task Get(GetSchedulesDirectCountries request) + { + // https://json.schedulesdirect.org/20141201/available/countries + + var response = await _httpClient.Get(new HttpRequestOptions + { + Url = "https://json.schedulesdirect.org/20141201/available/countries", + CacheLength = TimeSpan.FromDays(1), + CacheMode = CacheMode.Unconditional + + }).ConfigureAwait(false); + + return ResultFactory.GetResult(response, "application/json"); } private void AssertUserCanManageLiveTv() diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 3374a3cc9..2319a6c2c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -228,7 +228,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) { - info.Id = info.ProgramId.Substring(0, 10); + info.Id = Guid.NewGuid().ToString("N"); UpdateTimersForSeriesTimer(info); _seriesTimerProvider.Add(info); @@ -581,7 +581,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV epgData = GetEpgDataForChannel(seriesTimer.ChannelId); } - var newTimers = RecordingHelper.GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll(), _logger); + var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); var existingTimers = _timerProvider.GetAll() .Where(i => string.Equals(i.SeriesTimerId, seriesTimer.Id, StringComparison.OrdinalIgnoreCase)) @@ -603,6 +603,38 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } + private IEnumerable GetTimersForSeries(SeriesTimerInfo seriesTimer, IEnumerable allPrograms, IReadOnlyList currentRecordings) + { + allPrograms = GetProgramsForSeries(seriesTimer, allPrograms); + + allPrograms = allPrograms.Where(epg => currentRecordings.All(r => r.ProgramId.Substring(0, 14) != epg.Id.Substring(0, 14))); //filtered recordings already running + + return allPrograms.Select(i => RecordingHelper.CreateTimer(i, seriesTimer)); + } + + private IEnumerable GetProgramsForSeries(SeriesTimerInfo seriesTimer, IEnumerable allPrograms) + { + if (!seriesTimer.RecordAnyTime) + { + allPrograms = allPrograms.Where(epg => (seriesTimer.StartDate.TimeOfDay == epg.StartDate.TimeOfDay)); + } + + if (seriesTimer.RecordNewOnly) + { + allPrograms = allPrograms.Where(epg => !epg.IsRepeat); //Filtered by New only + } + + if (!seriesTimer.RecordAnyChannel) + { + allPrograms = allPrograms.Where(epg => string.Equals(epg.ChannelId, seriesTimer.ChannelId, StringComparison.OrdinalIgnoreCase)); + } + + allPrograms = allPrograms.Where(epg => seriesTimer.Days.Contains(epg.StartDate.DayOfWeek)); + + // TODO: This assumption will require review once additional listing providers are added + return allPrograms.Where(epg => epg.Id.StartsWith(seriesTimer.ProgramId, StringComparison.OrdinalIgnoreCase)); + } + private string GetChannelEpgCachePath(string channelId) { return Path.Combine(DataPath, "epg", channelId + ".json"); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index db89680d2..31fb072cd 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -1,51 +1,12 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Logging; using System; -using System.Collections.Generic; -using System.Linq; using System.Text; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { internal class RecordingHelper { - public static List GetTimersForSeries(SeriesTimerInfo seriesTimer, IEnumerable epgData, IReadOnlyList currentRecordings, ILogger logger) - { - List timers = new List(); - - // Filtered Per Show - var filteredEpg = epgData.Where(epg => epg.Id.Substring(0, 10) == seriesTimer.Id); - - if (!seriesTimer.RecordAnyTime) - { - filteredEpg = filteredEpg.Where(epg => (seriesTimer.StartDate.TimeOfDay == epg.StartDate.TimeOfDay)); - } - - if (seriesTimer.RecordNewOnly) - { - filteredEpg = filteredEpg.Where(epg => !epg.IsRepeat); //Filtered by New only - } - - if (!seriesTimer.RecordAnyChannel) - { - filteredEpg = filteredEpg.Where(epg => string.Equals(epg.ChannelId, seriesTimer.ChannelId, StringComparison.OrdinalIgnoreCase)); - } - - filteredEpg = filteredEpg.Where(epg => seriesTimer.Days.Contains(epg.StartDate.DayOfWeek)); - - filteredEpg = filteredEpg.Where(epg => currentRecordings.All(r => r.Id.Substring(0, 14) != epg.Id.Substring(0, 14))); //filtered recordings already running - - filteredEpg = filteredEpg.GroupBy(epg => epg.Id.Substring(0, 14)).Select(g => g.First()).ToList(); - - foreach (var epg in filteredEpg) - { - timers.Add(CreateTimer(epg, seriesTimer)); - } - - return timers; - } - public static DateTime GetStartTime(TimerInfo timer) { return timer.StartDate.AddSeconds(-timer.PrePaddingSeconds); diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 64599bc58..ffafe5979 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -35,6 +35,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings _httpClient = httpClient; } + private List GetScheduleRequestDates(DateTime startDateUtc, DateTime endDateUtc) + { + List dates = new List(); + + var start = new List { startDateUtc, startDateUtc.ToLocalTime() }.Min(); + var end = new List { endDateUtc, endDateUtc.ToLocalTime() }.Max(); + + while (start.DayOfYear <= end.Day) + { + dates.Add(start.ToString("yyyy-MM-dd")); + start = start.AddDays(1); + } + + return dates; + } + public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { List programsInfo = new List(); @@ -60,15 +76,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings httpOptions.RequestHeaders["token"] = token; - List dates = new List(); - int numberOfDay = 0; - DateTime lastEntry = startDateUtc; - while (lastEntry != endDateUtc) - { - lastEntry = startDateUtc.AddDays(numberOfDay); - dates.Add(lastEntry.ToString("yyyy-MM-dd")); - numberOfDay++; - } + var dates = GetScheduleRequestDates(startDateUtc, endDateUtc); ScheduleDirect.Station station = null; @@ -97,8 +105,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings StreamReader reader = new StreamReader(response.Content); string responseString = reader.ReadToEnd(); var dailySchedules = _jsonSerializer.DeserializeFromString>(responseString); - _logger.Debug("Found " + dailySchedules.Count() + " programs on " + channelNumber + - " ScheduleDirect"); + _logger.Debug("Found " + dailySchedules.Count() + " programs on " + channelNumber + " ScheduleDirect"); httpOptions = new HttpRequestOptions() { @@ -234,10 +241,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings bool repeat = (programInfo.@new == null); string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channel; - if (programInfo.audioProperties != null) { - if (programInfo.audioProperties.Exists(item => item == "stereo")) + if (programInfo.audioProperties.Exists(item => string.Equals(item, "dd 5.1", StringComparison.OrdinalIgnoreCase))) + { + audioType = ProgramAudio.DolbyDigital; + } + else if (programInfo.audioProperties.Exists(item => string.Equals(item, "dd", StringComparison.OrdinalIgnoreCase))) + { + audioType = ProgramAudio.DolbyDigital; + } + else if (programInfo.audioProperties.Exists(item => string.Equals(item, "stereo", StringComparison.OrdinalIgnoreCase))) { audioType = ProgramAudio.Stereo; } @@ -286,7 +300,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings imageLink = details.images; } - var info = new ProgramInfo { ChannelId = channel, @@ -554,7 +567,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings }; httpOptions.RequestHeaders["token"] = token; - + using (var response = await _httpClient.SendAsync(httpOptions, "PUT")) { } @@ -915,6 +928,5 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } - } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs index 006284ee1..b6242950f 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs @@ -10,11 +10,11 @@ namespace MediaBrowser.Server.Implementations.Sync { if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase)) { - profileBitrate = Convert.ToInt32(profileBitrate.Value * .75); + profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .7), 4000000); } else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase)) { - profileBitrate = Convert.ToInt32(profileBitrate.Value*.5); + profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .5), 1500000); } } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index a4da8c2b7..f76651260 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -742,9 +742,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1003,9 +1000,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 8f75454d76c9c21018476fd278f91ae69f9268c0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 29 Jul 2015 16:31:15 -0400 Subject: update image processing --- Emby.Drawing/ImageMagick/StripCollageBuilder.cs | 4 ++-- MediaBrowser.Api/UserLibrary/ItemsService.cs | 1 - MediaBrowser.Api/UserLibrary/UserViewsService.cs | 2 +- MediaBrowser.Controller/Entities/ICollectionFolder.cs | 14 ++++++++++++++ MediaBrowser.Controller/Entities/UserViewBuilder.cs | 5 +---- .../Channels/ChannelManager.cs | 2 +- .../Collections/ManualCollectionsFolder.cs | 1 - MediaBrowser.Server.Implementations/Dto/DtoService.cs | 14 ++++++++------ .../Library/LibraryManager.cs | 2 +- .../Library/UserViewManager.cs | 19 +++++++++---------- .../LiveTv/EmbyTV/EmbyTV.cs | 15 +++++++++------ .../LiveTv/Listings/SchedulesDirect.cs | 13 ++++++++++--- .../Photos/BaseDynamicImageProvider.cs | 6 +++--- .../Playlists/ManualPlaylistsFolder.cs | 4 +--- 14 files changed, 60 insertions(+), 42 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs b/Emby.Drawing/ImageMagick/StripCollageBuilder.cs index a50a75ccd..7ed0f36e2 100644 --- a/Emby.Drawing/ImageMagick/StripCollageBuilder.cs +++ b/Emby.Drawing/ImageMagick/StripCollageBuilder.cs @@ -285,14 +285,14 @@ namespace Emby.Drawing.ImageMagick private MagickWand BuildThumbCollageWand(List paths, int width, int height) { - var inputPaths = ImageHelpers.ProjectPaths(paths, 8); + var inputPaths = ImageHelpers.ProjectPaths(paths, 4); using (var wandImages = new MagickWand(inputPaths.ToArray())) { var wand = new MagickWand(width, height); wand.OpenImage("gradient:#111111-#111111"); using (var draw = new DrawingWand()) { - var iSlice = Convert.ToInt32(width * .1166666667); + var iSlice = Convert.ToInt32(width * .1166666667 * 2); int iTrans = Convert.ToInt32(height * .25); int iHeight = Convert.ToInt32(height * .62); var horizontalImagePadding = Convert.ToInt32(width * 0.0125); diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 881cec7ba..b412a6480 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; diff --git a/MediaBrowser.Api/UserLibrary/UserViewsService.cs b/MediaBrowser.Api/UserLibrary/UserViewsService.cs index 43d8dbc16..a49ab8556 100644 --- a/MediaBrowser.Api/UserLibrary/UserViewsService.cs +++ b/MediaBrowser.Api/UserLibrary/UserViewsService.cs @@ -89,7 +89,7 @@ namespace MediaBrowser.Api.UserLibrary var views = user.RootFolder .GetChildren(user, true) .OfType() - .Where(i => IsEligibleForSpecialView(i)) + .Where(IsEligibleForSpecialView) .ToList(); var list = views diff --git a/MediaBrowser.Controller/Entities/ICollectionFolder.cs b/MediaBrowser.Controller/Entities/ICollectionFolder.cs index f46d7ed6f..b55ca0a17 100644 --- a/MediaBrowser.Controller/Entities/ICollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/ICollectionFolder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -14,4 +15,17 @@ namespace MediaBrowser.Controller.Entities Guid Id { get; } IEnumerable PhysicalLocations { get; } } + + public static class CollectionFolderExtensions + { + public static string GetViewType(this ICollectionFolder folder, User user) + { + if (user.Configuration.PlainFolderViews.Contains(folder.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return null; + } + + return folder.CollectionType; + } + } } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 0733b65b1..462f66e20 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -264,10 +264,7 @@ namespace MediaBrowser.Controller.Entities private async Task> FindPlaylists(Folder parent, User user, InternalItemsQuery query) { - var collectionFolders = user.RootFolder.GetChildren(user, true).Select(i => i.Id).ToList(); - - var list = _playlistManager.GetPlaylists(user.Id.ToString("N")) - .Where(i => i.GetChildren(user, true).Any(media => _libraryManager.GetCollectionFolders(media).Select(c => c.Id).Any(collectionFolders.Contains))); + var list = _playlistManager.GetPlaylists(user.Id.ToString("N")); return GetResult(list, parent, query); } diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index 3e58e3bd5..179eb5629 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -476,7 +476,7 @@ namespace MediaBrowser.Server.Implementations.Channels public Channel GetChannel(string id) { - return (Channel)_libraryManager.GetItemById(new Guid(id)); + return _libraryManager.GetItemById(new Guid(id)) as Channel; } public IEnumerable GetAllChannelFeatures() diff --git a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs index 8f5d8fe9b..d62918d56 100644 --- a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs +++ b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; using System.Linq; namespace MediaBrowser.Server.Implementations.Collections diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index aade00aa4..31f1b17dd 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -351,6 +351,14 @@ namespace MediaBrowser.Server.Implementations.Dto AttachBasicFields(dto, item, owner, options); + var collectionFolder = item as ICollectionFolder; + if (collectionFolder != null) + { + dto.CollectionType = user == null ? + collectionFolder.CollectionType : + collectionFolder.GetViewType(user); + } + var playlist = item as Playlist; if (playlist != null) { @@ -1066,12 +1074,6 @@ namespace MediaBrowser.Server.Implementations.Dto dto.DisplayOrder = hasDisplayOrder.DisplayOrder; } - var collectionFolder = item as ICollectionFolder; - if (collectionFolder != null) - { - dto.CollectionType = collectionFolder.CollectionType; - } - var userView = item as UserView; if (userView != null) { diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 497a198fd..40d93e8ef 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1615,7 +1615,7 @@ namespace MediaBrowser.Server.Implementations.Library .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); } - private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(.01); + private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); public async Task GetNamedView(User user, string name, diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 14c5c9a03..61b28a072 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.Library list.AddRange(standaloneFolders); } - var parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType)) + var parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user))) .ToList(); if (parents.Count > 0) @@ -99,7 +99,7 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(parents, list, CollectionType.TvShows, string.Empty, user, cancellationToken).ConfigureAwait(false)); } - parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType)) + parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Music, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user))) .ToList(); if (parents.Count > 0) @@ -107,7 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(parents, list, CollectionType.Music, string.Empty, user, cancellationToken).ConfigureAwait(false)); } - parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType)) + parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Movies, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.GetViewType(user))) .ToList(); if (parents.Count > 0) @@ -115,7 +115,7 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(parents, list, CollectionType.Movies, string.Empty, user, cancellationToken).ConfigureAwait(false)); } - parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase)) + parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Games, StringComparison.OrdinalIgnoreCase)) .ToList(); if (parents.Count > 0) @@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(parents, list, CollectionType.Games, string.Empty, user, cancellationToken).ConfigureAwait(false)); } - parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)) + parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)) .ToList(); if (parents.Count > 0) @@ -131,7 +131,7 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(parents, list, CollectionType.BoxSets, string.Empty, user, cancellationToken).ConfigureAwait(false)); } - parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)) + parents = foldersWithViewTypes.Where(i => string.Equals(i.GetViewType(user), CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)) .ToList(); if (parents.Count > 0) @@ -204,8 +204,9 @@ namespace MediaBrowser.Server.Implementations.Library public async Task GetUserView(List parents, List currentViews, string viewType, string sortName, User user, CancellationToken cancellationToken) { var name = _localizationManager.GetLocalizedString("ViewType" + viewType); + var enableUserSpecificViews = _config.Configuration.EnableUserSpecificUserViews; - if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase))) + if (parents.Count == 1 && parents.All(i => string.Equals((enableUserSpecificViews ? i.CollectionType : i.GetViewType(user)), viewType, StringComparison.OrdinalIgnoreCase))) { if (!string.IsNullOrWhiteSpace(parents[0].Name)) { @@ -221,7 +222,7 @@ namespace MediaBrowser.Server.Implementations.Library return await GetUserView(parentId, name, viewType, enableRichView, sortName, user, cancellationToken).ConfigureAwait(false); } - if (_config.Configuration.EnableUserSpecificUserViews) + if (enableUserSpecificViews) { viewType = enableRichView ? viewType : null; var view = await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); @@ -233,8 +234,6 @@ namespace MediaBrowser.Server.Implementations.Library } return view; } - - return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); } return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2319a6c2c..c323f8e0d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common; +using System.Globalization; +using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; @@ -453,11 +454,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } var mediaStreamInfo = await GetChannelStream(timer.ChannelId, null, CancellationToken.None); - var duration = (timer.EndDate - DateTime.UtcNow).TotalSeconds + timer.PostPaddingSeconds; + var duration = (timer.EndDate - DateTime.UtcNow).Add(TimeSpan.FromSeconds(timer.PostPaddingSeconds)); HttpRequestOptions httpRequestOptions = new HttpRequestOptions() { - Url = mediaStreamInfo.Path + "?duration=" + duration + Url = mediaStreamInfo.Path + "?duration=" + duration.TotalSeconds.ToString(CultureInfo.InvariantCulture) }; var info = GetProgramInfoFromCache(timer.ChannelId, timer.ProgramId); @@ -516,13 +517,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV try { httpRequestOptions.BufferContent = false; - httpRequestOptions.CancellationToken = cancellationToken; + var durationToken = new CancellationTokenSource(duration); + var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; + httpRequestOptions.CancellationToken = linkedToken; _logger.Info("Writing file to path: " + recordPath); using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET")) { using (var output = File.Open(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { - await response.Content.CopyToAsync(output, 4096, cancellationToken); + await response.Content.CopyToAsync(output, 4096, linkedToken); } } @@ -530,7 +533,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } catch (OperationCanceledException) { - recording.Status = RecordingStatus.Cancelled; + recording.Status = RecordingStatus.Completed; } catch { diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index ffafe5979..655feedae 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using MediaBrowser.Common; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; @@ -20,19 +21,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings private readonly ILogger _logger; private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; - private const string UserAgent = "EmbyTV"; private readonly SemaphoreSlim _tokenSemaphore = new SemaphoreSlim(1, 1); + private readonly IApplicationHost _appHost; private const string ApiUrl = "https://json.schedulesdirect.org/20141201"; private readonly ConcurrentDictionary _channelPair = new ConcurrentDictionary(); - public SchedulesDirect(ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient) + public SchedulesDirect(ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IApplicationHost appHost) { _logger = logger; _jsonSerializer = jsonSerializer; _httpClient = httpClient; + _appHost = appHost; + } + + private string UserAgent + { + get { return "Emby/" + _appHost.ApplicationVersion; } } private List GetScheduleRequestDates(DateTime startDateUtc, DateTime endDateUtc) diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index eb25c7d79..642753fa6 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -118,7 +118,7 @@ namespace MediaBrowser.Server.Implementations.Photos protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) { - return CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 640, 360, drawText, primaryItem.Name); } protected virtual IEnumerable GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable items) @@ -130,12 +130,12 @@ namespace MediaBrowser.Server.Implementations.Photos protected Task CreatePosterCollage(IHasImages primaryItem, List items, string outputPath) { - return CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 400, 600, true, primaryItem.Name); } protected Task CreateSquareCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) { - return CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 600, 600, drawText, primaryItem.Name); } protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 2f3a1dd0c..3ec41b6dc 100644 --- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -16,9 +16,7 @@ namespace MediaBrowser.Server.Implementations.Playlists public override bool IsVisible(User user) { - return base.IsVisible(user) && GetChildren(user, false) - .OfType() - .Any(i => i.IsVisible(user)); + return base.IsVisible(user) && GetChildren(user, false).Any(); } protected override IEnumerable GetEligibleChildrenForRecursiveChildren(User user) -- cgit v1.2.3 From ccd4b940f70a7f9a6742d60b5d806bdce8ea68cf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 29 Jul 2015 22:08:35 -0400 Subject: update translations --- .../ScheduledTasks/IntervalTrigger.cs | 8 ++-- .../Localization/Core/de.json | 36 ++++++++-------- .../Localization/Core/es-MX.json | 34 +++++++-------- .../Localization/Core/fr.json | 36 ++++++++-------- .../Localization/Core/kk.json | 50 +++++++++++----------- .../Localization/Core/pt-BR.json | 38 ++++++++-------- .../Localization/Core/ru.json | 36 ++++++++-------- 7 files changed, 120 insertions(+), 118 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index 41073516a..15109be4f 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -45,11 +45,13 @@ namespace MediaBrowser.Common.ScheduledTasks if (DateTime.UtcNow > triggerDate) { - triggerDate = DateTime.UtcNow; - if (isApplicationStartup) { - triggerDate = triggerDate.AddMinutes(1); + triggerDate = DateTime.UtcNow.AddMinutes(5); + } + else + { + triggerDate = DateTime.UtcNow.Add(Interval); } } diff --git a/MediaBrowser.Server.Implementations/Localization/Core/de.json b/MediaBrowser.Server.Implementations/Localization/Core/de.json index f61988628..277a224ce 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/de.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/de.json @@ -132,24 +132,24 @@ "HeaderUser": "Benutzer", "HeaderName": "Name", "HeaderDate": "Datum", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "Premiere Datum", + "HeaderDateAdded": "Datum hinzugef\u00fcgt", "HeaderReleaseDate": "Ver\u00f6ffentlichungsdatum", "HeaderRuntime": "Laufzeit", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "Anzahl Wiedergaben", "HeaderSeason": "Staffel", "HeaderSeasonNumber": "Staffel Nummer", - "HeaderSeries": "Series:", + "HeaderSeries": "Serien:", "HeaderNetwork": "Netzwerk", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", + "HeaderYear": "Jahr:", + "HeaderYears": "Jahre:", + "HeaderParentalRating": "Altersfreigabe", "HeaderCommunityRating": "Community Bewertung", "HeaderTrailers": "Trailer", "HeaderSpecials": "Extras", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "Spiele Systeme", + "HeaderPlayers": "Spieler:", + "HeaderAlbumArtists": "Album K\u00fcnstler", "HeaderAlbums": "Alben", "HeaderDisc": "Disc", "HeaderTrack": "St\u00fcck", @@ -162,15 +162,15 @@ "HeaderCountries": "L\u00e4nder", "HeaderStatus": "Status", "HeaderTracks": "Lieder", - "HeaderMusicArtist": "Music artist", + "HeaderMusicArtist": "Musik K\u00fcnstler", "HeaderLocked": "Blockiert", "HeaderStudios": "Studios", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "Schauspieler", + "HeaderComposer": "Komponierer", + "HeaderDirector": "Regie", + "HeaderGuestStar": "Gaststar", + "HeaderProducer": "Produzenten", + "HeaderWriter": "Autoren", "HeaderParentalRatings": "Altersbeschr\u00e4nkung", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "Community Bewertungen" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json b/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json index 9765ed056..9e1030dbd 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/es-MX.json @@ -132,24 +132,24 @@ "HeaderUser": "Usuario", "HeaderName": "Nombre", "HeaderDate": "Fecha", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "Fecha de Estreno", + "HeaderDateAdded": "Fecha de Adici\u00f3n", "HeaderReleaseDate": "Fecha de estreno", "HeaderRuntime": "Duraci\u00f3n", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "Contador", "HeaderSeason": "Temporada", "HeaderSeasonNumber": "N\u00famero de temporada", "HeaderSeries": "Series:", "HeaderNetwork": "Cadena", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", + "HeaderYear": "A\u00f1o:", + "HeaderYears": "A\u00f1os:", + "HeaderParentalRating": "Clasificaci\u00f3n Parental", "HeaderCommunityRating": "Calificaci\u00f3n de la comunidad", "HeaderTrailers": "Tr\u00e1ilers", "HeaderSpecials": "Especiales", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "Sistemas de Juego", + "HeaderPlayers": "Reproductores:", + "HeaderAlbumArtists": "Artistas del \u00c1lbum", "HeaderAlbums": "\u00c1lbumes", "HeaderDisc": "Disco", "HeaderTrack": "Pista", @@ -162,15 +162,15 @@ "HeaderCountries": "Pa\u00edses", "HeaderStatus": "Estado", "HeaderTracks": "Pistas", - "HeaderMusicArtist": "Music artist", + "HeaderMusicArtist": "Int\u00e9rprete", "HeaderLocked": "Bloqueado", "HeaderStudios": "Estudios", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "Actores", + "HeaderComposer": "Compositores", + "HeaderDirector": "Directores", + "HeaderGuestStar": "Estrella invitada", + "HeaderProducer": "Productores", + "HeaderWriter": "Guionistas", "HeaderParentalRatings": "Clasificaci\u00f3n Parental", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "Clasificaciones de la comunidad" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/fr.json b/MediaBrowser.Server.Implementations/Localization/Core/fr.json index 9328c5c5d..fe76ac64e 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/fr.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/fr.json @@ -132,24 +132,24 @@ "HeaderUser": "Utilisateur", "HeaderName": "Nom", "HeaderDate": "Date", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "Date de la Premi\u00e8re", + "HeaderDateAdded": "Date d'ajout", "HeaderReleaseDate": "Date de sortie ", "HeaderRuntime": "Dur\u00e9e", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "Nombre de lectures", "HeaderSeason": "Saison", "HeaderSeasonNumber": "Num\u00e9ro de saison", - "HeaderSeries": "Series:", + "HeaderSeries": "S\u00e9ries :", "HeaderNetwork": "R\u00e9seau", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", + "HeaderYear": "Ann\u00e9e :", + "HeaderYears": "Ann\u00e9es :", + "HeaderParentalRating": "Classification parentale", "HeaderCommunityRating": "Note de la communaut\u00e9", "HeaderTrailers": "Bandes-annonces", "HeaderSpecials": "Episodes sp\u00e9ciaux", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "Plateformes de jeu", + "HeaderPlayers": "Lecteurs :", + "HeaderAlbumArtists": "Artistes sur l'album", "HeaderAlbums": "Albums", "HeaderDisc": "Disque", "HeaderTrack": "Piste", @@ -162,15 +162,15 @@ "HeaderCountries": "Pays", "HeaderStatus": "\u00c9tat", "HeaderTracks": "Pistes", - "HeaderMusicArtist": "Music artist", + "HeaderMusicArtist": "Artiste de l'album", "HeaderLocked": "Verrouill\u00e9", "HeaderStudios": "Studios", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "Acteurs", + "HeaderComposer": "Compositeurs", + "HeaderDirector": "R\u00e9alisateurs", + "HeaderGuestStar": "R\u00f4le principal", + "HeaderProducer": "Producteurs", + "HeaderWriter": "Auteur(e)s", "HeaderParentalRatings": "Note parentale", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "Classification de la communaut\u00e9" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/kk.json b/MediaBrowser.Server.Implementations/Localization/Core/kk.json index e33164779..432d90171 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/kk.json @@ -120,11 +120,11 @@ "UserStartedPlayingItemWithValues": "{0} - {1} \u043e\u0439\u043d\u0430\u0442\u0443\u044b \u0431\u0430\u0441\u0442\u0430\u043b\u0434\u044b", "UserStoppedPlayingItemWithValues": "{0} - {1} \u043e\u0439\u043d\u0430\u0442\u0443\u044b \u0442\u043e\u049b\u0442\u0430\u043b\u0434\u044b", "SubtitleDownloadFailureForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 {0} \u04af\u0448\u0456\u043d \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u044b\u043d\u0443\u044b \u0441\u04d9\u0442\u0441\u0456\u0437", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", - "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image", + "HeaderUnidentified": "\u0410\u043d\u044b\u049b\u0442\u0430\u043b\u043c\u0430\u0493\u0430\u043d", + "HeaderImagePrimary": "\u0411\u0430\u0441\u0442\u0430\u043f\u049b\u044b", + "HeaderImageBackdrop": "\u0410\u0440\u0442\u049b\u044b \u0441\u0443\u0440\u0435\u0442", + "HeaderImageLogo": "\u041b\u043e\u0433\u043e\u0442\u0438\u043f", + "HeaderUserPrimaryImage": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0441\u0443\u0440\u0435\u0442\u0456", "HeaderOverview": "\u0416\u0430\u043b\u043f\u044b \u0448\u043e\u043b\u0443", "HeaderShortOverview": "\u049a\u044b\u0441\u049b\u0430\u0448\u0430 \u0448\u043e\u043b\u0443", "HeaderType": "\u0422\u04af\u0440\u0456", @@ -132,24 +132,24 @@ "HeaderUser": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b", "HeaderName": "\u0410\u0442\u044b", "HeaderDate": "\u041a\u04af\u043d\u0456", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "\u0422\u04b1\u0441\u0430\u0443\u043a\u0435\u0441\u0435\u0440 \u043a\u04af\u043d\u0456", + "HeaderDateAdded": "\u04ae\u0441\u0442\u0435\u043b\u0433\u0435\u043d \u043a\u04af\u043d\u0456", "HeaderReleaseDate": "\u0428\u044b\u0493\u0430\u0440\u0443 \u043a\u04af\u043d\u0456", "HeaderRuntime": "\u04b0\u0437\u0430\u049b\u0442\u044b\u0493\u044b", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0435\u0441\u0435\u0431\u0456", "HeaderSeason": "\u041c\u0430\u0443\u0441\u044b\u043c", "HeaderSeasonNumber": "\u041c\u0430\u0443\u0441\u044b\u043c \u043d\u04e9\u043c\u0456\u0440\u0456", - "HeaderSeries": "Series:", + "HeaderSeries": "\u0422\u0435\u043b\u0435\u0445\u0438\u043a\u0430\u044f\u043b\u0430\u0440", "HeaderNetwork": "\u0422\u0435\u043b\u0435\u0436\u0435\u043b\u0456", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", - "HeaderCommunityRating": "\u049a\u0430\u0443\u044b\u043c\u0434\u0430\u0441\u0442\u044b\u049b \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u044b", + "HeaderYear": "\u0416\u044b\u043b:", + "HeaderYears": "\u0416\u044b\u043b\u0434\u0430\u0440:", + "HeaderParentalRating": "\u0416\u0430\u0441\u0442\u0430\u0441 \u0441\u0430\u043d\u0430\u0442\u044b", + "HeaderCommunityRating": "\u049a\u0430\u0443\u044b\u043c \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u044b", "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u043b\u0435\u0440", "HeaderSpecials": "\u0410\u0440\u043d\u0430\u0439\u044b \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0434\u0430\u0440", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "\u041e\u0439\u044b\u043d \u0436\u04af\u0439\u0435\u043b\u0435\u0440\u0456", + "HeaderPlayers": "\u041e\u0439\u044b\u043d\u0448\u044b\u043b\u0430\u0440:", + "HeaderAlbumArtists": "\u0410\u043b\u044c\u0431\u043e\u043c \u043e\u0440\u044b\u043d\u0434\u0430\u0443\u0448\u044b\u043b\u0430\u0440\u044b", "HeaderAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u0434\u0430\u0440", "HeaderDisc": "\u0414\u0438\u0441\u043a\u0456", "HeaderTrack": "\u0416\u043e\u043b\u0448\u044b\u049b", @@ -162,15 +162,15 @@ "HeaderCountries": "\u0415\u043b\u0434\u0435\u0440", "HeaderStatus": "\u041a\u04af\u0439", "HeaderTracks": "\u0416\u043e\u043b\u0448\u044b\u049b\u0442\u0430\u0440", - "HeaderMusicArtist": "Music artist", - "HeaderLocked": "Locked", + "HeaderMusicArtist": "\u041c\u0443\u0437\u044b\u043a\u0430 \u043e\u0440\u044b\u043d\u0434\u0430\u0443\u0448\u044b", + "HeaderLocked": "\u049a\u04b1\u043b\u044b\u043f\u0442\u0430\u043b\u0493\u0430\u043d", "HeaderStudios": "\u0421\u0442\u0443\u0434\u0438\u044f\u043b\u0430\u0440", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "\u0410\u043a\u0442\u0435\u0440\u043b\u0435\u0440", + "HeaderComposer": "\u041a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u043b\u0430\u0440", + "HeaderDirector": "\u0420\u0435\u0436\u0438\u0441\u0441\u0435\u0440\u043b\u0435\u0440", + "HeaderGuestStar": "\u0428\u0430\u049b\u044b\u0440\u044b\u043b\u0493\u0430\u043d \u0430\u043a\u0442\u0435\u0440", + "HeaderProducer": "\u041f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043b\u0435\u0440", + "HeaderWriter": "\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439\u0448\u0456\u043b\u0435\u0440", "HeaderParentalRatings": "\u0416\u0430\u0441\u0442\u0430\u0441 \u0441\u0430\u043d\u0430\u0442\u0442\u0430\u0440", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "\u049a\u0430\u0443\u044b\u043c \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u043b\u0430\u0440\u044b" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json b/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json index 58db6d609..e5e8afaa5 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/pt-BR.json @@ -112,7 +112,7 @@ "MessageServerConfigurationUpdated": "A configura\u00e7\u00e3o do servidor foi atualizada", "MessageNamedServerConfigurationUpdatedWithValue": "A se\u00e7\u00e3o {0} da configura\u00e7\u00e3o do servidor foi atualizada", "MessageApplicationUpdated": "O Servidor Emby foi atualizado", - "FailedLoginAttemptWithUserName": "Falha em tentativa de login de {0}", + "FailedLoginAttemptWithUserName": "Falha na tentativa de login de {0}", "AuthenticationSucceededWithUserName": "{0} autenticou-se com sucesso", "DeviceOfflineWithName": "{0} foi desconectado", "UserLockedOutWithName": "Usu\u00e1rio {0} foi bloqueado", @@ -132,24 +132,24 @@ "HeaderUser": "Usu\u00e1rio", "HeaderName": "Nome", "HeaderDate": "Data", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "Data da Estr\u00e9ia", + "HeaderDateAdded": "Data da Adi\u00e7\u00e3o", "HeaderReleaseDate": "Data de lan\u00e7amento", "HeaderRuntime": "Dura\u00e7\u00e3o", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "N\u00famero de Reprodu\u00e7\u00f5es", "HeaderSeason": "Temporada", "HeaderSeasonNumber": "N\u00famero da temporada", - "HeaderSeries": "Series:", + "HeaderSeries": "S\u00e9rie:", "HeaderNetwork": "Rede de TV", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", + "HeaderYear": "Ano:", + "HeaderYears": "Anos:", + "HeaderParentalRating": "Classifica\u00e7\u00e3o Parental", "HeaderCommunityRating": "Avalia\u00e7\u00e3o da Comunidade", "HeaderTrailers": "Trailers", "HeaderSpecials": "Especiais", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "Sistemas de Jogo", + "HeaderPlayers": "Jogadores:", + "HeaderAlbumArtists": "Artistas do \u00c1lbum", "HeaderAlbums": "\u00c1lbuns", "HeaderDisc": "Disco", "HeaderTrack": "Faixa", @@ -162,15 +162,15 @@ "HeaderCountries": "Pa\u00edses", "HeaderStatus": "Status", "HeaderTracks": "Faixas", - "HeaderMusicArtist": "Music artist", + "HeaderMusicArtist": "Artista da m\u00fasica", "HeaderLocked": "Travado", "HeaderStudios": "Est\u00fadios", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "Atores", + "HeaderComposer": "Compositores", + "HeaderDirector": "Diretores", + "HeaderGuestStar": "Ator convidado", + "HeaderProducer": "Produtores", + "HeaderWriter": "Escritores", "HeaderParentalRatings": "Classifica\u00e7\u00f5es Parentais", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "Avalia\u00e7\u00f5es da comunidade" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ru.json b/MediaBrowser.Server.Implementations/Localization/Core/ru.json index bd9e94ec6..56af637df 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ru.json @@ -132,24 +132,24 @@ "HeaderUser": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c", "HeaderName": "\u0418\u043c\u044f (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435)", "HeaderDate": "\u0414\u0430\u0442\u0430", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "\u0414\u0430\u0442\u0430 \u043f\u0440\u0435\u043c\u044c\u0435\u0440\u044b", + "HeaderDateAdded": "\u0414\u0430\u0442\u0430 \u0434\u043e\u0431-\u0438\u044f", "HeaderReleaseDate": "\u0414\u0430\u0442\u0430 \u0432\u044b\u043f.", "HeaderRuntime": "\u0414\u043b\u0438\u0442.", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "\u041a\u043e\u043b-\u0432\u043e \u0432\u043e\u0441\u043f\u0440-\u0438\u0439", "HeaderSeason": "\u0421\u0435\u0437\u043e\u043d", "HeaderSeasonNumber": "\u041d\u043e\u043c\u0435\u0440 \u0441\u0435\u0437\u043e\u043d\u0430", - "HeaderSeries": "Series:", + "HeaderSeries": "\u0421\u0435\u0440\u0438\u0430\u043b:", "HeaderNetwork": "\u0422\u0435\u043b\u0435\u0441\u0435\u0442\u044c", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", + "HeaderYear": "\u0413\u043e\u0434:", + "HeaderYears": "\u0413\u043e\u0434\u044b:", + "HeaderParentalRating": "\u0412\u043e\u0437\u0440. \u043a\u0430\u0442-\u0438\u044f", "HeaderCommunityRating": "\u041e\u0431\u0449. \u043e\u0446\u0435\u043d\u043a\u0430", "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b.", "HeaderSpecials": "\u0421\u043f\u0435\u0446.", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "\u0418\u0433\u0440. \u0441\u0438\u0441\u0442\u0435\u043c\u044b", + "HeaderPlayers": "\u0418\u0433\u0440\u043e\u043a\u0438:", + "HeaderAlbumArtists": "\u0410\u043b\u044c\u0431\u043e\u043c. \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438", "HeaderAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u044b", "HeaderDisc": "\u0414\u0438\u0441\u043a", "HeaderTrack": "\u0414\u043e\u0440-\u043a\u0430", @@ -162,15 +162,15 @@ "HeaderCountries": "\u0421\u0442\u0440\u0430\u043d\u044b", "HeaderStatus": "\u0421\u043e\u0441\u0442-\u0438\u0435", "HeaderTracks": "\u0414\u043e\u0440-\u043a\u0438", - "HeaderMusicArtist": "Music artist", + "HeaderMusicArtist": "\u041c\u0443\u0437. \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c", "HeaderLocked": "\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e", "HeaderStudios": "\u0421\u0442\u0443\u0434\u0438\u0438", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "\u0410\u043a\u0442\u0451\u0440\u044b", + "HeaderComposer": "\u041a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u044b", + "HeaderDirector": "\u0420\u0435\u0436\u0438\u0441\u0441\u0451\u0440\u044b", + "HeaderGuestStar": "\u041f\u0440\u0438\u0433\u043b. \u0430\u043a\u0442\u0451\u0440", + "HeaderProducer": "\u041f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u044b", + "HeaderWriter": "\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0441\u0442\u044b", "HeaderParentalRatings": "\u0412\u043e\u0437\u0440\u0430\u0441\u0442\u043d\u0430\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "\u041e\u0431\u0449. \u043e\u0446\u0435\u043d\u043a\u0438" } \ No newline at end of file -- cgit v1.2.3 From a2b9ee8ac6c760c02cd1cc42d0fe56137b77802e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 30 Jul 2015 10:34:46 -0400 Subject: update startup wizard --- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 6 +++++- MediaBrowser.Model/Session/PlayerStateInfo.cs | 6 ++++++ MediaBrowser.Server.Implementations/Session/SessionManager.cs | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs index 5f32725d8..7002a3703 100644 --- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs +++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs @@ -185,6 +185,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "PlaySessionId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public string PlaySessionId { get; set; } + + [ApiMember(Name = "RepeatMode", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public RepeatMode RepeatMode { get; set; } } /// @@ -325,7 +328,8 @@ namespace MediaBrowser.Api.UserLibrary VolumeLevel = request.VolumeLevel, PlayMethod = request.PlayMethod, PlaySessionId = request.PlaySessionId, - LiveStreamId = request.LiveStreamId + LiveStreamId = request.LiveStreamId, + RepeatMode = request.RepeatMode }); } diff --git a/MediaBrowser.Model/Session/PlayerStateInfo.cs b/MediaBrowser.Model/Session/PlayerStateInfo.cs index c9afef8e0..f78842e29 100644 --- a/MediaBrowser.Model/Session/PlayerStateInfo.cs +++ b/MediaBrowser.Model/Session/PlayerStateInfo.cs @@ -55,5 +55,11 @@ /// /// The play method. public PlayMethod? PlayMethod { get; set; } + + /// + /// Gets or sets the repeat mode. + /// + /// The repeat mode. + public RepeatMode RepeatMode { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 560d203db..c2160f48a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -366,6 +366,7 @@ namespace MediaBrowser.Server.Implementations.Session session.PlayState.AudioStreamIndex = info.AudioStreamIndex; session.PlayState.SubtitleStreamIndex = info.SubtitleStreamIndex; session.PlayState.PlayMethod = info.PlayMethod; + session.PlayState.RepeatMode = info.RepeatMode; } /// -- cgit v1.2.3 From 25395c5d82a9136253706a7fed5a552dcc452acd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 30 Jul 2015 22:34:15 -0400 Subject: update stream builder subtitles --- MediaBrowser.Model/Dlna/StreamBuilder.cs | 7 ++++++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 0f99da8b4..e0cc1b705 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -735,7 +735,12 @@ namespace MediaBrowser.Model.Dlna continue; } - if (profile.Method == SubtitleDeliveryMethod.Embed && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) + if (profile.Method != SubtitleDeliveryMethod.Embed) + { + continue; + } + + if (subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format) && StringHelper.EqualsIgnoreCase(profile.Format, subtitleStream.Codec)) { return profile; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs index 10baffea6..c74220137 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun string location; if (e.Headers.TryGetValue("Location", out location)) { - _logger.Debug("HdHomerun found at {0}", location); + //_logger.Debug("HdHomerun found at {0}", location); // Just get the beginning of the url Uri uri; @@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun var apiUrl = location.Replace(uri.LocalPath, String.Empty, StringComparison.OrdinalIgnoreCase) .TrimEnd('/'); - _logger.Debug("HdHomerun api url: {0}", apiUrl); + //_logger.Debug("HdHomerun api url: {0}", apiUrl); AddDevice(apiUrl); } } -- cgit v1.2.3 From a7b25c065c831804c701c44f30b277c9c7689ac3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 31 Jul 2015 16:38:08 -0400 Subject: update stream buffering --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 72 +++------------------- .../Progressive/ProgressiveStreamWriter.cs | 5 +- MediaBrowser.Controller/Entities/TV/Episode.cs | 2 +- .../HttpServer/RangeRequestWriter.cs | 13 ++-- .../HttpServer/StreamWriter.cs | 5 +- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- 6 files changed, 27 insertions(+), 72 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 305547e41..8ee508c4d 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -210,8 +210,6 @@ namespace MediaBrowser.Api.Playback.Hls { ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false); - await ReadSegmentLengths(playlistPath).ConfigureAwait(false); - if (currentTranscodingIndex.HasValue) { DeleteLastFile(playlistPath, segmentExtension, 0); @@ -255,55 +253,8 @@ namespace MediaBrowser.Api.Playback.Hls return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); } - private static readonly ConcurrentDictionary SegmentLengths = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private async Task ReadSegmentLengths(string playlist) - { - try - { - using (var fileStream = GetPlaylistFileStream(playlist)) - { - using (var reader = new StreamReader(fileStream)) - { - double duration = -1; - - while (!reader.EndOfStream) - { - var text = await reader.ReadLineAsync().ConfigureAwait(false); - - if (text.StartsWith("#EXTINF", StringComparison.OrdinalIgnoreCase)) - { - var parts = text.Split(new[] { ':' }, 2); - if (parts.Length == 2) - { - var time = parts[1].Trim(new[] { ',' }).Trim(); - double timeValue; - if (double.TryParse(time, NumberStyles.Any, CultureInfo.InvariantCulture, out timeValue)) - { - duration = timeValue; - continue; - } - } - } - else if (duration != -1) - { - SegmentLengths.AddOrUpdate(text, duration, (k, v) => duration); - Logger.Debug("Added segment length of {0} for {1}", duration, text); - } - - duration = -1; - } - } - } - } - catch (DirectoryNotFoundException) - { - - } - catch (FileNotFoundException) - { - - } - } + // 256k + private const int BufferSize = 262144; private long GetSeekPositionTicks(StreamState state, string playlist, int requestedIndex) { @@ -455,21 +406,18 @@ namespace MediaBrowser.Api.Playback.Hls { using (var fileStream = GetPlaylistFileStream(playlistPath)) { - using (var reader = new StreamReader(fileStream)) + using (var reader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) { - while (!reader.EndOfStream) - { - var text = await reader.ReadLineAsync().ConfigureAwait(false); + var text = await reader.ReadToEndAsync().ConfigureAwait(false); - // If it appears in the playlist, it's done - if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + // If it appears in the playlist, it's done + if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + { + if (File.Exists(segmentPath)) { - if (File.Exists(segmentPath)) - { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); - } - break; + return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); } + //break; } } } diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 6a3443f35..adedd9461 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -91,6 +91,9 @@ namespace MediaBrowser.Api.Playback.Progressive private readonly IFileSystem _fileSystem; private readonly TranscodingJob _job; + // 256k + private const int BufferSize = 262144; + private long _bytesWritten = 0; public ProgressiveFileCopier(IFileSystem fileSystem, TranscodingJob job) @@ -108,7 +111,7 @@ namespace MediaBrowser.Api.Playback.Progressive { while (eofCount < 15) { - CopyToInternal(fs, outputStream, 81920); + CopyToInternal(fs, outputStream, BufferSize); var fsPosition = fs.Position; diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 8f5b8f6cf..5163c3de4 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -150,7 +150,7 @@ namespace MediaBrowser.Controller.Entities.TV { var series = Series; - if (ParentIndexNumber.HasValue) + if (series != null && ParentIndexNumber.HasValue) { var findNumber = ParentIndexNumber.Value; diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index 322114112..f20487733 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -28,6 +28,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer public Action OnComplete { get; set; } private readonly ILogger _logger; + // 256k + private const int BufferSize = 262144; + /// /// The _options /// @@ -187,7 +190,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer // If the requested range is "0-", we can optimize by just doing a stream copy if (RangeEnd >= TotalContentLength - 1) { - source.CopyTo(responseStream); + source.CopyTo(responseStream, BufferSize); } else { @@ -211,8 +214,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private void CopyToInternal(Stream source, Stream destination, long copyLength) { - const int bufferSize = 81920; - var array = new byte[bufferSize]; + var array = new byte[BufferSize]; int count; while ((count = source.Read(array, 0, array.Length)) != 0) { @@ -249,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer // If the requested range is "0-", we can optimize by just doing a stream copy if (RangeEnd >= TotalContentLength - 1) { - await source.CopyToAsync(responseStream).ConfigureAwait(false); + await source.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false); } else { @@ -268,8 +270,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private async Task CopyToAsyncInternal(Stream source, Stream destination, int copyLength, CancellationToken cancellationToken) { - const int bufferSize = 81920; - var array = new byte[bufferSize]; + var array = new byte[BufferSize]; int count; while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) { diff --git a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs index fe662542e..daa5b86d9 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs @@ -81,6 +81,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer WriteToInternal(responseStream); } + // 256k + private const int BufferSize = 262144; + /// /// Writes to async. /// @@ -92,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer { using (var src = SourceStream) { - src.CopyTo(responseStream); + src.CopyTo(responseStream, BufferSize); } } catch (Exception ex) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c323f8e0d..4430b9455 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -525,7 +525,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { using (var output = File.Open(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { - await response.Content.CopyToAsync(output, 4096, linkedToken); + await response.Content.CopyToAsync(output, 131072, linkedToken); } } -- cgit v1.2.3 From bd39a81ba263d3ac961fdb8469629541c65f77f0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 1 Aug 2015 17:17:46 -0400 Subject: add new voice commands --- MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs | 4 ++-- MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs | 2 +- MediaBrowser.Common/IO/StreamDefaults.cs | 4 ++-- MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs index ea4a61e25..e9ef84663 100644 --- a/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs +++ b/MediaBrowser.Common.Implementations/IO/CommonFileSystem.cs @@ -234,10 +234,10 @@ namespace MediaBrowser.Common.Implementations.IO { if (_supportsAsyncFileStreams && isAsync) { - return new FileStream(path, mode, access, share, 4096, true); + return new FileStream(path, mode, access, share, StreamDefaults.DefaultFileStreamBufferSize, true); } - return new FileStream(path, mode, access, share); + return new FileStream(path, mode, access, share, StreamDefaults.DefaultFileStreamBufferSize); } /// diff --git a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs index b49551ea9..f194b334a 100644 --- a/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs +++ b/MediaBrowser.Common.Implementations/Serialization/JsonSerializer.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Common.Implementations.Serialization private Stream OpenFile(string path) { - return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); + return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 131072); } /// diff --git a/MediaBrowser.Common/IO/StreamDefaults.cs b/MediaBrowser.Common/IO/StreamDefaults.cs index 0cbf1643f..450d293d4 100644 --- a/MediaBrowser.Common/IO/StreamDefaults.cs +++ b/MediaBrowser.Common/IO/StreamDefaults.cs @@ -9,11 +9,11 @@ namespace MediaBrowser.Common.IO /// /// The default copy to buffer size /// - public const int DefaultCopyToBufferSize = 81920; + public const int DefaultCopyToBufferSize = 262144; /// /// The default file stream buffer size /// - public const int DefaultFileStreamBufferSize = 4096; + public const int DefaultFileStreamBufferSize = 262144; } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index da37cfa8b..961d58eb6 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -335,7 +335,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// Stream. private Stream GetFileStream(string path, FileShare fileShare) { - return _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, fileShare, true); + return _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, fileShare); } public object GetStaticResult(IRequest requestContext, -- cgit v1.2.3 From edecae6ed5bcd7159ac2ba2c12d8d38824915129 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Aug 2015 13:02:23 -0400 Subject: improve guide loading performance --- Emby.Drawing/ImageProcessor.cs | 26 +++---- MediaBrowser.Api/LiveTv/LiveTvService.cs | 80 +++++++++++++++++++--- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 15 ++-- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 18 ++--- MediaBrowser.Model/Channels/ChannelQuery.cs | 14 +++- MediaBrowser.Model/LiveTv/ProgramQuery.cs | 10 +++ .../LiveTv/RecommendedProgramQuery.cs | 14 +++- MediaBrowser.Model/LiveTv/RecordingQuery.cs | 14 +++- .../Dto/DtoService.cs | 5 -- .../Library/MediaSourceManager.cs | 4 ++ .../LiveTv/LiveTvDtoService.cs | 5 +- .../LiveTv/LiveTvManager.cs | 14 ++-- 12 files changed, 166 insertions(+), 53 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 2ba4f5aab..1e4537bae 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -410,18 +410,20 @@ namespace Emby.Drawing { ImageSize size; - try - { - size = ImageHeader.GetDimensions(path, _logger, _fileSystem); - } - catch - { - _logger.Info("Failed to read image header for {0}. Doing it the slow way.", path); - - CheckDisposed(); - - size = _imageEncoder.GetImageSize(path); - } + size = ImageHeader.GetDimensions(path, _logger, _fileSystem); + //try + //{ + // size = ImageHeader.GetDimensions(path, _logger, _fileSystem); + //} + //catch + //{ + // return; + // //_logger.Info("Failed to read image header for {0}. Doing it the slow way.", path); + + // //CheckDisposed(); + + // //size = _imageEncoder.GetImageSize(path); + //} StartSaveImageSizeTimer(); diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 6814ad751..3ff4c4828 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Channels", "GET", Summary = "Gets available live tv channels.")] [Authenticated] - public class GetChannels : IReturn> + public class GetChannels : IReturn>, IHasDtoOptions { [ApiMember(Name = "Type", Description = "Optional filter by channel type.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public ChannelType? Type { get; set; } @@ -62,6 +62,22 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "EnableFavoriteSorting", Description = "Incorporate favorite and like status into channel sorting.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool EnableFavoriteSorting { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } + + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string Fields { get; set; } } [Route("/LiveTv/Channels/{Id}", "GET", Summary = "Gets a live tv channel")] @@ -81,7 +97,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Recordings", "GET", Summary = "Gets live tv recordings")] [Authenticated] - public class GetRecordings : IReturn> + public class GetRecordings : IReturn>, IHasDtoOptions { [ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string ChannelId { get; set; } @@ -106,6 +122,22 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "SeriesTimerId", Description = "Optional filter by recordings belonging to a series timer", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string SeriesTimerId { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } + + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string Fields { get; set; } } [Route("/LiveTv/Recordings/Groups", "GET", Summary = "Gets live tv recording groups")] @@ -164,7 +196,7 @@ namespace MediaBrowser.Api.LiveTv [Route("/LiveTv/Programs", "GET,POST", Summary = "Gets available live tv epgs..")] [Authenticated] - public class GetPrograms : IReturn> + public class GetPrograms : IReturn>, IHasDtoOptions { [ApiMember(Name = "ChannelIds", Description = "The channels to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string ChannelIds { get; set; } @@ -207,11 +239,27 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "Genres", Description = "The genres to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string Genres { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } + + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string Fields { get; set; } } [Route("/LiveTv/Programs/Recommended", "GET", Summary = "Gets available live tv epgs..")] [Authenticated] - public class GetRecommendedPrograms : IReturn> + public class GetRecommendedPrograms : IReturn>, IHasDtoOptions { [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string UserId { get; set; } @@ -230,6 +278,22 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "IsMovie", Description = "Optional filter for movies.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsMovie { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } + + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string Fields { get; set; } } [Route("/LiveTv/Programs/{Id}", "GET", Summary = "Gets a live tv program")] @@ -490,7 +554,7 @@ namespace MediaBrowser.Api.LiveTv IsDisliked = request.IsDisliked, EnableFavoriteSorting = request.EnableFavoriteSorting - }, CancellationToken.None).ConfigureAwait(false); + }, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -546,7 +610,7 @@ namespace MediaBrowser.Api.LiveTv query.IsSports = request.IsSports; query.Genres = (request.Genres ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - var result = await _liveTvManager.GetPrograms(query, CancellationToken.None).ConfigureAwait(false); + var result = await _liveTvManager.GetPrograms(query, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } @@ -563,7 +627,7 @@ namespace MediaBrowser.Api.LiveTv IsSports = request.IsSports }; - var result = await _liveTvManager.GetRecommendedPrograms(query, CancellationToken.None).ConfigureAwait(false); + var result = await _liveTvManager.GetRecommendedPrograms(query, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } @@ -575,7 +639,7 @@ namespace MediaBrowser.Api.LiveTv public async Task Get(GetRecordings request) { - var options = new DtoOptions(); + var options = GetDtoOptions(request); options.DeviceId = AuthorizationContext.GetAuthorizationInfo(Request).DeviceId; var result = await _liveTvManager.GetRecordings(new RecordingQuery diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 53ad6dbdc..889875383 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -69,9 +69,10 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the channels. /// /// The query. + /// The options. /// The cancellation token. /// IEnumerable{Channel}. - Task> GetChannels(LiveTvChannelQuery query, CancellationToken cancellationToken); + Task> GetChannels(LiveTvChannelQuery query, DtoOptions options, CancellationToken cancellationToken); /// /// Gets the recording. @@ -173,14 +174,15 @@ namespace MediaBrowser.Controller.LiveTv /// The user. /// Task{ProgramInfoDto}. Task GetProgram(string id, CancellationToken cancellationToken, User user = null); - + /// /// Gets the programs. /// /// The query. + /// The options. /// The cancellation token. /// IEnumerable{ProgramInfo}. - Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken); + Task> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken); /// /// Updates the timer. @@ -240,10 +242,10 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the recommended programs. /// /// The query. + /// The options. /// The cancellation token. /// Task{QueryResult{ProgramInfoDto}}. - Task> GetRecommendedPrograms(RecommendedProgramQuery query, - CancellationToken cancellationToken); + Task> GetRecommendedPrograms(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken); /// /// Gets the recommended programs internal. @@ -251,8 +253,7 @@ namespace MediaBrowser.Controller.LiveTv /// The query. /// The cancellation token. /// Task<QueryResult<LiveTvProgram>>. - Task> GetRecommendedProgramsInternal(RecommendedProgramQuery query, - CancellationToken cancellationToken); + Task> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken); /// /// Gets the live tv information. diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index 0e4cf7392..25514f1dc 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -971,17 +971,17 @@ namespace MediaBrowser.Dlna.Didl int? width = null; int? height = null; - try - { - var size = _imageProcessor.GetImageSize(imageInfo); + //try + //{ + // var size = _imageProcessor.GetImageSize(imageInfo); - width = Convert.ToInt32(size.Width); - height = Convert.ToInt32(size.Height); - } - catch - { + // width = Convert.ToInt32(size.Width); + // height = Convert.ToInt32(size.Height); + //} + //catch + //{ - } + //} return new ImageDownloadInfo { diff --git a/MediaBrowser.Model/Channels/ChannelQuery.cs b/MediaBrowser.Model/Channels/ChannelQuery.cs index 3c6e43fde..b63d797f4 100644 --- a/MediaBrowser.Model/Channels/ChannelQuery.cs +++ b/MediaBrowser.Model/Channels/ChannelQuery.cs @@ -1,7 +1,19 @@ -namespace MediaBrowser.Model.Channels +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; + +namespace MediaBrowser.Model.Channels { public class ChannelQuery { + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + public ItemFields[] Fields { get; set; } + public bool? EnableImages { get; set; } + public int? ImageTypeLimit { get; set; } + public ImageType[] EnableImageTypes { get; set; } + /// /// Gets or sets the user identifier. /// diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs index c19ba54bd..3f652ea6f 100644 --- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Entities; using System; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Model.LiveTv { @@ -15,6 +16,15 @@ namespace MediaBrowser.Model.LiveTv Genres = new string[] { }; } + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + public ItemFields[] Fields { get; set; } + public bool? EnableImages { get; set; } + public int? ImageTypeLimit { get; set; } + public ImageType[] EnableImageTypes { get; set; } + /// /// Gets or sets the channel ids. /// diff --git a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs index 4a8ae2365..09d45066b 100644 --- a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs @@ -1,7 +1,19 @@ -namespace MediaBrowser.Model.LiveTv +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; + +namespace MediaBrowser.Model.LiveTv { public class RecommendedProgramQuery { + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + public ItemFields[] Fields { get; set; } + public bool? EnableImages { get; set; } + public int? ImageTypeLimit { get; set; } + public ImageType[] EnableImageTypes { get; set; } + /// /// Gets or sets the user identifier. /// diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs index daa137db6..0cf997602 100644 --- a/MediaBrowser.Model/LiveTv/RecordingQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs @@ -1,4 +1,7 @@ -namespace MediaBrowser.Model.LiveTv +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; + +namespace MediaBrowser.Model.LiveTv { /// /// Class RecordingQuery. @@ -58,5 +61,14 @@ /// /// The series timer identifier. public string SeriesTimerId { get; set; } + + /// + /// Fields to return within the items, in addition to basic information + /// + /// The fields. + public ItemFields[] Fields { get; set; } + public bool? EnableImages { get; set; } + public int? ImageTypeLimit { get; set; } + public ImageType[] EnableImageTypes { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 31f1b17dd..2ff9a2813 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1767,11 +1767,6 @@ namespace MediaBrowser.Server.Implementations.Dto { size = _imageProcessor.GetImageSize(imageInfo); } - catch (FileNotFoundException) - { - _logger.Error("Image file does not exist: {0}", path); - return; - } catch (Exception ex) { _logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 87e71e327..2263b3e1f 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -77,6 +77,10 @@ namespace MediaBrowser.Server.Implementations.Library { return false; } + if (string.Equals(stream.Codec, "ssa", StringComparison.OrdinalIgnoreCase)) + { + return false; + } return true; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 72fea2c79..9ffd8a500 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -198,10 +198,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv /// Gets the channel info dto. /// /// The info. + /// The options. /// The current program. /// The user. /// ChannelInfoDto. - public ChannelInfoDto GetChannelInfoDto(LiveTvChannel info, LiveTvProgram currentProgram, User user = null) + public ChannelInfoDto GetChannelInfoDto(LiveTvChannel info, DtoOptions options, LiveTvProgram currentProgram, User user = null) { var dto = new ChannelInfoDto { @@ -238,7 +239,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (currentProgram != null) { - dto.CurrentProgram = _dtoService.GetBaseItemDto(currentProgram, new DtoOptions(), user); + dto.CurrentProgram = _dtoService.GetBaseItemDto(currentProgram, options, user); } return dto; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d8954724a..f73e648fa 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -238,7 +238,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return result; } - public async Task> GetChannels(LiveTvChannelQuery query, CancellationToken cancellationToken) + public async Task> GetChannels(LiveTvChannelQuery query, DtoOptions options, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -261,7 +261,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channelIdString = channel.Id.ToString("N"); var currentProgram = programs.FirstOrDefault(i => string.Equals(i.ChannelId, channelIdString, StringComparison.OrdinalIgnoreCase)); - returnList.Add(_tvDtoService.GetChannelInfoDto(channel, currentProgram, user)); + returnList.Add(_tvDtoService.GetChannelInfoDto(channel, options, currentProgram, user)); } var result = new QueryResult @@ -762,7 +762,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return dto; } - public async Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) + public async Task> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken) { var internalQuery = new InternalItemsQuery { @@ -822,7 +822,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv .Select(i => { RefreshIfNeeded(i); - return _dtoService.GetBaseItemDto(i, new DtoOptions(), user); + return _dtoService.GetBaseItemDto(i, options, user); }) .ToArray(); @@ -907,14 +907,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv return result; } - public async Task> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken) + public async Task> GetRecommendedPrograms(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken) { var internalResult = await GetRecommendedProgramsInternal(query, cancellationToken).ConfigureAwait(false); var user = _userManager.GetUserById(query.UserId); var returnArray = internalResult.Items - .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user)) + .Select(i => _dtoService.GetBaseItemDto(i, options, user)) .ToArray(); await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); @@ -1712,7 +1712,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv .OrderBy(i => i.StartDate) .FirstOrDefault(); - var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user); + var dto = _tvDtoService.GetChannelInfoDto(channel, new DtoOptions(), currentProgram, user); return dto; } -- cgit v1.2.3 From 47b1a4cafd0cc1882503e46fb8a5082a3b061078 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Aug 2015 15:08:55 -0400 Subject: update image processing --- Emby.Drawing/ImageProcessor.cs | 16 +++++++++++++++- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/Playback/StreamState.cs | 2 +- MediaBrowser.Api/StartupWizardService.cs | 1 + MediaBrowser.Controller/Library/IMetadataFileSaver.cs | 5 +++++ MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs | 9 +++++++-- MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs | 9 +++++++-- MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs | 9 +++++++-- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 2 +- MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs | 2 +- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 ++ MediaBrowser.Model/Dto/MediaSourceInfo.cs | 4 ++-- MediaBrowser.Providers/Manager/ProviderManager.cs | 8 +++++++- .../Library/MediaSourceManager.cs | 2 +- .../LiveTv/LiveTvManager.cs | 4 ++-- .../LiveTv/LiveTvMediaSourceProvider.cs | 8 ++++++-- Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 20 files changed, 72 insertions(+), 25 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 1e4537bae..9db2c1c20 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -189,7 +189,21 @@ namespace Emby.Drawing dateModified = tuple.Item2; } - var originalImageSize = GetImageSize(originalImagePath, dateModified); + ImageSize originalImageSize; + + try + { + originalImageSize = GetImageSize(originalImagePath, dateModified); + } + catch + { + // This is an arbitrary default, but don't fail the whole process over this + originalImageSize = new ImageSize + { + Width = 100, + Height = 100 + }; + } // Determine the output size based on incoming parameters var newSize = DrawingUtils.Resize(originalImageSize, options.Width, options.Height, options.MaxWidth, options.MaxHeight); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 3bef397f9..f108b344f 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -854,7 +854,7 @@ namespace MediaBrowser.Api.Playback state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false); } - if (state.MediaSource.RequiresOpening ?? false) + if (state.MediaSource.RequiresOpening) { var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest { diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index 4df696096..34dc5ea12 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -185,7 +185,7 @@ namespace MediaBrowser.Api.Playback private async void DisposeLiveStream() { - if ((MediaSource.RequiresClosing ?? false) && string.IsNullOrWhiteSpace(Request.LiveStreamId)) + if ((MediaSource.RequiresClosing) && string.IsNullOrWhiteSpace(Request.LiveStreamId)) { try { diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 6ee8d3603..277e02bf9 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -67,6 +67,7 @@ namespace MediaBrowser.Api _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableUserSpecificUserViews = true; _config.Configuration.EnableCustomPathSubFolders = true; + _config.Configuration.DisableXmlSavers = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Controller/Library/IMetadataFileSaver.cs b/MediaBrowser.Controller/Library/IMetadataFileSaver.cs index 0883da48f..e09e58302 100644 --- a/MediaBrowser.Controller/Library/IMetadataFileSaver.cs +++ b/MediaBrowser.Controller/Library/IMetadataFileSaver.cs @@ -11,4 +11,9 @@ namespace MediaBrowser.Controller.Library /// System.String. string GetSavePath(IHasMetadata item); } + + public interface IConfigurableProvider + { + bool IsEnabled { get; } + } } \ No newline at end of file diff --git a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs index 7a2a97c0c..96d95d40b 100644 --- a/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/EpisodeXmlSaver.cs @@ -12,7 +12,7 @@ using System.Threading; namespace MediaBrowser.LocalMetadata.Savers { - public class EpisodeXmlSaver : IMetadataFileSaver + public class EpisodeXmlProvider : IMetadataFileSaver, IConfigurableProvider { private readonly IItemRepository _itemRepository; @@ -20,7 +20,7 @@ namespace MediaBrowser.LocalMetadata.Savers private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; - public EpisodeXmlSaver(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager) + public EpisodeXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager) { _itemRepository = itemRepository; _config = config; @@ -51,6 +51,11 @@ namespace MediaBrowser.LocalMetadata.Savers } } + public bool IsEnabled + { + get { return !_config.Configuration.DisableXmlSavers; } + } + /// /// Saves the specified item. /// diff --git a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs index dc5b45259..a6fba3e9b 100644 --- a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs @@ -15,13 +15,13 @@ namespace MediaBrowser.LocalMetadata.Savers /// /// Saves movie.xml for movies, trailers and music videos /// - public class MovieXmlSaver : IMetadataFileSaver + public class MovieXmlProvider : IMetadataFileSaver, IConfigurableProvider { private readonly IItemRepository _itemRepository; private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; - public MovieXmlSaver(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager) + public MovieXmlProvider(IItemRepository itemRepository, IServerConfigurationManager config, ILibraryManager libraryManager) { _itemRepository = itemRepository; _config = config; @@ -36,6 +36,11 @@ namespace MediaBrowser.LocalMetadata.Savers } } + public bool IsEnabled + { + get { return !_config.Configuration.DisableXmlSavers; } + } + /// /// Determines whether [is enabled for] [the specified item]. /// diff --git a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs index 45aff5e2c..44b1cd8d3 100644 --- a/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/SeriesXmlSaver.cs @@ -12,12 +12,12 @@ using System.Threading; namespace MediaBrowser.LocalMetadata.Savers { - public class SeriesXmlSaver : IMetadataFileSaver + public class SeriesXmlProvider : IMetadataFileSaver, IConfigurableProvider { private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; - public SeriesXmlSaver(IServerConfigurationManager config, ILibraryManager libraryManager) + public SeriesXmlProvider(IServerConfigurationManager config, ILibraryManager libraryManager) { _config = config; _libraryManager = libraryManager; @@ -47,6 +47,11 @@ namespace MediaBrowser.LocalMetadata.Savers return item is Series && updateType >= ItemUpdateType.MetadataDownload; } + public bool IsEnabled + { + get { return !_config.Configuration.DisableXmlSavers; } + } + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); /// diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 140e84963..dd88512fb 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -436,7 +436,7 @@ namespace MediaBrowser.MediaEncoding.Encoder state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false); } - if (state.MediaSource.RequiresOpening ?? false) + if (state.MediaSource.RequiresOpening) { var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest { diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs index 2eeb580e3..806910d89 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs @@ -136,7 +136,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private async void DisposeLiveStream() { - if (MediaSource.RequiresClosing ?? false) + if (MediaSource.RequiresClosing) { try { diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0a2fabc1b..072416684 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -213,6 +213,8 @@ namespace MediaBrowser.Model.Configuration public int SharingExpirationDays { get; set; } + public bool DisableXmlSavers { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index 75edc6a52..8897edcbd 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -26,9 +26,9 @@ namespace MediaBrowser.Model.Dto public bool SupportsDirectStream { get; set; } public bool SupportsDirectPlay { get; set; } - public bool? RequiresOpening { get; set; } + public bool RequiresOpening { get; set; } public string OpenToken { get; set; } - public bool? RequiresClosing { get; set; } + public bool RequiresClosing { get; set; } public string LiveStreamId { get; set; } public int? BufferMs { get; set; } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index beef968fb..453e07987 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -106,9 +106,15 @@ namespace MediaBrowser.Providers.Manager _identityProviders = identityProviders.ToArray(); _identityConverters = identityConverters.ToArray(); _metadataProviders = metadataProviders.ToArray(); - _savers = metadataSavers.ToArray(); _imageSavers = imageSavers.ToArray(); _externalIds = externalIds.OrderBy(i => i.Name).ToArray(); + + _savers = metadataSavers.Where(i => + { + var configurable = i as IConfigurableProvider; + + return configurable == null || configurable.IsEnabled; + }).ToArray(); } public Task RefreshSingleItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 2263b3e1f..c5ff100f9 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -449,7 +449,7 @@ namespace MediaBrowser.Server.Implementations.Library LiveStreamInfo current; if (_openStreams.TryGetValue(id, out current)) { - if (current.MediaSource.RequiresClosing ?? false) + if (current.MediaSource.RequiresClosing) { var tuple = GetProvider(id); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index f73e648fa..b4669f53e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -368,7 +368,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; - if (info.RequiresClosing ?? false) + if (info.RequiresClosing) { var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_"; @@ -385,7 +385,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; - if (info.RequiresClosing ?? false) + if (info.RequiresClosing) { var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_"; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index cf34b6b99..66a21830e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -59,6 +59,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv { IEnumerable sources; + var forceRequireOpening = false; + try { if (item is ILiveTvRecording) @@ -78,6 +80,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv sources = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false) .ToList(); + + forceRequireOpening = true; } var list = sources.ToList(); @@ -87,12 +91,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv { source.Type = MediaSourceType.Default; - if (!source.RequiresOpening.HasValue) + if (source.RequiresOpening || forceRequireOpening) { source.RequiresOpening = true; } - if (source.RequiresOpening.HasValue && source.RequiresOpening.Value) + if (source.RequiresOpening) { var openKeys = new List(); openKeys.Add(item.GetType().Name); diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index fffb68e36..c43b90c8c 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.629 + 3.0.631 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 856e63199..32e3b2fc6 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.629 + 3.0.631 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 30175007d..fc33477a9 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.629 + 3.0.631 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index c688c6f2c..704c30f95 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.629 + 3.0.631 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 2a93de8e119a0be79c3ca9470e73d5e54182aaf0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Aug 2015 19:47:31 -0400 Subject: update live tv guide --- .../LiveTv/EmbyTV/EmbyTV.cs | 19 +++++++++++++++---- .../MediaBrowser.WebDashboard.csproj | 15 --------------- 2 files changed, 15 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 4430b9455..9ca2537f1 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using MediaBrowser.Common; +using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; @@ -13,6 +12,7 @@ using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -134,7 +134,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { foreach (var provider in GetListingProviders()) { - await provider.Item1.AddMetadata(provider.Item2, list, cancellationToken).ConfigureAwait(false); + try + { + await provider.Item1.AddMetadata(provider.Item2, list, cancellationToken).ConfigureAwait(false); + } + catch (NotSupportedException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error adding metadata", ex); + } } } @@ -637,7 +648,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV // TODO: This assumption will require review once additional listing providers are added return allPrograms.Where(epg => epg.Id.StartsWith(seriesTimer.ProgramId, StringComparison.OrdinalIgnoreCase)); } - + private string GetChannelEpgCachePath(string channelId) { return Path.Combine(DataPath, "epg", channelId + ".json"); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 68db88852..0a29b0d91 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -180,24 +180,9 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 30710dbe007b60d696cdf28e4bf97a428432124b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 4 Aug 2015 10:26:36 -0400 Subject: update components --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 8 ++++++++ MediaBrowser.Model/Dto/BaseItemDto.cs | 1 + MediaBrowser.Model/LiveTv/ProgramQuery.cs | 5 +++++ MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs | 5 +++++ .../LiveTv/EmbyTV/EmbyTV.cs | 10 +++++----- .../LiveTv/Listings/SchedulesDirect.cs | 15 +++++++-------- .../LiveTv/LiveTvManager.cs | 4 +++- 7 files changed, 34 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 3ff4c4828..bdec55561 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -222,6 +222,9 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "IsMovie", Description = "Optional filter for movies.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET,POST")] public bool? IsMovie { get; set; } + [ApiMember(Name = "IsKids", Description = "Optional filter for kids.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET,POST")] + public bool? IsKids { get; set; } + [ApiMember(Name = "IsSports", Description = "Optional filter for sports.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET,POST")] public bool? IsSports { get; set; } @@ -279,6 +282,9 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "IsMovie", Description = "Optional filter for movies.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsMovie { get; set; } + [ApiMember(Name = "IsKids", Description = "Optional filter for kids.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsKids { get; set; } + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool? EnableImages { get; set; } @@ -607,6 +613,7 @@ namespace MediaBrowser.Api.LiveTv query.SortBy = (request.SortBy ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); query.SortOrder = request.SortOrder; query.IsMovie = request.IsMovie; + query.IsKids = request.IsKids; query.IsSports = request.IsSports; query.Genres = (request.Genres ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); @@ -624,6 +631,7 @@ namespace MediaBrowser.Api.LiveTv Limit = request.Limit, HasAired = request.HasAired, IsMovie = request.IsMovie, + IsKids = request.IsKids, IsSports = request.IsSports }; diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 7c5d9e9a1..aa68e09a0 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -646,6 +646,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets a value indicating whether [supports playlists]. /// /// true if [supports playlists]; otherwise, false. + [IgnoreDataMember] public bool SupportsPlaylists { get diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs index 3f652ea6f..7a877e356 100644 --- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs @@ -63,6 +63,11 @@ namespace MediaBrowser.Model.LiveTv /// If set to null, all programs will be returned public bool? IsMovie { get; set; } + /// + /// Gets or sets a value indicating whether this instance is kids. + /// + /// null if [is kids] contains no value, true if [is kids]; otherwise, false. + public bool? IsKids { get; set; } /// /// Gets or sets a value indicating whether this instance is sports. /// diff --git a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs index 09d45066b..e83a8fda6 100644 --- a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs @@ -44,6 +44,11 @@ namespace MediaBrowser.Model.LiveTv /// null if [is movie] contains no value, true if [is movie]; otherwise, false. public bool? IsMovie { get; set; } /// + /// Gets or sets a value indicating whether this instance is kids. + /// + /// null if [is kids] contains no value, true if [is kids]; otherwise, false. + public bool? IsKids { get; set; } + /// /// Gets or sets a value indicating whether this instance is sports. /// /// null if [is sports] contains no value, true if [is sports]; otherwise, false. diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 9ca2537f1..b96e3b26c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -490,13 +490,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (recording == null) { - recording = new RecordingInfo() + recording = new RecordingInfo { ChannelId = info.ChannelId, Id = Guid.NewGuid().ToString("N"), StartDate = info.StartDate, EndDate = info.EndDate, - Genres = info.Genres ?? null, + Genres = info.Genres, IsKids = info.IsKids, IsLive = info.IsLive, IsMovie = info.IsMovie, @@ -507,10 +507,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV IsSports = info.IsSports, IsRepeat = !info.IsPremiere, Name = info.Name, - EpisodeTitle = info.EpisodeTitle ?? "", + EpisodeTitle = info.EpisodeTitle, ProgramId = info.Id, - HasImage = info.HasImage ?? false, - ImagePath = info.ImagePath ?? null, + HasImage = info.HasImage, + ImagePath = info.ImagePath, ImageUrl = info.ImageUrl, OriginalAirDate = info.OriginalAirDate, Status = RecordingStatus.Scheduled, diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 655feedae..2aadf4a66 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -286,20 +286,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } ScheduleDirect.Gracenote gracenote; - string EpisodeTitle = ""; + string episodeTitle = null; if (details.metadata != null) { gracenote = details.metadata.Find(x => x.Gracenote != null).Gracenote; if ((details.showType ?? "No ShowType") == "Series") { - EpisodeTitle = "Season: " + gracenote.season + " Episode: " + gracenote.episode; + episodeTitle = "Season: " + gracenote.season + " Episode: " + gracenote.episode; } } if (details.episodeTitle150 != null) { - EpisodeTitle = EpisodeTitle + " " + details.episodeTitle150; + episodeTitle = ((episodeTitle ?? string.Empty) + " " + details.episodeTitle150).Trim(); } - bool hasImage = false; + var imageLink = ""; if (details.hasImageArtwork) @@ -314,11 +314,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings Overview = desc, StartDate = startAt, EndDate = endAt, - Genres = new List() { "N/A" }, Name = details.titles[0].title120 ?? "Unkown", OfficialRating = "0", CommunityRating = null, - EpisodeTitle = EpisodeTitle, + EpisodeTitle = episodeTitle, Audio = audioType, IsHD = hdtv, IsRepeat = repeat, @@ -339,8 +338,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings (details.showType ?? "No ShowType") == "Short Film", IsPremiere = false, }; - //logger.Info("Done init"); - if (null != details.originalAirDate) + + if (!string.IsNullOrWhiteSpace(details.originalAirDate)) { info.OriginalAirDate = DateTime.Parse(details.originalAirDate); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index b4669f53e..6861901ac 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -774,6 +774,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv ChannelIds = query.ChannelIds, IsMovie = query.IsMovie, IsSports = query.IsSports, + IsKids = query.IsKids, Genres = query.Genres }; @@ -844,7 +845,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, IsAiring = query.IsAiring, IsMovie = query.IsMovie, - IsSports = query.IsSports + IsSports = query.IsSports, + IsKids = query.IsKids }; if (query.HasAired.HasValue) -- cgit v1.2.3 From feed1c0b7dab20a7cf90df2be89060b06e1df318 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 4 Aug 2015 14:14:16 -0400 Subject: add user display lang setting --- .../LiveTv/EmbyTV/EntryPoint.cs | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs index 713cb9cd3..a297c866a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs @@ -1,12 +1,41 @@ -using MediaBrowser.Controller.Plugins; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Security; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { public class EntryPoint : IServerEntryPoint { - public void Run() + private readonly IConfigurationManager _config; + private readonly ISecurityManager _manager; + + public EntryPoint(IConfigurationManager config, ISecurityManager manager) + { + _config = config; + _manager = manager; + } + + public async void Run() { EmbyTV.Current.Start(); + + if (GetConfiguration().ListingProviders.Count > 0 || GetConfiguration().TunerHosts.Count > 0) + { + try + { + await _manager.GetRegistrationStatus("livetvguide").ConfigureAwait(false); + } + catch + { + + } + } + } + + private LiveTvOptions GetConfiguration() + { + return _config.GetConfiguration("livetv"); } public void Dispose() -- cgit v1.2.3 From 7caedd1aee55f0fc4a5521b78b2366c091130dfe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 4 Aug 2015 23:43:54 -0400 Subject: added recording logging --- MediaBrowser.Api/Library/LibraryService.cs | 3 ++- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 91f15c8a4..50c4ad14f 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -262,7 +262,7 @@ namespace MediaBrowser.Api.Library /// Initializes a new instance of the class. /// public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, - IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization) + IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv) { _itemRepo = itemRepo; _libraryManager = libraryManager; @@ -272,6 +272,7 @@ namespace MediaBrowser.Api.Library _authContext = authContext; _activityManager = activityManager; _localization = localization; + _liveTv = liveTv; } public object Get(GetMediaFolders request) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 40d93e8ef..e89c83397 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1217,7 +1217,7 @@ namespace MediaBrowser.Server.Implementations.Library { var result = ItemRepository.GetItemIdsList(query); - var items = result.Select(GetItemById).ToArray(); + var items = result.Select(GetItemById).Where(i => i != null).ToArray(); return new QueryResult { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index b96e3b26c..c90b9eacb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -541,13 +541,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } recording.Status = RecordingStatus.Completed; + _logger.Info("Recording completed"); } catch (OperationCanceledException) { + _logger.Info("Recording cancelled"); recording.Status = RecordingStatus.Completed; } - catch + catch (Exception ex) { + _logger.ErrorException("Error recording", ex); recording.Status = RecordingStatus.Error; } -- cgit v1.2.3 From 96346fc88ced93cc068ae9610900b3a1420f2130 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 5 Aug 2015 21:21:18 -0400 Subject: update globalize --- MediaBrowser.Api/UserLibrary/ArtistsService.cs | 41 ++--------- .../Entities/Audio/MusicAlbum.cs | 6 ++ .../Entities/UserViewBuilder.cs | 84 +++++----------------- MediaBrowser.Controller/Library/ILibraryManager.cs | 13 +++- .../Music/MusicBrainzAlbumProvider.cs | 2 +- .../Library/LibraryManager.cs | 83 +++++++++++++++------ .../Library/Validators/ArtistsValidator.cs | 10 +-- .../LiveTv/LiveTvManager.cs | 42 ++++++++--- .../UserViews/DynamicImageProvider.cs | 6 -- 9 files changed, 138 insertions(+), 149 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index 2393d0533..f027fe9df 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -6,7 +6,6 @@ using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using ServiceStack; -using System; using System.Collections.Generic; using System.Linq; @@ -128,44 +127,14 @@ namespace MediaBrowser.Api.UserLibrary { if (request is GetAlbumArtists) { - return items - .Where(i => !i.IsFolder) - .OfType() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(name => - { - try - { - return LibraryManager.GetArtist(name); - } - catch (Exception ex) - { - Logger.ErrorException("Error getting artist {0}", ex, name); - return null; - } - - }).Where(i => i != null); + return LibraryManager.GetAlbumArtists(items + .Where(i => !i.IsFolder) + .OfType()); } - return items + return LibraryManager.GetArtists(items .Where(i => !i.IsFolder) - .OfType() - .SelectMany(i => i.AllArtists) - .DistinctNames() - .Select(name => - { - try - { - return LibraryManager.GetArtist(name); - } - catch (Exception ex) - { - Logger.ErrorException("Error getting artist {0}", ex, name); - return null; - } - - }).Where(i => i != null); + .OfType()); } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 8a77d7616..807beee52 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -54,6 +54,12 @@ namespace MediaBrowser.Controller.Entities.Audio get { return AlbumArtists.FirstOrDefault(); } } + [IgnoreDataMember] + public override bool SupportsPeople + { + get { return false; } + } + public List AlbumArtists { get; set; } /// diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 462f66e20..ba2820bc1 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -341,95 +341,43 @@ namespace MediaBrowser.Controller.Entities var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)) - .OfType() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null); + .OfType(); - return GetResult(items, queryParent, query); + var artists = _libraryManager.GetAlbumArtists(items); + + return GetResult(artists, queryParent, query); } private QueryResult GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query) { - var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) - .OfType() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null); + .OfType(); + + var artists = _libraryManager.GetAlbumArtists(items); return GetResult(artists, parent, query); } private QueryResult GetMusicArtists(Folder parent, User user, InternalItemsQuery query) { - var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) - .OfType() - .SelectMany(i => i.Artists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null); + .OfType(); + var artists = _libraryManager.GetArtists(items); + return GetResult(artists, parent, query); } private QueryResult GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query) { - var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) - .OfType() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null && _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); + .OfType(); + var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); + return GetResult(artists, parent, query); } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 77c07dfd4..9c52fd2dc 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -61,7 +61,18 @@ namespace MediaBrowser.Controller.Library /// The name. /// Task{Artist}. MusicArtist GetArtist(string name); - + /// + /// Gets the album artists. + /// + /// The items. + /// IEnumerable<MusicArtist>. + IEnumerable GetAlbumArtists(IEnumerable items); + /// + /// Gets the artists. + /// + /// The items. + /// IEnumerable<MusicArtist>. + IEnumerable GetArtists(IEnumerable items); /// /// Gets a Studio /// diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs index 664eff004..6748c2ba5 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs @@ -280,7 +280,7 @@ namespace MediaBrowser.Providers.Music { // MusicBrainz is extremely adamant about limiting to one request per second - await Task.Delay(800, cancellationToken).ConfigureAwait(false); + await Task.Delay(1000, cancellationToken).ConfigureAwait(false); var doc = new XmlDocument(); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index e89c83397..c9a5cb731 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -939,26 +939,7 @@ namespace MediaBrowser.Server.Implementations.Library } } - var fileInfo = new DirectoryInfo(path); - - var isNew = false; - - if (!fileInfo.Exists) - { - try - { - fileInfo = Directory.CreateDirectory(path); - } - catch (UnauthorizedAccessException ex) - { - _logger.Error("Error creating directory {0}", ex, path); - throw new Exception(string.Format("Error creating directory {0}", path), ex); - } - - isNew = true; - } - - var item = isNew ? null : GetItemById(id) as T; + var item = GetItemById(id) as T; if (item == null) { @@ -966,8 +947,8 @@ namespace MediaBrowser.Server.Implementations.Library { Name = name, Id = id, - DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo), - DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo), + DateCreated = DateTime.UtcNow, + DateModified = DateTime.UtcNow, Path = path }; } @@ -980,6 +961,59 @@ namespace MediaBrowser.Server.Implementations.Library return item; } + public IEnumerable GetAlbumArtists(IEnumerable items) + { + var names = items + .SelectMany(i => i.AlbumArtists) + .DistinctNames() + .Select(i => + { + try + { + var artist = GetArtist(i); + + return artist; + } + catch + { + // Already logged at lower levels + return null; + } + }) + .Where(i => i != null); + + return names; + } + + public IEnumerable GetArtists(IEnumerable items) + { + var names = items + .SelectMany(i => i.AllArtists) + .DistinctNames() + .Select(i => + { + try + { + var artist = GetArtist(i); + + return artist; + } + catch + { + // Already logged at lower levels + return null; + } + }) + .Where(i => i != null); + + return names; + } + + private void SetPropertiesFromSongs(MusicArtist artist, IEnumerable items) + { + + } + /// /// Validate and refresh the People sub-set of the IBN. /// The items are stored in the db but not loaded into memory until actually requested by an operation. @@ -2118,6 +2152,11 @@ namespace MediaBrowser.Server.Implementations.Library public Task UpdatePeople(BaseItem item, List people) { + if (!item.SupportsPeople) + { + return Task.FromResult(true); + } + return ItemRepository.UpdatePeople(item.Id, people); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index c9440bb27..68d351b44 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -48,26 +48,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators .Cast() .ToList(); - var allArtists = allSongs.SelectMany(i => i.AllArtists) - .DistinctNames() - .ToList(); + var allArtists = _libraryManager.GetArtists(allSongs).ToList(); var numComplete = 0; var numArtists = allArtists.Count; - foreach (var artist in allArtists) + foreach (var artistItem in allArtists) { cancellationToken.ThrowIfCancellationRequested(); try { - var artistItem = _libraryManager.GetArtist(artist); - await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (IOException ex) { - _logger.ErrorException("Error validating Artist {0}", ex, artist); + _logger.ErrorException("Error validating Artist {0}", ex, artistItem.Name); } // Update progress diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 6861901ac..aa883ce75 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1398,14 +1398,40 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.EpisodeTitle = program.EpisodeTitle; dto.ChannelType = program.ChannelType; dto.Audio = program.Audio; - dto.IsHD = program.IsHD; - dto.IsMovie = program.IsMovie; - dto.IsSeries = program.IsSeries; - dto.IsSports = program.IsSports; - dto.IsLive = program.IsLive; - dto.IsNews = program.IsNews; - dto.IsKids = program.IsKids; - dto.IsPremiere = program.IsPremiere; + + if (program.IsHD.HasValue && program.IsHD.Value) + { + dto.IsHD = program.IsHD; + } + if (program.IsMovie) + { + dto.IsMovie = program.IsMovie; + } + if (program.IsSeries) + { + dto.IsSeries = program.IsSeries; + } + if (program.IsSports) + { + dto.IsSports = program.IsSports; + } + if (program.IsLive) + { + dto.IsLive = program.IsLive; + } + if (program.IsNews) + { + dto.IsNews = program.IsNews; + } + if (program.IsKids) + { + dto.IsKids = program.IsKids; + } + if (program.IsPremiere) + { + dto.IsPremiere = program.IsPremiere; + } + dto.OriginalAirDate = program.OriginalAirDate; if (channel != null) diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 0162b8802..ca2568a0f 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -155,12 +155,6 @@ namespace MediaBrowser.Server.Implementations.UserViews SpecialFolder.MovieMovies, SpecialFolder.MovieResume, - SpecialFolder.GameFavorites, - SpecialFolder.GameGenres, - SpecialFolder.GameSystems, - SpecialFolder.LatestGames, - SpecialFolder.RecentlyPlayedGames, - SpecialFolder.MusicArtists, SpecialFolder.MusicAlbumArtists, SpecialFolder.MusicAlbums, -- cgit v1.2.3 From 3a309db3c53542be3b2d3854b077cfd125f1f435 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 9 Aug 2015 12:35:27 -0400 Subject: update tv --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/VideoHlsService.cs | 2 +- MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 8ee508c4d..0d501066e 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -825,7 +825,7 @@ namespace MediaBrowser.Api.Playback.Hls } else { - var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", + var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", state.SegmentLength.ToString(UsCulture)); var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index dcfafee78..2d1abf7e9 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -100,7 +100,7 @@ namespace MediaBrowser.Api.Playback.Hls args; } - var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", + var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", state.SegmentLength.ToString(UsCulture)); var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 308784299..f34b43e43 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -137,6 +137,8 @@ namespace MediaBrowser.Server.Implementations.TV var lastWatchedDate = DateTime.MinValue; Episode nextUp = null; + var includeMissing = user.Configuration.DisplayMissingEpisodes; + // Go back starting with the most recent episodes foreach (var episode in allEpisodes) { @@ -154,7 +156,7 @@ namespace MediaBrowser.Server.Implementations.TV } else { - if (episode.LocationType != LocationType.Virtual) + if (!episode.IsVirtualUnaired && (!episode.IsMissingEpisode || includeMissing)) { nextUp = episode; } @@ -166,7 +168,7 @@ namespace MediaBrowser.Server.Implementations.TV return new Tuple(nextUp, lastWatchedDate, false); } - var firstEpisode = allEpisodes.LastOrDefault(i => i.LocationType != LocationType.Virtual && !i.IsPlayed(user)); + var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (!i.IsMissingEpisode || includeMissing) && !i.IsPlayed(user)); // Return the first episode return new Tuple(firstEpisode, DateTime.MinValue, true); -- cgit v1.2.3 From 1936d6db43e10cc6f45fa72fde4b1628e06b8abd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 13:37:50 -0400 Subject: update search hints --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 5 + MediaBrowser.Api/SearchService.cs | 9 ++ .../Configuration/BaseApplicationConfiguration.cs | 2 - MediaBrowser.Model/Search/SearchHint.cs | 12 ++ .../Library/Resolvers/TV/SeriesResolver.cs | 10 +- .../LiveTv/Listings/Emby/EmbyListings.cs | 59 +++++++++ .../Listings/Emby/EmbyListingsNorthAmerica.cs | 144 +++++++++++++++++++++ .../LiveTv/Listings/Emby/IEmbyListingProvider.cs | 18 +++ .../MediaBrowser.Server.Implementations.csproj | 3 + .../ApplicationHost.cs | 21 ++- .../MediaBrowser.WebDashboard.csproj | 6 + 11 files changed, 276 insertions(+), 13 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs create mode 100644 MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs create mode 100644 MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index f108b344f..8f5301642 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1748,6 +1748,11 @@ namespace MediaBrowser.Api.Playback return false; } + if (videoStream.IsAnamorphic ?? false) + { + return false; + } + // Can't stream copy if we're burning in subtitles if (request.SubtitleStreamIndex.HasValue) { diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index 9d1aef300..302b8d834 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Search; @@ -171,6 +172,8 @@ namespace MediaBrowser.Api ProductionYear = item.ProductionYear }; + result.ChannelId = item.ChannelId; + var primaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary); if (primaryImageTag != null) @@ -218,6 +221,12 @@ namespace MediaBrowser.Api result.Artists = song.Artists.ToArray(); } + if (!string.IsNullOrWhiteSpace(item.ChannelId)) + { + var channel = _libraryManager.GetItemById(item.ChannelId); + result.ChannelName = channel == null ? null : channel.Name; + } + return result; } diff --git a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs index 1a05f38fa..2b53c6688 100644 --- a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs +++ b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs @@ -63,8 +63,6 @@ namespace MediaBrowser.Model.Configuration { EnableAutoUpdate = true; LogFileRetentionDays = 3; - - EnableDebugLevelLogging = true; } } } diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index 4eced7706..d51c0325d 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -132,5 +132,17 @@ namespace MediaBrowser.Model.Search /// /// The episode count. public int? EpisodeCount { get; set; } + + /// + /// Gets or sets the channel identifier. + /// + /// The channel identifier. + public string ChannelId { get; set; } + + /// + /// Gets or sets the name of the channel. + /// + /// The name of the channel. + public string ChannelName { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index f12022dc7..c5565eb53 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -110,11 +110,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { var attributes = child.Attributes; - if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName); - continue; - } + //if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) + //{ + // //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName); + // continue; + //} // Can't enforce this because files saved by Bitcasa are always marked System //if ((attributes & FileAttributes.System) == FileAttributes.System) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs new file mode 100644 index 000000000..5edebb393 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby +{ + public class EmbyGuide : IListingsProvider + { + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + + public EmbyGuide(IHttpClient httpClient, IJsonSerializer jsonSerializer) + { + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + } + + public string Name + { + get { return "Emby Guide"; } + } + + public string Type + { + get { return "emby"; } + } + + public Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) + { + return GetListingsProvider(info.Country).GetProgramsAsync(info, channelNumber, startDateUtc, endDateUtc, cancellationToken); + } + + public Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) + { + return GetListingsProvider(info.Country).AddMetadata(info, channels, cancellationToken); + } + + public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) + { + return GetListingsProvider(info.Country).Validate(info, validateLogin, validateListings); + } + + public Task> GetLineups(ListingsProviderInfo info, string country, string location) + { + return GetListingsProvider(country).GetLineups(info, country, location); + } + + private IEmbyListingProvider GetListingsProvider(string country) + { + return new EmbyListingsNorthAmerica(_httpClient, _jsonSerializer); + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs new file mode 100644 index 000000000..99bd5325e --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -0,0 +1,144 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby +{ + public class EmbyListingsNorthAmerica : IEmbyListingProvider + { + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + + public EmbyListingsNorthAmerica(IHttpClient httpClient, IJsonSerializer jsonSerializer) + { + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + } + + public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) + { + return new List(); + } + + public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) + { + var response = await GetResponse("https://data.emby.media/service/lineups?id=" + info.ListingsId).ConfigureAwait(false); + + foreach (var channel in channels) + { + + } + } + + public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) + { + return Task.FromResult(true); + } + + public async Task> GetLineups(ListingsProviderInfo info, string country, string location) + { + var response = await GetResponse("https://data.emby.media/service/lineups?id=" + location).ConfigureAwait(false); + + return response.Select(i => new NameIdPair + { + + Name = GetName(i), + Id = i.lineupID + + }).ToList(); + } + + private string GetName(LineupInfo info) + { + var name = info.lineupName; + + if (string.Equals(info.lineupType, "cab", StringComparison.OrdinalIgnoreCase)) + { + name += " - Cable"; + } + else if (string.Equals(info.lineupType, "sat", StringComparison.OrdinalIgnoreCase)) + { + name += " - SAT"; + } + else if (string.Equals(info.lineupType, "ota", StringComparison.OrdinalIgnoreCase)) + { + name += " - OTA"; + } + + return name; + } + + private async Task GetResponse(string url) + where T : class + { + using (var stream = await _httpClient.Get(new HttpRequestOptions + { + Url = url + + }).ConfigureAwait(false)) + { + using (var reader = new StreamReader(stream)) + { + var path = await reader.ReadToEndAsync().ConfigureAwait(false); + + // location = zip code + using (var secondStream = await _httpClient.Get(new HttpRequestOptions + { + Url = "https://data.emby.media" + path + + }).ConfigureAwait(false)) + { + return _jsonSerializer.DeserializeFromStream(secondStream); + } + } + } + } + + private class LineupInfo + { + public string lineupID { get; set; } + public string lineupName { get; set; } + public string lineupType { get; set; } + public string providerID { get; set; } + public string providerName { get; set; } + public string serviceArea { get; set; } + public string country { get; set; } + } + + private class Station + { + public string number { get; set; } + public int channelNumber { get; set; } + public int subChannelNumber { get; set; } + public int stationID { get; set; } + public string name { get; set; } + public string callsign { get; set; } + public string network { get; set; } + public string stationType { get; set; } + public int NTSC_TSID { get; set; } + public int DTV_TSID { get; set; } + public string webLink { get; set; } + public string logoFilename { get; set; } + } + + private class LineupDetailResponse + { + public string lineupID { get; set; } + public string lineupName { get; set; } + public string lineupType { get; set; } + public string providerID { get; set; } + public string providerName { get; set; } + public string serviceArea { get; set; } + public string country { get; set; } + public List stations { get; set; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs new file mode 100644 index 000000000..83477acfc --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs @@ -0,0 +1,18 @@ +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby +{ + public interface IEmbyListingProvider + { + Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); + Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken); + Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); + Task> GetLineups(ListingsProviderInfo info, string country, string location); + } +} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7eddf5ed1..2571f9b2c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -222,6 +222,9 @@ + + + diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index b554e0d1c..60ff36c6d 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -529,7 +529,7 @@ namespace MediaBrowser.Server.Startup.Common var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); await sharingRepo.Initialize().ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); - + RegisterSingleInstance(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this)); var activityLogRepo = await GetActivityLogRepository().ConfigureAwait(false); @@ -1088,15 +1088,24 @@ namespace MediaBrowser.Server.Startup.Common { get { - // Return the first matched address, if found, or the first known local address - var address = LocalIpAddress; + try + { + // Return the first matched address, if found, or the first known local address + var address = LocalIpAddress; - if (!string.IsNullOrWhiteSpace(address)) + if (!string.IsNullOrWhiteSpace(address)) + { + address = GetLocalApiUrl(address); + } + + return address; + } + catch (Exception ex) { - address = GetLocalApiUrl(address); + Logger.ErrorException("Error getting local Ip address information", ex); } - return address; + return null; } } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index a1e232257..e8a2e8673 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -183,6 +183,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -213,6 +216,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 23b88a69bfc7df88372048f448584098f2c9441b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 13:44:57 -0400 Subject: update comment --- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 99bd5325e..4659459d3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -45,11 +45,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public async Task> GetLineups(ListingsProviderInfo info, string country, string location) { + // location = zip code var response = await GetResponse("https://data.emby.media/service/lineups?id=" + location).ConfigureAwait(false); return response.Select(i => new NameIdPair { - Name = GetName(i), Id = i.lineupID @@ -89,7 +89,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby { var path = await reader.ReadToEndAsync().ConfigureAwait(false); - // location = zip code using (var secondStream = await _httpClient.Get(new HttpRequestOptions { Url = "https://data.emby.media" + path -- cgit v1.2.3 From d6dc1826cc8fbffbb03f323d455bb59ffecde74b Mon Sep 17 00:00:00 2001 From: Eric Reed Date: Mon, 10 Aug 2015 14:22:30 -0400 Subject: Lineups retrieval --- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 4659459d3..5a8dd65b9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -45,8 +45,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public async Task> GetLineups(ListingsProviderInfo info, string country, string location) { - // location = zip code - var response = await GetResponse("https://data.emby.media/service/lineups?id=" + location).ConfigureAwait(false); + // location = postal code + var path = await GetResponse("https://data.emby.media/service/lineups?postalCode=" + location).ConfigureAwait(false); + + var response = await GetResponse("https://data.emby.media" + path).ConfigureAwait(false); return response.Select(i => new NameIdPair { -- cgit v1.2.3 From 4f6fb1a76ea3f6f088ce5d524c398b746977dea1 Mon Sep 17 00:00:00 2001 From: Eric Reed Date: Mon, 10 Aug 2015 14:58:12 -0400 Subject: Chg to mb3admin --- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 5a8dd65b9..4713e3074 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby // location = postal code var path = await GetResponse("https://data.emby.media/service/lineups?postalCode=" + location).ConfigureAwait(false); - var response = await GetResponse("https://data.emby.media" + path).ConfigureAwait(false); + var response = await GetResponse("https://www.mb3admin.com" + path).ConfigureAwait(false); return response.Select(i => new NameIdPair { -- cgit v1.2.3 From 1e9292c4543381338df3d0135f326801f0daf2b4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 15:09:10 -0400 Subject: update tv --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 5 +++- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 3 ++- .../LiveTv/Listings/Emby/EmbyListings.cs | 2 +- .../Listings/Emby/EmbyListingsNorthAmerica.cs | 2 +- .../LiveTv/Listings/Emby/IEmbyListingProvider.cs | 2 +- .../LiveTv/LiveTvManager.cs | 28 ++++++++++++++++------ 6 files changed, 30 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index bdec55561..e55103230 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -440,6 +440,9 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "Id", Description = "Provider id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string Id { get; set; } + [ApiMember(Name = "Type", Description = "Provider Type", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string Type { get; set; } + [ApiMember(Name = "Location", Description = "Location", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string Location { get; set; } @@ -535,7 +538,7 @@ namespace MediaBrowser.Api.LiveTv public async Task Get(GetLineups request) { - var info = await _liveTvManager.GetLineups(request.Id, request.Country, request.Location).ConfigureAwait(false); + var info = await _liveTvManager.GetLineups(request.Type, request.Id, request.Country, request.Location).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(info); } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 889875383..e568b2eae 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -357,10 +357,11 @@ namespace MediaBrowser.Controller.LiveTv /// /// Gets the lineups. /// + /// Type of the provider. /// The provider identifier. /// The country. /// The location. /// Task<List<NameIdPair>>. - Task> GetLineups(string providerId, string country, string location); + Task> GetLineups(string providerType, string providerId, string country, string location); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs index 5edebb393..e446ff469 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public Task> GetLineups(ListingsProviderInfo info, string country, string location) { - return GetListingsProvider(country).GetLineups(info, country, location); + return GetListingsProvider(country).GetLineups(country, location); } private IEmbyListingProvider GetListingsProvider(string country) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 4713e3074..6fc6975a8 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby return Task.FromResult(true); } - public async Task> GetLineups(ListingsProviderInfo info, string country, string location) + public async Task> GetLineups(string country, string location) { // location = postal code var path = await GetResponse("https://data.emby.media/service/lineups?postalCode=" + location).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs index 83477acfc..95c22b986 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs @@ -13,6 +13,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken); Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); - Task> GetLineups(ListingsProviderInfo info, string country, string location); + Task> GetLineups(string country, string location); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index aa883ce75..02ca7f0f6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2272,20 +2272,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv return info; } - public Task> GetLineups(string providerId, string country, string location) + public Task> GetLineups(string providerType, string providerId, string country, string location) { var config = GetConfiguration(); - var info = config.ListingProviders.FirstOrDefault(i => string.Equals(i.Id, providerId, StringComparison.OrdinalIgnoreCase)); + if (string.IsNullOrWhiteSpace(providerId)) + { + var provider = _listingProviders.FirstOrDefault(i => string.Equals(providerType, i.Type, StringComparison.OrdinalIgnoreCase)); - var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase)); + if (provider == null) + { + throw new ResourceNotFoundException(); + } - if (provider == null) - { - throw new ResourceNotFoundException(); + return provider.GetLineups(null, country, location); } + else + { + var info = config.ListingProviders.FirstOrDefault(i => string.Equals(i.Id, providerId, StringComparison.OrdinalIgnoreCase)); - return provider.GetLineups(info, country, location); + var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase)); + + if (provider == null) + { + throw new ResourceNotFoundException(); + } + + return provider.GetLineups(info, country, location); + } } } } -- cgit v1.2.3 From f2f917ccee6bbabe155630ff7446c071c3228712 Mon Sep 17 00:00:00 2001 From: Eric Reed Date: Mon, 10 Aug 2015 15:46:09 -0400 Subject: Fix response --- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 6fc6975a8..37025b8e8 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -46,9 +46,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public async Task> GetLineups(string country, string location) { // location = postal code - var path = await GetResponse("https://data.emby.media/service/lineups?postalCode=" + location).ConfigureAwait(false); - - var response = await GetResponse("https://www.mb3admin.com" + path).ConfigureAwait(false); + var response = await GetResponse("https://data.emby.media/service/lineups?postalCode=" + location).ConfigureAwait(false); return response.Select(i => new NameIdPair { @@ -93,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby using (var secondStream = await _httpClient.Get(new HttpRequestOptions { - Url = "https://data.emby.media" + path + Url = "https://www.mb3admin.com" + path }).ConfigureAwait(false)) { -- cgit v1.2.3 From 9216fe821af40cfe5729a15b6adeb56dc4af8cf1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 16:13:42 -0400 Subject: update tv --- .../Listings/Emby/EmbyListingsNorthAmerica.cs | 61 +++++++++++++++++++++- .../LiveTv/Listings/SchedulesDirect.cs | 2 +- 2 files changed, 61 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 37025b8e8..8aa66cf1b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -25,6 +25,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { + var url = "https://data.emby.media/service/listings?id=" + info.ListingsId; + url += "&start=" + startDateUtc.ToString("s", System.Globalization.CultureInfo.InvariantCulture); + url += "&end=" + endDateUtc.ToString("s", System.Globalization.CultureInfo.InvariantCulture); + + var response = await GetResponse(url).ConfigureAwait(false); + return new List(); } @@ -53,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby Name = GetName(i), Id = i.lineupID - }).ToList(); + }).OrderBy(i => i.Name).ToList(); } private string GetName(LineupInfo info) @@ -139,5 +145,58 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public string country { get; set; } public List stations { get; set; } } + + private class ListingInfo + { + public string number { get; set; } + public int channelNumber { get; set; } + public int subChannelNumber { get; set; } + public int stationID { get; set; } + public string name { get; set; } + public string callsign { get; set; } + public string network { get; set; } + public string stationType { get; set; } + public string webLink { get; set; } + public string logoFilename { get; set; } + public int listingID { get; set; } + public string listDateTime { get; set; } + public int duration { get; set; } + public int showID { get; set; } + public int seriesID { get; set; } + public string showName { get; set; } + public string episodeTitle { get; set; } + public string episodeNumber { get; set; } + public int parts { get; set; } + public int partNum { get; set; } + public bool seriesPremiere { get; set; } + public bool seasonPremiere { get; set; } + public bool seriesFinale { get; set; } + public bool seasonFinale { get; set; } + public bool repeat { get; set; } + public bool @new { get; set; } + public string rating { get; set; } + public bool captioned { get; set; } + public bool educational { get; set; } + public bool blackWhite { get; set; } + public bool subtitled { get; set; } + public bool live { get; set; } + public bool hd { get; set; } + public bool descriptiveVideo { get; set; } + public bool inProgress { get; set; } + public string showTypeID { get; set; } + public int breakoutLevel { get; set; } + public string showType { get; set; } + public string year { get; set; } + public string guest { get; set; } + public string cast { get; set; } + public string director { get; set; } + public int starRating { get; set; } + public string description { get; set; } + public string league { get; set; } + public string team1 { get; set; } + public string team2 { get; set; } + public string @event { get; set; } + public string location { get; set; } + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 2aadf4a66..457d1a4f1 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -16,7 +16,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.Listings { - public class SchedulesDirect : IListingsProvider + public class SchedulesDirect { private readonly ILogger _logger; private readonly IJsonSerializer _jsonSerializer; -- cgit v1.2.3 From fe4d3bc57c890a1c1dc33f40acef2495715d83ae Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 16:20:23 -0400 Subject: update tv --- .../Listings/Emby/EmbyListingsNorthAmerica.cs | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 8aa66cf1b..18d0f8c21 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Net; +using System.Globalization; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; @@ -40,7 +41,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby foreach (var channel in channels) { + var station = response.stations.FirstOrDefault(i => + { + var channelNumber = i.channelNumber.ToString(CultureInfo.InvariantCulture); + if (i.subChannelNumber > 0) + { + channelNumber += "." + i.subChannelNumber.ToString(CultureInfo.InvariantCulture); + } + return string.Equals(channelNumber, channel.Number, StringComparison.OrdinalIgnoreCase); + }); + + if (station != null) + { + channel.Name = station.name; + + if (!string.IsNullOrWhiteSpace(station.logoFilename)) + { + channel.HasImage = true; + channel.ImageUrl = "http://cdn.tvpassport.com/image/station/100x100/" + station.logoFilename; + } + } } } -- cgit v1.2.3 From e687f4b3e70c202981b100be60c93d2c2ba27a06 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 20:14:15 -0400 Subject: update components --- .../Listings/Emby/EmbyListingsNorthAmerica.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 18d0f8c21..641505e38 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -1,11 +1,11 @@ -using System.Globalization; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -27,8 +27,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { var url = "https://data.emby.media/service/listings?id=" + info.ListingsId; - url += "&start=" + startDateUtc.ToString("s", System.Globalization.CultureInfo.InvariantCulture); - url += "&end=" + endDateUtc.ToString("s", System.Globalization.CultureInfo.InvariantCulture); + + // Normalize + startDateUtc = startDateUtc.Date; + endDateUtc = startDateUtc.AddDays(7); + + url += "&start=" + startDateUtc.ToString("s", CultureInfo.InvariantCulture) + "Z"; + url += "&end=" + endDateUtc.ToString("s", CultureInfo.InvariantCulture) + "Z"; var response = await GetResponse(url).ConfigureAwait(false); @@ -108,7 +113,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby { using (var stream = await _httpClient.Get(new HttpRequestOptions { - Url = url + Url = url, + CacheLength = TimeSpan.FromDays(1), + CacheMode = CacheMode.Unconditional }).ConfigureAwait(false)) { @@ -118,7 +125,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby using (var secondStream = await _httpClient.Get(new HttpRequestOptions { - Url = "https://www.mb3admin.com" + path + Url = "https://www.mb3admin.com" + path, + CacheLength = TimeSpan.FromDays(1), + CacheMode = CacheMode.Unconditional }).ConfigureAwait(false)) { -- cgit v1.2.3 From 853848966f191c3dc026b77a8214bd22b9f266ce Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Aug 2015 20:40:16 -0400 Subject: update translations --- .../Localization/Core/kk.json | 2 +- .../Localization/Core/nl.json | 60 +++++++++++----------- .../Localization/Core/ru.json | 12 ++--- 3 files changed, 37 insertions(+), 37 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Localization/Core/kk.json b/MediaBrowser.Server.Implementations/Localization/Core/kk.json index 432d90171..f57b9ee12 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/kk.json @@ -128,7 +128,7 @@ "HeaderOverview": "\u0416\u0430\u043b\u043f\u044b \u0448\u043e\u043b\u0443", "HeaderShortOverview": "\u049a\u044b\u0441\u049b\u0430\u0448\u0430 \u0448\u043e\u043b\u0443", "HeaderType": "\u0422\u04af\u0440\u0456", - "HeaderSeverity": "\u0410\u0443\u044b\u0440\u043b\u044b\u0493\u044b", + "HeaderSeverity": "\u049a\u0438\u044b\u043d\u0434\u044b\u0493\u044b", "HeaderUser": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b", "HeaderName": "\u0410\u0442\u044b", "HeaderDate": "\u041a\u04af\u043d\u0456", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/nl.json b/MediaBrowser.Server.Implementations/Localization/Core/nl.json index 32d698779..8658518a4 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/nl.json @@ -37,17 +37,17 @@ "NotificationOptionPluginInstalled": "Plug-in ge\u00efnstalleerd", "NotificationOptionPluginUninstalled": "Plug-in verwijderd", "NotificationOptionVideoPlayback": "Video afspelen gestart", - "NotificationOptionAudioPlayback": "Audio afspelen gestart", + "NotificationOptionAudioPlayback": "Geluid afspelen gestart", "NotificationOptionGamePlayback": "Game gestart", "NotificationOptionVideoPlaybackStopped": "Video afspelen gestopt", - "NotificationOptionAudioPlaybackStopped": "Audio afspelen gestopt", + "NotificationOptionAudioPlaybackStopped": "Geluid afspelen gestopt", "NotificationOptionGamePlaybackStopped": "Afspelen spel gestopt", "NotificationOptionTaskFailed": "Mislukken van de geplande taak", "NotificationOptionInstallationFailed": "Mislukken van de installatie", "NotificationOptionNewLibraryContent": "Nieuwe content toegevoegd", "NotificationOptionNewLibraryContentMultiple": "Nieuwe content toegevoegd (meerdere)", "NotificationOptionCameraImageUploaded": "Camera afbeelding ge\u00fcpload", - "NotificationOptionUserLockedOut": "Gebruiker uitgesloten", + "NotificationOptionUserLockedOut": "Gebruikersaccount vergrendeld", "NotificationOptionServerRestartRequired": "Server herstart nodig", "ViewTypePlaylists": "Afspeellijsten", "ViewTypeMovies": "Films", @@ -115,45 +115,45 @@ "FailedLoginAttemptWithUserName": "Mislukte aanmeld poging van {0}", "AuthenticationSucceededWithUserName": "{0} is succesvol geverifieerd", "DeviceOfflineWithName": "{0} is losgekoppeld", - "UserLockedOutWithName": "Gebruiker {0} is uitgesloten", + "UserLockedOutWithName": "Gebruikersaccount {0} is vergrendeld", "UserOfflineFromDevice": "Verbinding van {0} met {1} is verbroken", "UserStartedPlayingItemWithValues": "{0} heeft afspelen van {1} gestart", "UserStoppedPlayingItemWithValues": "{0} heeft afspelen van {1} gestopt", "SubtitleDownloadFailureForItem": "Downloaden van ondertiteling voor {0} is mislukt", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", + "HeaderUnidentified": "One\u00efdentificaard", + "HeaderImagePrimary": "Primair", + "HeaderImageBackdrop": "Achtergrond", "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image", - "HeaderOverview": "Overview", - "HeaderShortOverview": "Short Overview", + "HeaderUserPrimaryImage": "Afbeelding gebruiker", + "HeaderOverview": "Overzicht", + "HeaderShortOverview": "Kort overzicht", "HeaderType": "Type", - "HeaderSeverity": "Severity", + "HeaderSeverity": "Ernst", "HeaderUser": "Gebruiker", "HeaderName": "Naam", "HeaderDate": "Datum", - "HeaderPremiereDate": "Premiere Date", - "HeaderDateAdded": "Date Added", + "HeaderPremiereDate": "Premi\u00e8re Datum", + "HeaderDateAdded": "Datum toegevoegd", "HeaderReleaseDate": "Uitgave datum", "HeaderRuntime": "Speelduur", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "Afspeel telling", "HeaderSeason": "Seizoen", "HeaderSeasonNumber": "Seizoen nummer", "HeaderSeries": "Series:", "HeaderNetwork": "Zender", - "HeaderYear": "Year:", - "HeaderYears": "Years:", - "HeaderParentalRating": "Parental Rating", + "HeaderYear": "Jaar:", + "HeaderYears": "Jaren:", + "HeaderParentalRating": "Kijkwijzer classificatie", "HeaderCommunityRating": "Gemeenschap cijfer", "HeaderTrailers": "Trailers", "HeaderSpecials": "Specials", - "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderGameSystems": "Spel systemen", + "HeaderPlayers": "Spelers:", + "HeaderAlbumArtists": "Album artiesten", "HeaderAlbums": "Albums", "HeaderDisc": "Schijf", "HeaderTrack": "Track", - "HeaderAudio": "Audio", + "HeaderAudio": "Geluid", "HeaderVideo": "Video", "HeaderEmbeddedImage": "Ingesloten afbeelding", "HeaderResolution": "Resolutie", @@ -162,15 +162,15 @@ "HeaderCountries": "Landen", "HeaderStatus": "Status", "HeaderTracks": "Tracks", - "HeaderMusicArtist": "Music artist", - "HeaderLocked": "Locked", + "HeaderMusicArtist": "Muziek artiest", + "HeaderLocked": "Vergrendeld", "HeaderStudios": "Studio's", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "Acteurs", + "HeaderComposer": "Componisten", + "HeaderDirector": "Regiseurs", + "HeaderGuestStar": "Gast ster", + "HeaderProducer": "Producenten", + "HeaderWriter": "Schrijvers", "HeaderParentalRatings": "Ouderlijke toezicht", - "HeaderCommunityRatings": "Community ratings" + "HeaderCommunityRatings": "Gemeenschapswaardering" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ru.json b/MediaBrowser.Server.Implementations/Localization/Core/ru.json index 56af637df..6a8bae45a 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ru.json @@ -83,11 +83,11 @@ "ViewTypeMusicAlbums": "\u0410\u043b\u044c\u0431\u043e\u043c\u044b", "ViewTypeMusicAlbumArtists": "\u0410\u043b\u044c\u0431\u043e\u043c\u043d\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438", "HeaderOtherDisplaySettings": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f", - "ViewTypeMusicSongs": "\u041c\u0435\u043b\u043e\u0434\u0438\u0438", + "ViewTypeMusicSongs": "\u041a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438", "ViewTypeMusicFavorites": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435", "ViewTypeMusicFavoriteAlbums": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0430\u043b\u044c\u0431\u043e\u043c\u044b", "ViewTypeMusicFavoriteArtists": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438", - "ViewTypeMusicFavoriteSongs": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u043b\u043e\u0434\u0438\u0438", + "ViewTypeMusicFavoriteSongs": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438", "ViewTypeFolders": "\u041f\u0430\u043f\u043a\u0438", "ViewTypeLiveTvRecordingGroups": "\u0417\u0430\u043f\u0438\u0441\u0438", "ViewTypeLiveTvChannels": "\u041a\u0430\u043d\u0430\u043b\u044b", @@ -125,10 +125,10 @@ "HeaderImageBackdrop": "\u0417\u0430\u0434\u043d\u0438\u043a", "HeaderImageLogo": "\u041b\u043e\u0433\u043e\u0442\u0438\u043f", "HeaderUserPrimaryImage": "\u0420\u0438\u0441\u0443\u043d\u043e\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", - "HeaderOverview": "\u041e\u0431\u0437\u043e\u0440", - "HeaderShortOverview": "\u041a\u0440\u0430\u0442\u043a\u0438\u0439 \u043e\u0431\u0437\u043e\u0440", + "HeaderOverview": "\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435", + "HeaderShortOverview": "\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435", "HeaderType": "\u0422\u0438\u043f", - "HeaderSeverity": "\u0421\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u044c", + "HeaderSeverity": "\u0412\u0430\u0436\u043d\u043e\u0441\u0442\u044c", "HeaderUser": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c", "HeaderName": "\u0418\u043c\u044f (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435)", "HeaderDate": "\u0414\u0430\u0442\u0430", @@ -136,7 +136,7 @@ "HeaderDateAdded": "\u0414\u0430\u0442\u0430 \u0434\u043e\u0431-\u0438\u044f", "HeaderReleaseDate": "\u0414\u0430\u0442\u0430 \u0432\u044b\u043f.", "HeaderRuntime": "\u0414\u043b\u0438\u0442.", - "HeaderPlayCount": "\u041a\u043e\u043b-\u0432\u043e \u0432\u043e\u0441\u043f\u0440-\u0438\u0439", + "HeaderPlayCount": "\u0427\u0438\u0441\u043b\u043e \u0432\u043e\u0441\u043f\u0440-\u0438\u0439", "HeaderSeason": "\u0421\u0435\u0437\u043e\u043d", "HeaderSeasonNumber": "\u041d\u043e\u043c\u0435\u0440 \u0441\u0435\u0437\u043e\u043d\u0430", "HeaderSeries": "\u0421\u0435\u0440\u0438\u0430\u043b:", -- cgit v1.2.3 From 881fcf2434bc8833c45f4028e5bfa2ad113a9d18 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 11 Aug 2015 13:47:29 -0400 Subject: update components --- MediaBrowser.Controller/LiveTv/ProgramInfo.cs | 17 ++- MediaBrowser.Controller/LiveTv/RecordingInfo.cs | 6 +- MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs | 6 + .../LiveTv/EmbyTV/EmbyTV.cs | 21 +++- .../Listings/Emby/EmbyListingsNorthAmerica.cs | 133 ++++++++++++++++++++- .../LiveTv/LiveTvManager.cs | 1 + 6 files changed, 170 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index 36f082b02..3f8fc639f 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -150,7 +150,22 @@ namespace MediaBrowser.Controller.LiveTv /// /// The production year. public int? ProductionYear { get; set; } - + /// + /// Gets or sets the home page URL. + /// + /// The home page URL. + public string HomePageUrl { get; set; } + /// + /// Gets or sets the series identifier. + /// + /// The series identifier. + public string SeriesId { get; set; } + /// + /// Gets or sets the show identifier. + /// + /// The show identifier. + public string ShowId { get; set; } + public ProgramInfo() { Genres = new List(); diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index e5817d390..42064cf50 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -185,7 +185,11 @@ namespace MediaBrowser.Controller.LiveTv /// /// null if [has image] contains no value, true if [has image]; otherwise, false. public bool? HasImage { get; set; } - + /// + /// Gets or sets the show identifier. + /// + /// The show identifier. + public string ShowId { get; set; } public RecordingInfo() { diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs index 1be6549ff..2d79473f0 100644 --- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs @@ -94,6 +94,12 @@ namespace MediaBrowser.Controller.LiveTv /// /// true if this instance is post padding required; otherwise, false. public bool IsPostPaddingRequired { get; set; } + + /// + /// Gets or sets the series identifier. + /// + /// The series identifier. + public string SeriesId { get; set; } public SeriesTimerInfo() { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c90b9eacb..cf294997b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -295,6 +295,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV RecordAnyTime = false, RecordNewOnly = false }; + + if (program != null) + { + defaults.SeriesId = program.SeriesId; + defaults.ProgramId = program.Id; + } + return Task.FromResult(defaults); } @@ -515,8 +522,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV OriginalAirDate = info.OriginalAirDate, Status = RecordingStatus.Scheduled, Overview = info.Overview, - SeriesTimerId = info.Id.Substring(0, 10), - TimerId = timer.Id + SeriesTimerId = timer.SeriesTimerId, + TimerId = timer.Id, + ShowId = info.ShowId }; _recordingProvider.Add(recording); } @@ -624,7 +632,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { allPrograms = GetProgramsForSeries(seriesTimer, allPrograms); - allPrograms = allPrograms.Where(epg => currentRecordings.All(r => r.ProgramId.Substring(0, 14) != epg.Id.Substring(0, 14))); //filtered recordings already running + var recordingShowIds = currentRecordings.Select(i => i.ShowId).ToList(); + + allPrograms = allPrograms.Where(epg => !recordingShowIds.Contains(epg.ShowId, StringComparer.OrdinalIgnoreCase)); return allPrograms.Select(i => RecordingHelper.CreateTimer(i, seriesTimer)); } @@ -638,7 +648,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (seriesTimer.RecordNewOnly) { - allPrograms = allPrograms.Where(epg => !epg.IsRepeat); //Filtered by New only + allPrograms = allPrograms.Where(epg => !epg.IsRepeat); } if (!seriesTimer.RecordAnyChannel) @@ -648,8 +658,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV allPrograms = allPrograms.Where(epg => seriesTimer.Days.Contains(epg.StartDate.DayOfWeek)); - // TODO: This assumption will require review once additional listing providers are added - return allPrograms.Where(epg => epg.Id.StartsWith(seriesTimer.ProgramId, StringComparison.OrdinalIgnoreCase)); + return allPrograms.Where(epg => string.Equals(epg.SeriesId, seriesTimer.SeriesId, StringComparison.OrdinalIgnoreCase)); } private string GetChannelEpgCachePath(string channelId) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 641505e38..6c1cc5506 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -26,6 +26,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { + channelNumber = NormalizeNumber(channelNumber); + var url = "https://data.emby.media/service/listings?id=" + info.ListingsId; // Normalize @@ -36,8 +38,100 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby url += "&end=" + endDateUtc.ToString("s", CultureInfo.InvariantCulture) + "Z"; var response = await GetResponse(url).ConfigureAwait(false); - - return new List(); + + return response.Where(i => IncludeInResults(i, channelNumber)).Select(GetProgramInfo); + } + + private ProgramInfo GetProgramInfo(ListingInfo info) + { + var showType = info.showType ?? string.Empty; + + var program = new ProgramInfo + { + Id = info.listingID.ToString(CultureInfo.InvariantCulture), + Name = GetStringValue(info.showName), + EpisodeTitle = GetStringValue(info.episodeTitle), + HomePageUrl = GetStringValue(info.webLink), + Overview = info.description, + IsHD = info.hd, + IsLive = info.live, + IsPremiere = info.seasonPremiere || info.seriesPremiere, + IsMovie = showType.IndexOf("Movie", StringComparison.OrdinalIgnoreCase) != -1, + IsKids = showType.IndexOf("Children", StringComparison.OrdinalIgnoreCase) != -1, + IsNews = showType.IndexOf("News", StringComparison.OrdinalIgnoreCase) != -1, + IsSports = showType.IndexOf("Sports", StringComparison.OrdinalIgnoreCase) != -1 + }; + + if (!string.IsNullOrWhiteSpace(info.listDateTime)) + { + program.StartDate = DateTime.ParseExact(info.listDateTime, "yyyy'-'MM'-'dd' 'HH':'mm':'ss", CultureInfo.InvariantCulture); + program.EndDate = program.StartDate.AddMinutes(info.duration); + } + + if (info.starRating > 0) + { + program.CommunityRating = info.starRating*2; + } + + if (!string.IsNullOrWhiteSpace(info.rating)) + { + // They don't have dashes so try to normalize + program.OfficialRating = info.rating.Replace("TV", "TV-").Replace("--", "-"); + } + + if (!string.IsNullOrWhiteSpace(info.year)) + { + program.ProductionYear = int.Parse(info.year, CultureInfo.InvariantCulture); + } + + if (info.showID > 0) + { + program.ShowId = info.showID.ToString(CultureInfo.InvariantCulture); + } + + if (info.seriesID > 0) + { + program.SeriesId = info.seriesID.ToString(CultureInfo.InvariantCulture); + program.IsSeries = true; + program.IsRepeat = info.repeat; + } + + if (info.starRating > 0) + { + program.CommunityRating = info.starRating * 2; + } + + if (string.Equals(info.showName, "Movie", StringComparison.OrdinalIgnoreCase)) + { + // Sometimes the movie title will be in here + if (!string.IsNullOrWhiteSpace(info.episodeTitle)) + { + program.Name = info.episodeTitle; + } + } + + return program; + } + + private string GetStringValue(string s) + { + return string.IsNullOrWhiteSpace(s) ? null : s; + } + + private bool IncludeInResults(ListingInfo info, string itemNumber) + { + if (string.Equals(itemNumber, NormalizeNumber(info.number), StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + var channelNumber = info.channelNumber.ToString(CultureInfo.InvariantCulture); + if (info.subChannelNumber > 0) + { + channelNumber += "." + info.subChannelNumber.ToString(CultureInfo.InvariantCulture); + } + + return string.Equals(channelNumber, itemNumber, StringComparison.OrdinalIgnoreCase); } public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) @@ -48,18 +142,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby { var station = response.stations.FirstOrDefault(i => { + var itemNumber = NormalizeNumber(channel.Number); + + if (string.Equals(itemNumber, NormalizeNumber(i.number), StringComparison.OrdinalIgnoreCase)) + { + return true; + } + var channelNumber = i.channelNumber.ToString(CultureInfo.InvariantCulture); if (i.subChannelNumber > 0) { channelNumber += "." + i.subChannelNumber.ToString(CultureInfo.InvariantCulture); } - return string.Equals(channelNumber, channel.Number, StringComparison.OrdinalIgnoreCase); + return string.Equals(channelNumber, itemNumber, StringComparison.OrdinalIgnoreCase); }); if (station != null) { - channel.Name = station.name; + //channel.Name = station.name; if (!string.IsNullOrWhiteSpace(station.logoFilename)) { @@ -70,6 +171,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby } } + private string NormalizeNumber(string number) + { + return number.Replace('-', '.'); + } + public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) { return Task.FromResult(true); @@ -108,7 +214,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby return name; } - private async Task GetResponse(string url) + private async Task GetResponse(string url, Func filter = null) where T : class { using (var stream = await _httpClient.Get(new HttpRequestOptions @@ -131,12 +237,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby }).ConfigureAwait(false)) { - return _jsonSerializer.DeserializeFromStream(secondStream); + return ParseResponse(secondStream, filter); } } } } + private T ParseResponse(Stream response, Func filter) + { + using (var reader = new StreamReader(response)) + { + var json = reader.ReadToEnd(); + + if (filter != null) + { + json = filter(json); + } + + return _jsonSerializer.DeserializeFromString(json); + } + } + private class LineupInfo { public string lineupID { get; set; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 02ca7f0f6..331f42185 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -622,6 +622,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProviderImageUrl = info.ImageUrl; item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks; item.StartDate = info.StartDate; + item.HomePageUrl = info.HomePageUrl; item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; -- cgit v1.2.3 From 3b4be8f8be96fd79d428a0ac428928602b8c362b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 11 Aug 2015 14:39:12 -0400 Subject: update dates --- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 6c1cc5506..103d9ec42 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -65,6 +65,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby if (!string.IsNullOrWhiteSpace(info.listDateTime)) { program.StartDate = DateTime.ParseExact(info.listDateTime, "yyyy'-'MM'-'dd' 'HH':'mm':'ss", CultureInfo.InvariantCulture); + program.StartDate = DateTime.SpecifyKind(program.StartDate, DateTimeKind.Utc); program.EndDate = program.StartDate.AddMinutes(info.duration); } -- cgit v1.2.3 From a5ef7589170efb465bd183741e3d42bca297a314 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 11 Aug 2015 14:50:27 -0400 Subject: update date --- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index 103d9ec42..fca1bb012 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby var response = await GetResponse(url).ConfigureAwait(false); - return response.Where(i => IncludeInResults(i, channelNumber)).Select(GetProgramInfo); + return response.Where(i => IncludeInResults(i, channelNumber)).Select(GetProgramInfo).OrderBy(i => i.StartDate); } private ProgramInfo GetProgramInfo(ListingInfo info) -- cgit v1.2.3 From da837ffbf040051f7c73b407331c5d0f9e9dce90 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 12 Aug 2015 17:39:02 -0400 Subject: update translations --- MediaBrowser.Server.Implementations/Channels/ChannelManager.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 3 +++ MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index 179eb5629..fbecaa65d 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -914,7 +914,7 @@ namespace MediaBrowser.Server.Implementations.Channels if (query.Limit.HasValue && query.Limit.Value > channelInfo.MaxPageSize.Value) { - throw new ArgumentException(string.Format("{0} channel only supports a maximum of {1} records at a time.", channel.Name, channelInfo.MaxPageSize.Value)); + query.Limit = Math.Min(query.Limit.Value, channelInfo.MaxPageSize.Value); } providerLimit = query.Limit; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 331f42185..389eda904 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -20,6 +20,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; +using MoreLinq; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -878,8 +879,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv var programList = programs.ToList(); var genres = programList.SelectMany(i => i.Genres) + .Where(i => !string.IsNullOrWhiteSpace(i)) .DistinctNames() .Select(i => _libraryManager.GetGenre(i)) + .DistinctBy(i => i.Id) .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase); programs = programList.OrderBy(i => i.HasImage(ImageType.Primary) ? 0 : 1) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index e8a2e8673..2b90ae52a 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -138,6 +138,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -225,9 +228,15 @@ PreserveNewest + + PreserveNewest + PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 6ed2a85f45c4b59b4fe6ee1c93b81aa76a69fc78 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 10:42:40 -0400 Subject: update polymer --- MediaBrowser.Api/Sync/SyncHelper.cs | 6 ------ .../LiveTv/Listings/SchedulesDirect.cs | 6 ++++-- MediaBrowser.Server.Implementations/Sync/SyncManager.cs | 17 +++++++++-------- 3 files changed, 13 insertions(+), 16 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs index 6a5b6a927..0d3e8707d 100644 --- a/MediaBrowser.Api/Sync/SyncHelper.cs +++ b/MediaBrowser.Api/Sync/SyncHelper.cs @@ -10,11 +10,6 @@ namespace MediaBrowser.Api.Sync { List options = new List(); - if (items.Count > 1) - { - options.Add(SyncJobOption.Name); - } - foreach (BaseItemDto item in items) { if (item.SupportsSync ?? false) @@ -65,7 +60,6 @@ namespace MediaBrowser.Api.Sync { List options = new List(); - options.Add(SyncJobOption.Name); options.Add(SyncJobOption.Quality); options.Add(SyncJobOption.Profile); options.Add(SyncJobOption.UnwatchedOnly); diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 457d1a4f1..b0edfc46b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -337,6 +337,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings (details.showType ?? "No ShowType") == "TV Movie" || (details.showType ?? "No ShowType") == "Short Film", IsPremiere = false, + ShowId = programInfo.programID }; if (!string.IsNullOrWhiteSpace(details.originalAirDate)) @@ -448,8 +449,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings _logger.Info("Headend: " + headend.headend); foreach (ScheduleDirect.Lineup lineup in headend.lineups) { - _logger.Info("Headend: " + lineup.uri.Substring(18)); - lineups.Add(new NameIdPair() + _logger.Info("Headend: " + lineup.uri); + + lineups.Add(new NameIdPair { Name = string.IsNullOrWhiteSpace(lineup.name) ? lineup.lineup : lineup.name, Id = lineup.uri.Substring(18) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 6c71a90a0..36f8984dd 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -52,8 +52,8 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly IConfigurationManager _config; private readonly IUserDataManager _userDataManager; private readonly Func _mediaSourceManager; - private readonly IJsonSerializer _json; - private readonly ITaskManager _taskManager; + private readonly IJsonSerializer _json; + private readonly ITaskManager _taskManager; private ISyncProvider[] _providers = { }; @@ -63,7 +63,7 @@ namespace MediaBrowser.Server.Implementations.Sync public event EventHandler> SyncJobItemUpdated; public event EventHandler> SyncJobItemCreated; - public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func mediaSourceManager, IJsonSerializer json, ITaskManager taskManager) + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func mediaSourceManager, IJsonSerializer json, ITaskManager taskManager) { _libraryManager = libraryManager; _repo = repo; @@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Sync _userDataManager = userDataManager; _mediaSourceManager = mediaSourceManager; _json = json; - _taskManager = taskManager; + _taskManager = taskManager; } public void AddParts(IEnumerable providers) @@ -126,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (string.IsNullOrWhiteSpace(request.Name)) { - throw new ArgumentException("Please supply a name for the sync job."); + request.Name = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString(); } var target = GetSyncTargets(request.UserId) @@ -217,9 +217,10 @@ namespace MediaBrowser.Server.Implementations.Sync }, _logger); } - if (returnResult.JobItems.Any (i => i.Status == SyncJobItemStatus.Queued || i.Status == SyncJobItemStatus.Converting)) { - _taskManager.QueueScheduledTask (); - } + if (returnResult.JobItems.Any(i => i.Status == SyncJobItemStatus.Queued || i.Status == SyncJobItemStatus.Converting)) + { + _taskManager.QueueScheduledTask(); + } return returnResult; } -- cgit v1.2.3 From ec5619e0f960a2abc2226f81fcfcb82ae9fc295a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 13:24:07 -0400 Subject: restore polymer changes --- Emby.Drawing/ImageProcessor.cs | 2 +- MediaBrowser.Controller/Entities/UserView.cs | 6 ++-- .../Dto/DtoService.cs | 2 +- .../Library/LibraryManager.cs | 3 +- .../Photos/BaseDynamicImageProvider.cs | 25 +++++++-------- .../UserViews/CollectionFolderImageProvider.cs | 2 +- .../UserViews/DynamicImageProvider.cs | 37 ++-------------------- 7 files changed, 19 insertions(+), 58 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index e6aaaa797..970b463cd 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -422,7 +422,7 @@ namespace Emby.Drawing { throw; } - _logger.Info("Failed to read image header for {0}. Doing it the slow way.", path); + //_logger.Info("Failed to read image header for {0}. Doing it the slow way.", path); CheckDisposed(); diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index dad6de01a..ce4de613e 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -1,10 +1,10 @@ -using System.Runtime.Serialization; -using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; +using System.Runtime.Serialization; using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities @@ -14,8 +14,6 @@ namespace MediaBrowser.Controller.Entities public string ViewType { get; set; } public Guid ParentId { get; set; } - public Guid? UserId { get; set; } - public static ITVSeriesManager TVSeriesManager; public static IPlaylistManager PlaylistManager; diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 2ff9a2813..1dbdf90a7 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1769,7 +1769,7 @@ namespace MediaBrowser.Server.Implementations.Dto } catch (Exception ex) { - _logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); + //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); return; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index c9a5cb731..dfcc1370e 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1773,8 +1773,7 @@ namespace MediaBrowser.Server.Implementations.Library DateCreated = DateTime.UtcNow, Name = name, ViewType = viewType, - ForcedSortName = sortName, - UserId = user.Id + ForcedSortName = sortName }; if (!string.IsNullOrWhiteSpace(parentId)) diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index 642753fa6..4b7e1c3a7 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -116,9 +116,9 @@ namespace MediaBrowser.Server.Implementations.Photos return parts.GetMD5().ToString("N"); } - protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) + protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath) { - return CreateCollage(primaryItem, items, outputPath, 640, 360, drawText, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 640, 360); } protected virtual IEnumerable GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable items) @@ -130,20 +130,20 @@ namespace MediaBrowser.Server.Implementations.Photos protected Task CreatePosterCollage(IHasImages primaryItem, List items, string outputPath) { - return CreateCollage(primaryItem, items, outputPath, 400, 600, true, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 400, 600); } - protected Task CreateSquareCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) + protected Task CreateSquareCollage(IHasImages primaryItem, List items, string outputPath) { - return CreateCollage(primaryItem, items, outputPath, 600, 600, drawText, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 600, 600); } - protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) + protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height) { - return CreateCollage(primaryItem, items, outputPath, width, height, drawText, text); + return CreateCollage(primaryItem, items, outputPath, width, height); } - private Task CreateCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) + private Task CreateCollage(IHasImages primaryItem, List items, string outputPath, int width, int height) { Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); @@ -152,7 +152,6 @@ namespace MediaBrowser.Server.Implementations.Photos Height = height, Width = width, OutputPath = outputPath, - Text = drawText ? text : null, InputPaths = GetStripCollageImagePaths(primaryItem, items).ToArray() }; @@ -181,22 +180,20 @@ namespace MediaBrowser.Server.Implementations.Photos return false; } - var drawText = !(item is UserView) && !(item is ICollectionFolder); - if (imageType == ImageType.Thumb) { - return await CreateThumbCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false); + return await CreateThumbCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } if (imageType == ImageType.Primary) { if (item is UserView) { - return await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false); + return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } if (item is PhotoAlbum || item is Playlist) { - return await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false); + return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } return await CreatePosterCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs index 39dbcf226..7054515b6 100644 --- a/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Server.Implementations.UserViews return false; } - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name).ConfigureAwait(false); + return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); } return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index ca2568a0f..7fbd2b26c 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -61,7 +61,6 @@ namespace MediaBrowser.Server.Implementations.UserViews { var userItemsResult = await view.GetItems(new InternalItemsQuery { - User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, CollapseBoxSetItems = false }); @@ -73,7 +72,6 @@ namespace MediaBrowser.Server.Implementations.UserViews var result = await view.GetItems(new InternalItemsQuery { - User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, CollapseBoxSetItems = false, Recursive = recursive, ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Playlist" } @@ -138,38 +136,7 @@ namespace MediaBrowser.Server.Implementations.UserViews var view = item as UserView; if (view != null) { - var supported = new[] - { - SpecialFolder.TvFavoriteEpisodes, - SpecialFolder.TvFavoriteSeries, - SpecialFolder.TvGenres, - SpecialFolder.TvLatest, - SpecialFolder.TvNextUp, - SpecialFolder.TvResume, - SpecialFolder.TvShowSeries, - - SpecialFolder.MovieCollections, - SpecialFolder.MovieFavorites, - SpecialFolder.MovieGenres, - SpecialFolder.MovieLatest, - SpecialFolder.MovieMovies, - SpecialFolder.MovieResume, - - SpecialFolder.MusicArtists, - SpecialFolder.MusicAlbumArtists, - SpecialFolder.MusicAlbums, - SpecialFolder.MusicGenres, - SpecialFolder.MusicLatest, - SpecialFolder.MusicPlaylists, - SpecialFolder.MusicSongs, - SpecialFolder.MusicFavorites, - SpecialFolder.MusicFavoriteArtists, - SpecialFolder.MusicFavoriteAlbums, - SpecialFolder.MusicFavoriteSongs - - }; - - return (IsUsingCollectionStrip(view) || supported.Contains(view.ViewType, StringComparer.OrdinalIgnoreCase)); + return (IsUsingCollectionStrip(view)); } return false; @@ -207,7 +174,7 @@ namespace MediaBrowser.Server.Implementations.UserViews return false; } - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name).ConfigureAwait(false); + return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); } return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); -- cgit v1.2.3 From 032891c9f3327ca626938ca175d7d4623e6a27d0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 14:00:26 -0400 Subject: update user views --- .../Entities/UserViewBuilder.cs | 86 ++++++++++------------ MediaBrowser.Controller/Library/ILibraryManager.cs | 32 +++++++- .../Library/IUserViewManager.cs | 5 +- .../Channels/ChannelManager.cs | 3 +- .../Library/LibraryManager.cs | 83 ++++++++++++++++++++- .../Library/UserViewManager.cs | 12 +-- .../LiveTv/LiveTvManager.cs | 3 +- 7 files changed, 161 insertions(+), 63 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index ba2820bc1..cee5dadd2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -285,14 +285,14 @@ namespace MediaBrowser.Controller.Entities var list = new List(); - list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicPlaylists, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicLatest, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicPlaylists, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicAlbums, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, "3", parent).ConfigureAwait(false)); //list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "5", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "6", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "7", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicSongs, "5", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicGenres, "6", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavorites, "7", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -301,9 +301,9 @@ namespace MediaBrowser.Controller.Entities { var list = new List(); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, user, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, "2", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -329,7 +329,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -366,7 +366,7 @@ namespace MediaBrowser.Controller.Entities .OfType(); var artists = _libraryManager.GetArtists(items); - + return GetResult(artists, parent, query); } @@ -377,7 +377,7 @@ namespace MediaBrowser.Controller.Entities .OfType(); var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); - + return GetResult(artists, parent, query); } @@ -443,12 +443,12 @@ namespace MediaBrowser.Controller.Entities var list = new List(); - list.Add(await GetUserView(SpecialFolder.MovieResume, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieLatest, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieMovies, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieCollections, user, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieFavorites, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieGenres, user, "5", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieResume, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieLatest, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieMovies, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieCollections, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieFavorites, "4", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieGenres, "5", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -554,7 +554,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -616,13 +616,13 @@ namespace MediaBrowser.Controller.Entities var list = new List(); - list.Add(await GetUserView(SpecialFolder.TvResume, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvNextUp, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvLatest, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvShowSeries, user, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, user, "5", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvGenres, user, "6", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvResume, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvNextUp, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvLatest, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvShowSeries, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, "4", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, "5", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvGenres, "6", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -637,11 +637,11 @@ namespace MediaBrowser.Controller.Entities var list = new List(); - list.Add(await GetUserView(SpecialFolder.LatestGames, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameFavorites, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameSystems, user, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameGenres, user, "4", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.LatestGames, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.GameFavorites, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.GameSystems, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.GameGenres, "4", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -739,7 +739,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -791,7 +791,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1871,26 +1871,20 @@ namespace MediaBrowser.Controller.Entities var list = new List(); //list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, user.RootFolder).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, user.RootFolder).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.LiveTvChannels, string.Empty, user.RootFolder).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, string.Empty, user.RootFolder).ConfigureAwait(false)); return GetResult(list, queryParent, query); } - private async Task GetUserView(string name, string type, User user, string sortName, BaseItem parent) + private Task GetUserView(string name, string type, string sortName, BaseItem parent) { - var view = await _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, user, sortName, CancellationToken.None) - .ConfigureAwait(false); - - return view; + return _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, sortName, CancellationToken.None); } - private async Task GetUserView(string type, User user, string sortName, BaseItem parent) + private Task GetUserView(string type, string sortName, BaseItem parent) { - var view = await _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, user, sortName, CancellationToken.None) - .ConfigureAwait(false); - - return view; + return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None); } public static bool IsYearMismatched(BaseItem item, ILibraryManager libraryManager) diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 9c52fd2dc..6906a25fb 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -351,7 +351,37 @@ namespace MediaBrowser.Controller.Library Task GetNamedView(User user, string name, string viewType, - string sortName, + string sortName, + CancellationToken cancellationToken); + + /// + /// Gets the named view. + /// + /// The name. + /// Type of the view. + /// Name of the sort. + /// The cancellation token. + /// Task<UserView>. + Task GetNamedView(string name, + string viewType, + string sortName, + CancellationToken cancellationToken); + + /// + /// Gets the named view. + /// + /// The name. + /// The parent identifier. + /// Type of the view. + /// Name of the sort. + /// The unique identifier. + /// The cancellation token. + /// Task<UserView>. + Task GetNamedView(string name, + string parentId, + string viewType, + string sortName, + string uniqueId, CancellationToken cancellationToken); /// diff --git a/MediaBrowser.Controller/Library/IUserViewManager.cs b/MediaBrowser.Controller/Library/IUserViewManager.cs index f0b862c2d..5391d113e 100644 --- a/MediaBrowser.Controller/Library/IUserViewManager.cs +++ b/MediaBrowser.Controller/Library/IUserViewManager.cs @@ -12,10 +12,9 @@ namespace MediaBrowser.Controller.Library { Task> GetUserViews(UserViewQuery query, CancellationToken cancellationToken); - Task GetUserSubView(string name, string parentId, string type, User user, string sortName, - CancellationToken cancellationToken); + Task GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken); - Task GetUserSubView(string category, string type, User user, string sortName, CancellationToken cancellationToken); + Task GetUserSubView(string category, string type, string sortName, CancellationToken cancellationToken); List>> GetLatestItems(LatestItemsQuery request); } diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index fbecaa65d..cbbed856c 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1407,9 +1407,8 @@ namespace MediaBrowser.Server.Implementations.Channels public async Task GetInternalChannelFolder(string userId, CancellationToken cancellationToken) { var name = _localization.GetLocalizedString("ViewTypeChannels"); - var user = _userManager.GetUserById(userId); - return await _libraryManager.GetNamedView(user, name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false); + return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false); } public async Task DownloadChannelItem(IChannelMediaItem item, string destination, diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index dfcc1370e..1d2e5e322 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1651,7 +1651,7 @@ namespace MediaBrowser.Server.Implementations.Library private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); - public async Task GetNamedView(User user, + public Task GetNamedView(User user, string name, string viewType, string sortName, @@ -1659,10 +1659,17 @@ namespace MediaBrowser.Server.Implementations.Library { if (ConfigurationManager.Configuration.EnableUserSpecificUserViews) { - return await GetNamedViewInternal(user, name, null, viewType, sortName, null, cancellationToken) - .ConfigureAwait(false); + return GetNamedViewInternal(user, name, null, viewType, sortName, null, cancellationToken); } + return GetNamedView(name, viewType, sortName, cancellationToken); + } + + public async Task GetNamedView(string name, + string viewType, + string sortName, + CancellationToken cancellationToken) + { var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "views"); @@ -1806,6 +1813,76 @@ namespace MediaBrowser.Server.Implementations.Library return item; } + public async Task GetNamedView(string name, + string parentId, + string viewType, + string sortName, + string uniqueId, + CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException("name"); + } + + var idValues = "37_namedview_" + name + (parentId ?? string.Empty); + if (!string.IsNullOrWhiteSpace(uniqueId)) + { + idValues += uniqueId; + } + + var id = GetNewItemId(idValues, typeof(UserView)); + + var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N")); + + var item = GetItemById(id) as UserView; + + var isNew = false; + + if (item == null) + { + Directory.CreateDirectory(path); + + item = new UserView + { + Path = path, + Id = id, + DateCreated = DateTime.UtcNow, + Name = name, + ViewType = viewType, + ForcedSortName = sortName + }; + + if (!string.IsNullOrWhiteSpace(parentId)) + { + item.ParentId = new Guid(parentId); + } + + await CreateItem(item, cancellationToken).ConfigureAwait(false); + + isNew = true; + } + + if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase)) + { + item.ViewType = viewType; + await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); + } + + var refresh = isNew || (DateTime.UtcNow - item.DateLastSaved) >= _viewRefreshInterval; + + if (refresh) + { + _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions + { + // Need to force save to increment DateLastSaved + ForceSave = true + }); + } + + return item; + } + public bool IsVideoFile(string path) { var resolver = new VideoResolver(GetNamingOptions(), new PatternsLogger()); diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 61b28a072..c32dc0d41 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -167,8 +167,8 @@ namespace MediaBrowser.Server.Implementations.Library if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId)) { - //list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false)); - list.Add(await GetUserView(new List(), list, CollectionType.LiveTv, string.Empty, user, cancellationToken).ConfigureAwait(false)); + var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.LiveTv); + list.Add(await _libraryManager.GetNamedView(name, CollectionType.LiveTv, string.Empty, cancellationToken).ConfigureAwait(false)); } } @@ -187,18 +187,18 @@ namespace MediaBrowser.Server.Implementations.Library .ThenBy(i => i.SortName); } - public Task GetUserSubView(string name, string parentId, string type, User user, string sortName, CancellationToken cancellationToken) + public Task GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken) { var uniqueId = parentId + "subview" + type; - return _libraryManager.GetNamedView(user, name, parentId, type, sortName, uniqueId, cancellationToken); + return _libraryManager.GetNamedView(name, parentId, type, sortName, uniqueId, cancellationToken); } - public Task GetUserSubView(string parentId, string type, User user, string sortName, CancellationToken cancellationToken) + public Task GetUserSubView(string parentId, string type, string sortName, CancellationToken cancellationToken) { var name = _localizationManager.GetLocalizedString("ViewType" + type); - return GetUserSubView(name, parentId, type, user, sortName, cancellationToken); + return GetUserSubView(name, parentId, type, sortName, cancellationToken); } public async Task GetUserView(List parents, List currentViews, string viewType, string sortName, User user, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 389eda904..cc3c06dd4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2204,8 +2204,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task GetInternalLiveTvFolder(string userId, CancellationToken cancellationToken) { var name = _localization.GetLocalizedString("ViewTypeLiveTV"); - var user = _userManager.GetUserById(userId); - return await _libraryManager.GetNamedView(user, name, "livetv", "zz_" + name, cancellationToken).ConfigureAwait(false); + return await _libraryManager.GetNamedView(name, "livetv", "zz_" + name, cancellationToken).ConfigureAwait(false); } public async Task SaveTunerHost(TunerHostInfo info) -- cgit v1.2.3 From 45c8f51a9c56471e2306ad6fd71ab4b51ee8047f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 14:30:08 -0400 Subject: update user views --- MediaBrowser.Controller/Channels/IChannelManager.cs | 3 +-- MediaBrowser.Controller/Entities/UserView.cs | 2 ++ .../Channels/ChannelManager.cs | 4 ++-- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 3 +-- .../Library/UserViewManager.cs | 11 ++++++----- .../UserViews/DynamicImageProvider.cs | 1 + 6 files changed, 13 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index f5c4ab373..8d3e0f596 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -121,10 +121,9 @@ namespace MediaBrowser.Controller.Channels /// /// Gets the channel folder. /// - /// The user identifier. /// The cancellation token. /// BaseItemDto. - Task GetInternalChannelFolder(string userId, CancellationToken cancellationToken); + Task GetInternalChannelFolder(CancellationToken cancellationToken); /// /// Gets the channel folder. diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index ce4de613e..488e54cc3 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -14,6 +14,8 @@ namespace MediaBrowser.Controller.Entities public string ViewType { get; set; } public Guid ParentId { get; set; } + public Guid? UserId { get; set; } + public static ITVSeriesManager TVSeriesManager; public static IPlaylistManager PlaylistManager; diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index cbbed856c..f670176e6 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1399,12 +1399,12 @@ namespace MediaBrowser.Server.Implementations.Channels { var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId); - var folder = await GetInternalChannelFolder(userId, cancellationToken).ConfigureAwait(false); + var folder = await GetInternalChannelFolder(cancellationToken).ConfigureAwait(false); return _dtoService.GetBaseItemDto(folder, new DtoOptions(), user); } - public async Task GetInternalChannelFolder(string userId, CancellationToken cancellationToken) + public async Task GetInternalChannelFolder(CancellationToken cancellationToken) { var name = _localization.GetLocalizedString("ViewTypeChannels"); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 1d2e5e322..c316aab25 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1670,8 +1670,7 @@ namespace MediaBrowser.Server.Implementations.Library string sortName, CancellationToken cancellationToken) { - var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, - "views"); + var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "views"); path = Path.Combine(path, _fileSystem.GetValidFilename(viewType)); diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index c32dc0d41..5d753826a 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -141,12 +141,13 @@ namespace MediaBrowser.Server.Implementations.Library if (user.Configuration.DisplayFoldersView) { - list.Add(await GetUserView(new List(), list, CollectionType.Folders, "zz_" + CollectionType.Folders, user, cancellationToken).ConfigureAwait(false)); + var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Folders); + list.Add(await _libraryManager.GetNamedView(name, CollectionType.Folders, string.Empty, cancellationToken).ConfigureAwait(false)); } if (query.IncludeExternalContent) { - var channelResult = await _channelManager.GetChannels(new ChannelQuery + var channelResult = await _channelManager.GetChannelsInternal(new ChannelQuery { UserId = query.UserId @@ -155,14 +156,14 @@ namespace MediaBrowser.Server.Implementations.Library var channels = channelResult.Items; var embeddedChannels = channels - .Where(i => user.Configuration.DisplayChannelsWithinViews.Contains(i.Id)) + .Where(i => user.Configuration.DisplayChannelsWithinViews.Contains(i.Id.ToString("N"))) .ToList(); - list.AddRange(embeddedChannels.Select(i => _channelManager.GetChannel(i.Id))); + list.AddRange(embeddedChannels); if (channels.Length > embeddedChannels.Count) { - list.Add(await _channelManager.GetInternalChannelFolder(query.UserId, cancellationToken).ConfigureAwait(false)); + list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false)); } if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId)) diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 7fbd2b26c..b11a7d167 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -72,6 +72,7 @@ namespace MediaBrowser.Server.Implementations.UserViews var result = await view.GetItems(new InternalItemsQuery { + User = (view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null), CollapseBoxSetItems = false, Recursive = recursive, ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Playlist" } -- cgit v1.2.3 From 9c879eefc33df13b7dac555e159d5c4ccf09213e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 15:14:54 -0400 Subject: update channel settings --- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 3 +-- MediaBrowser.Model/Configuration/UserConfiguration.cs | 1 + MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 2 +- MediaBrowser.Server.Implementations/Library/UserViewManager.cs | 5 ++--- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 6 +++--- 5 files changed, 8 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index e568b2eae..df09d39b2 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -273,10 +273,9 @@ namespace MediaBrowser.Controller.LiveTv /// /// Gets the live tv folder. /// - /// The user identifier. /// The cancellation token. /// BaseItemDto. - Task GetInternalLiveTvFolder(string userId, CancellationToken cancellationToken); + Task GetInternalLiveTvFolder(CancellationToken cancellationToken); /// /// Gets the live tv folder. diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 9dd84bc7d..349780958 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -50,6 +50,7 @@ namespace MediaBrowser.Model.Configuration public string[] PlainFolderViews { get; set; } public bool HidePlayedInLatest { get; set; } + public bool DisplayChannelsInline { get; set; } /// /// Initializes a new instance of the class. diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index c316aab25..0cfd38479 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1824,7 +1824,7 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("name"); } - var idValues = "37_namedview_" + name + (parentId ?? string.Empty); + var idValues = "37_namedview_" + name + (parentId ?? string.Empty) + (viewType ?? string.Empty); if (!string.IsNullOrWhiteSpace(uniqueId)) { idValues += uniqueId; diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 5d753826a..a609c53ab 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -156,7 +156,7 @@ namespace MediaBrowser.Server.Implementations.Library var channels = channelResult.Items; var embeddedChannels = channels - .Where(i => user.Configuration.DisplayChannelsWithinViews.Contains(i.Id.ToString("N"))) + .Where(i => user.Configuration.DisplayChannelsInline || user.Configuration.DisplayChannelsWithinViews.Contains(i.Id.ToString("N"))) .ToList(); list.AddRange(embeddedChannels); @@ -168,8 +168,7 @@ namespace MediaBrowser.Server.Implementations.Library if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId)) { - var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.LiveTv); - list.Add(await _libraryManager.GetNamedView(name, CollectionType.LiveTv, string.Empty, cancellationToken).ConfigureAwait(false)); + list.Add(await _liveTvManager.GetInternalLiveTvFolder(CancellationToken.None).ConfigureAwait(false)); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index cc3c06dd4..782473bea 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2196,15 +2196,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId); - var folder = await GetInternalLiveTvFolder(userId, cancellationToken).ConfigureAwait(false); + var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); return _dtoService.GetBaseItemDto(folder, new DtoOptions(), user); } - public async Task GetInternalLiveTvFolder(string userId, CancellationToken cancellationToken) + public async Task GetInternalLiveTvFolder(CancellationToken cancellationToken) { var name = _localization.GetLocalizedString("ViewTypeLiveTV"); - return await _libraryManager.GetNamedView(name, "livetv", "zz_" + name, cancellationToken).ConfigureAwait(false); + return await _libraryManager.GetNamedView(name, "livetv", name, cancellationToken).ConfigureAwait(false); } public async Task SaveTunerHost(TunerHostInfo info) -- cgit v1.2.3 From d1fd921280b7441f0a5462eb63352fbe86f14165 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 21:10:07 -0400 Subject: update plugin page --- MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index f20487733..a5c69317b 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -198,6 +198,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer } } } + catch (IOException ex) + { + throw; + } catch (Exception ex) { _logger.ErrorException("Error in range request writer", ex); -- cgit v1.2.3 From c1a1012f78f901ccc3d179b2eadb17b13e6927f6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Aug 2015 23:15:25 -0400 Subject: fix live tv chromecast playback --- MediaBrowser.Api/UserLibrary/ArtistsService.cs | 2 +- .../UserLibrary/BaseItemsByNameService.cs | 54 ++++++++++++++++++---- MediaBrowser.Api/UserLibrary/GameGenresService.cs | 20 ++++++-- MediaBrowser.Api/UserLibrary/GenresService.cs | 33 ++++++++++++- MediaBrowser.Api/UserLibrary/MusicGenresService.cs | 6 +-- MediaBrowser.Api/UserLibrary/PersonsService.cs | 2 +- MediaBrowser.Api/UserLibrary/StudiosService.cs | 2 +- MediaBrowser.Api/UserLibrary/YearsService.cs | 2 +- MediaBrowser.Controller/Dto/IDtoService.cs | 4 +- .../Dto/DtoService.cs | 3 +- 10 files changed, 100 insertions(+), 28 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index f027fe9df..cde5eade5 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { if (request is GetAlbumArtists) { diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index 539b792f4..a28202943 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -48,6 +48,42 @@ namespace MediaBrowser.Api.UserLibrary DtoService = dtoService; } + protected BaseItem GetParentItem(GetItemsByName request) + { + BaseItem parentItem; + + if (!string.IsNullOrWhiteSpace(request.UserId)) + { + var user = UserManager.GetUserById(request.UserId); + parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId); + } + else + { + parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId); + } + + return parentItem; + } + + protected string GetParentItemViewType(GetItemsByName request) + { + var parent = GetParentItem(request); + + var collectionFolder = parent as ICollectionFolder; + if (collectionFolder != null) + { + return collectionFolder.CollectionType; + } + + var view = parent as UserView; + if (view != null) + { + return view.ViewType; + } + + return null; + } + /// /// Gets the specified request. /// @@ -114,13 +150,13 @@ namespace MediaBrowser.Api.UserLibrary var filteredItems = FilterItems(request, extractedItems, user); - filteredItems = FilterByLibraryItems(request, filteredItems, user, libraryItems); + filteredItems = FilterByLibraryItems(request, filteredItems.Cast(), user, libraryItems).Cast(); - filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending).Cast(); + filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending); var ibnItemsArray = filteredItems.ToList(); - IEnumerable ibnItems = ibnItemsArray; + IEnumerable ibnItems = ibnItemsArray; var result = new ItemsResult { @@ -141,14 +177,14 @@ namespace MediaBrowser.Api.UserLibrary } - IEnumerable>> tuples; + IEnumerable>> tuples; if (dtoOptions.Fields.Contains(ItemFields.ItemCounts)) { - tuples = ibnItems.Select(i => new Tuple>(i, i.GetTaggedItems(libraryItems).ToList())); + tuples = ibnItems.Select(i => new Tuple>(i, ((IItemByName)i).GetTaggedItems(libraryItems).ToList())); } else { - tuples = ibnItems.Select(i => new Tuple>(i, new List())); + tuples = ibnItems.Select(i => new Tuple>(i, new List())); } var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, user)); @@ -180,7 +216,7 @@ namespace MediaBrowser.Api.UserLibrary return options.Fields.Contains(ItemFields.ItemCounts); } - private IEnumerable FilterByLibraryItems(GetItemsByName request, IEnumerable items, User user, IEnumerable libraryItems) + private IEnumerable FilterByLibraryItems(GetItemsByName request, IEnumerable items, User user, IEnumerable libraryItems) { var filters = request.GetFilters().ToList(); @@ -211,7 +247,7 @@ namespace MediaBrowser.Api.UserLibrary /// The items. /// The user. /// IEnumerable{`0}. - private IEnumerable FilterItems(GetItemsByName request, IEnumerable items, User user) + private IEnumerable FilterItems(GetItemsByName request, IEnumerable items, User user) { if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater)) { @@ -375,7 +411,7 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Task{`0}}. - protected abstract IEnumerable GetAllItems(GetItemsByName request, IEnumerable items); + protected abstract IEnumerable GetAllItems(GetItemsByName request, IEnumerable items); } /// diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs index f9d0f0d0f..a1ad14a4d 100644 --- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs @@ -99,14 +99,24 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { - var itemsList = items.Where(i => i.Genres != null).ToList(); - - return itemsList + return items .SelectMany(i => i.Genres) .DistinctNames() - .Select(name => LibraryManager.GetGameGenre(name)); + .Select(name => + { + try + { + return LibraryManager.GetGameGenre(name); + } + catch (Exception ex) + { + Logger.ErrorException("Error getting genre {0}", ex, name); + return null; + } + }) + .Where(i => i != null); } } } diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index 070246886..9e56907da 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using ServiceStack; using System; @@ -104,8 +105,38 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { + var viewType = GetParentItemViewType(request); + + if (string.Equals(viewType, CollectionType.Music) || string.Equals(viewType, CollectionType.MusicVideos)) + { + return items + .SelectMany(i => i.Genres) + .DistinctNames() + .Select(name => LibraryManager.GetMusicGenre(name)); + } + + if (string.Equals(viewType, CollectionType.Games)) + { + return items + .SelectMany(i => i.Genres) + .DistinctNames() + .Select(name => + { + try + { + return LibraryManager.GetGameGenre(name); + } + catch (Exception ex) + { + Logger.ErrorException("Error getting genre {0}", ex, name); + return null; + } + }) + .Where(i => i != null); + } + return items .SelectMany(i => i.Genres) .DistinctNames() diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs index e63d6c0f4..182691584 100644 --- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs +++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs @@ -99,11 +99,9 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { - var itemsList = items.ToList(); - - return itemsList + return items .SelectMany(i => i.Genres) .DistinctNames() .Select(name => LibraryManager.GetMusicGenre(name)); diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs index fc1431f2e..e6a60fcc6 100644 --- a/MediaBrowser.Api/UserLibrary/PersonsService.cs +++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { var inputPersonTypes = ((GetPersons)request).PersonTypes; var personTypes = string.IsNullOrEmpty(inputPersonTypes) ? new string[] { } : inputPersonTypes.Split(','); diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs index d6a7db14f..7cf8d752a 100644 --- a/MediaBrowser.Api/UserLibrary/StudiosService.cs +++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { var itemsList = items.Where(i => i.Studios != null).ToList(); diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs index 859b9f959..4b3fe6c8e 100644 --- a/MediaBrowser.Api/UserLibrary/YearsService.cs +++ b/MediaBrowser.Api/UserLibrary/YearsService.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Api.UserLibrary /// The request. /// The items. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. - protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) + protected override IEnumerable GetAllItems(GetItemsByName request, IEnumerable items) { var itemsList = items.Where(i => i.ProductionYear != null).ToList(); diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index 5ec8f274b..e4ab29102 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -81,13 +81,11 @@ namespace MediaBrowser.Controller.Dto /// /// Gets the item by name dto. /// - /// /// The item. /// The options. /// The tagged items. /// The user. /// BaseItemDto. - BaseItemDto GetItemByNameDto(T item, DtoOptions options, List taggedItems, User user = null) - where T : BaseItem, IItemByName; + BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, User user = null); } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 1dbdf90a7..5c9f72b7d 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -397,8 +397,7 @@ namespace MediaBrowser.Server.Implementations.Dto return dto; } - public BaseItemDto GetItemByNameDto(T item, DtoOptions options, List taggedItems, User user = null) - where T : BaseItem, IItemByName + public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, User user = null) { var syncProgress = GetSyncedItemProgress(options); -- cgit v1.2.3 From ebd2f7b63d13bce6e5a30f8b37f89617bed44ff2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 15 Aug 2015 14:46:57 -0400 Subject: restore saved movie views --- MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index b0edfc46b..36710c052 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -16,7 +16,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.Listings { - public class SchedulesDirect + public class SchedulesDirect : IListingsProvider { private readonly ILogger _logger; private readonly IJsonSerializer _jsonSerializer; -- cgit v1.2.3 From d685925bbbfbe82367eff0122301a2ef130f0478 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 15 Aug 2015 16:33:53 -0400 Subject: update schedules direct --- MediaBrowser.Api/ApiEntryPoint.cs | 6 ------ .../LiveTv/Listings/SchedulesDirect.cs | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 54c28d390..c2b406190 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -336,12 +336,6 @@ namespace MediaBrowser.Api if (job.Type != TranscodingJobType.Progressive) { timerDuration = 1800000; - - // We can really reduce the timeout for apps that are using the newer api - if (!string.IsNullOrWhiteSpace(job.PlaySessionId)) - { - timerDuration = 300000; - } } job.PingTimeout = timerDuration; diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 36710c052..8650d4bc4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -337,7 +337,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings (details.showType ?? "No ShowType") == "TV Movie" || (details.showType ?? "No ShowType") == "Short Film", IsPremiere = false, - ShowId = programInfo.programID + ShowId = programInfo.programID, + SeriesId = programInfo.programID.Substring(0, 10) }; if (!string.IsNullOrWhiteSpace(details.originalAirDate)) -- cgit v1.2.3 From e376c31436c72fa870a2c1991ff48d3543069ce0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 15 Aug 2015 17:58:52 -0400 Subject: fix subs not starting initially --- .../LiveTv/EmbyTV/EmbyTV.cs | 31 +++++++++------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index cf294997b..6e5749250 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -238,20 +238,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return Task.FromResult(0); } - public Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) + public async Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) { info.Id = Guid.NewGuid().ToString("N"); - UpdateTimersForSeriesTimer(info); + await UpdateTimersForSeriesTimer(info).ConfigureAwait(false); _seriesTimerProvider.Add(info); - return Task.FromResult(true); } - public Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) + public async Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) { _seriesTimerProvider.Update(info); - UpdateTimersForSeriesTimer(info); - return Task.FromResult(true); + await UpdateTimersForSeriesTimer(info).ConfigureAwait(false); } public Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken) @@ -594,12 +592,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return _config.GetConfiguration("livetv"); } - private void UpdateTimersForSeriesTimer(SeriesTimerInfo seriesTimer) + private async Task UpdateTimersForSeriesTimer(SeriesTimerInfo seriesTimer) { List epgData; if (seriesTimer.RecordAnyChannel) { - epgData = GetEpgDataForAllChannels(); + var channels = await GetChannelsAsync(CancellationToken.None).ConfigureAwait(false); + var channelIds = channels.Select(i => i.Id).ToList(); + epgData = GetEpgDataForChannels(channelIds); } else { @@ -656,9 +656,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV allPrograms = allPrograms.Where(epg => string.Equals(epg.ChannelId, seriesTimer.ChannelId, StringComparison.OrdinalIgnoreCase)); } - allPrograms = allPrograms.Where(epg => seriesTimer.Days.Contains(epg.StartDate.DayOfWeek)); + allPrograms = allPrograms.Where(i => seriesTimer.Days.Contains(i.StartDate.DayOfWeek)); - return allPrograms.Where(epg => string.Equals(epg.SeriesId, seriesTimer.SeriesId, StringComparison.OrdinalIgnoreCase)); + return allPrograms.Where(i => string.Equals(i.SeriesId, seriesTimer.SeriesId, StringComparison.OrdinalIgnoreCase)); } private string GetChannelEpgCachePath(string channelId) @@ -690,16 +690,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return new List(); } } - private List GetEpgDataForAllChannels() + private List GetEpgDataForChannels(List channelIds) { - List channelEpg = new List(); - DirectoryInfo dir = new DirectoryInfo(Path.Combine(DataPath, "epg")); - List channels = dir.GetFiles("*").Where(i => string.Equals(i.Extension, ".json", StringComparison.OrdinalIgnoreCase)).Select(f => f.Name).ToList(); - foreach (var channel in channels) - { - channelEpg.AddRange(GetEpgDataForChannel(channel)); - } - return channelEpg; + return channelIds.SelectMany(GetEpgDataForChannel).ToList(); } public void Dispose() -- cgit v1.2.3 From f6dcef0cfdb4364f11836e395ff8933974bcf627 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 15 Aug 2015 20:41:55 -0400 Subject: update recordings --- .../LiveTv/EmbyTV/EmbyTV.cs | 8 +++++--- .../LiveTv/EmbyTV/RecordingHelper.cs | 18 ++---------------- 2 files changed, 7 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 6e5749250..f4a6385a4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.LiveTv; @@ -33,6 +34,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly TimerManager _timerProvider; private readonly LiveTvManager _liveTvManager; + private IFileSystem _fileSystem; public static EmbyTV Current; @@ -481,14 +483,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var recordPath = RecordingPath; if (info.IsMovie) { - recordPath = Path.Combine(recordPath, "Movies", RecordingHelper.RemoveSpecialCharacters(info.Name)); + recordPath = Path.Combine(recordPath, "Movies", _fileSystem.GetValidFilename(info.Name)); } else { - recordPath = Path.Combine(recordPath, "TV", RecordingHelper.RemoveSpecialCharacters(info.Name)); + recordPath = Path.Combine(recordPath, "TV", _fileSystem.GetValidFilename(info.Name)); } - recordPath = Path.Combine(recordPath, RecordingHelper.GetRecordingName(timer, info)); + recordPath = Path.Combine(recordPath, _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info))); Directory.CreateDirectory(Path.GetDirectoryName(recordPath)); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 31fb072cd..09a5a3912 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.LiveTv; using System; -using System.Text; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { @@ -44,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { fancyName += "_(" + info.ProductionYear + ")"; } - if (info.IsSeries) + if (info.IsSeries && !string.IsNullOrWhiteSpace(info.EpisodeTitle)) { fancyName += "_" + info.EpisodeTitle.Replace("Season: ", "S").Replace(" Episode: ", "E"); } @@ -56,20 +55,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { fancyName += "_" + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); } - return RemoveSpecialCharacters(fancyName) + ".ts"; - } - - public static string RemoveSpecialCharacters(string str) - { - StringBuilder sb = new StringBuilder(); - foreach (char c in str) - { - if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' || c == '_' || c == '-' || c == ' ') - { - sb.Append(c); - } - } - return sb.ToString(); + return fancyName + ".ts"; } } } -- cgit v1.2.3 From 1f1f7642c3df2f9ec67bbdbdb4d5ed66e126f3ab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Aug 2015 11:53:30 -0400 Subject: update subtitle escaping --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 4 ++-- MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs | 7 +++++++ MediaBrowser.Controller/Session/SessionInfo.cs | 6 ++++++ MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 4 ++-- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 5 +++++ MediaBrowser.Model/Session/SessionInfoDto.cs | 6 ++++++ .../Session/SessionManager.cs | 2 ++ .../MediaBrowser.WebDashboard.csproj | 17 +++-------------- 8 files changed, 33 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 8f5301642..6fba6052f 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -619,7 +619,7 @@ namespace MediaBrowser.Api.Playback // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(subtitlePath), charsetParam, seconds.ToString(UsCulture)); } @@ -627,7 +627,7 @@ namespace MediaBrowser.Api.Playback var mediaPath = state.MediaPath ?? string.Empty; return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - mediaPath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(mediaPath), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 5bec7980a..23285b612 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -116,5 +116,12 @@ namespace MediaBrowser.Controller.MediaEncoding Task EncodeVideo(EncodingJobOptions options, IProgress progress, CancellationToken cancellationToken); + + /// + /// Escapes the subtitle filter path. + /// + /// The path. + /// System.String. + string EscapeSubtitleFilterPath(string path); } } diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 64b20c13e..b3e82f925 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -125,6 +125,12 @@ namespace MediaBrowser.Controller.Session /// The session controller. public ISessionController SessionController { get; set; } + /// + /// Gets or sets the application icon URL. + /// + /// The application icon URL. + public string AppIconUrl { get; set; } + /// /// Gets or sets the supported commands. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index dd88512fb..181f147b4 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -865,13 +865,13 @@ namespace MediaBrowser.MediaEncoding.Encoder // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(subtitlePath), charsetParam, seconds.ToString(UsCulture)); } return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - state.MediaPath.Replace('\\', '/').Replace(":/", "\\:/"), + MediaEncoder.EscapeSubtitleFilterPath(state.MediaPath), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c059a8b54..50b6a94aa 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -765,6 +765,11 @@ namespace MediaBrowser.MediaEncoding.Encoder } } + public string EscapeSubtitleFilterPath(string path) + { + return path.Replace('\\', '/').Replace(":/", "\\:/").Replace("'", "'\\\\\\'"); + } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs index 98df3efe5..da8ab9b8a 100644 --- a/MediaBrowser.Model/Session/SessionInfoDto.cs +++ b/MediaBrowser.Model/Session/SessionInfoDto.cs @@ -99,6 +99,12 @@ namespace MediaBrowser.Model.Session /// /// The device id. public string DeviceId { get; set; } + + /// + /// Gets or sets the application icon URL. + /// + /// The application icon URL. + public string AppIconUrl { get; set; } /// /// Gets or sets a value indicating whether [supports remote control]. diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index c2160f48a..70a4cb439 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -161,6 +161,7 @@ namespace MediaBrowser.Server.Implementations.Session if (capabilities != null) { + info.AppIconUrl = capabilities.IconUrl; ReportCapabilities(info, capabilities, false); } } @@ -1476,6 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Session NowPlayingItem = session.NowPlayingItem, SupportsRemoteControl = session.SupportsMediaControl, PlayState = session.PlayState, + AppIconUrl = session.AppIconUrl, TranscodingInfo = session.NowPlayingItem == null ? null : session.TranscodingInfo }; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 42a9c5c1b..a90fbaec8 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -156,6 +156,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -565,12 +568,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -802,9 +799,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -2207,11 +2201,6 @@ PreserveNewest - - - PreserveNewest - - PreserveNewest -- cgit v1.2.3 From 061c363495699eda74787c4b74967a83269ae17e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Aug 2015 14:37:53 -0400 Subject: update live tv channel ids --- .../LiveTv/EmbyTV/EmbyTV.cs | 63 ++++++++++------------ .../LiveTv/Listings/SchedulesDirect.cs | 25 +++++---- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 16 +++++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 13 ++++- 4 files changed, 65 insertions(+), 52 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index f4a6385a4..46b10703a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -117,14 +117,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV try { var channels = await hostInstance.Item1.GetChannels(hostInstance.Item2, cancellationToken).ConfigureAwait(false); - var newChannels = channels.ToList(); - foreach (var channel in newChannels) - { - channel.Id = hostInstance.Item1.Type.GetMD5().ToString("N") + "-" + channel.Id; - } - - list.AddRange(newChannels); + list.AddRange(channels); } catch (Exception ex) { @@ -310,18 +304,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return Task.FromResult((IEnumerable)_seriesTimerProvider.GetAll()); } - private string GetOriginalChannelId(string channelId) - { - var parts = channelId.Split('-'); - - return string.Join("-", parts.Skip(1).ToArray()); - } - public async Task> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { foreach (var provider in GetListingProviders()) { - var programs = await provider.Item1.GetProgramsAsync(provider.Item2, GetOriginalChannelId(channelId), startDateUtc, endDateUtc, cancellationToken) + var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channelId, startDateUtc, endDateUtc, cancellationToken) .ConfigureAwait(false); var list = programs.ToList(); @@ -364,15 +351,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { _logger.Info("Streaming Channel " + channelId); - var configurationId = channelId.Split('-')[0]; - foreach (var hostInstance in GetTunerHosts()) { - if (!string.Equals(configurationId, hostInstance.Item1.Type.GetMD5().ToString("N"), StringComparison.OrdinalIgnoreCase)) - { - continue; - } - if (!string.IsNullOrWhiteSpace(streamId)) { var originalStreamId = string.Join("-", streamId.Split('-').Skip(1).ToArray()); @@ -386,16 +366,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV MediaSourceInfo mediaSourceInfo = null; try { - mediaSourceInfo = await hostInstance.Item1.GetChannelStream(hostInstance.Item2, GetOriginalChannelId(channelId), streamId, cancellationToken).ConfigureAwait(false); + mediaSourceInfo = await hostInstance.Item1.GetChannelStream(hostInstance.Item2, channelId, streamId, cancellationToken).ConfigureAwait(false); } - catch (ApplicationException e) + catch (Exception e) { - _logger.Info(e.Message); - continue; + _logger.ErrorException("Error getting channel stream", e); } - mediaSourceInfo.Id = Guid.NewGuid().ToString("N"); - return mediaSourceInfo; + if (mediaSourceInfo != null) + { + mediaSourceInfo.Id = Guid.NewGuid().ToString("N"); + return mediaSourceInfo; + } } throw new ApplicationException("Tuner not found."); @@ -403,20 +385,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken) { - var configurationId = channelId.Split('-')[0]; - foreach (var hostInstance in GetTunerHosts()) { - if (string.Equals(configurationId, hostInstance.Item1.Type.GetMD5().ToString("N"), StringComparison.OrdinalIgnoreCase)) + try { - var sources = await hostInstance.Item1.GetChannelStreamMediaSources(hostInstance.Item2, GetOriginalChannelId(channelId), cancellationToken).ConfigureAwait(false); + var sources = await hostInstance.Item1.GetChannelStreamMediaSources(hostInstance.Item2, channelId, cancellationToken).ConfigureAwait(false); foreach (var source in sources) { source.Id = hostInstance.Item2.Id + "-" + source.Id; } - return sources; + if (sources.Count > 0) + { + return sources; + } + } + catch (NotImplementedException) + { + } } @@ -636,7 +623,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var recordingShowIds = currentRecordings.Select(i => i.ShowId).ToList(); - allPrograms = allPrograms.Where(epg => !recordingShowIds.Contains(epg.ShowId, StringComparer.OrdinalIgnoreCase)); + allPrograms = allPrograms.Where(epg => !recordingShowIds.Contains(epg.ShowId, StringComparer.OrdinalIgnoreCase)); return allPrograms.Select(i => RecordingHelper.CreateTimer(i, seriesTimer)); } @@ -650,7 +637,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (seriesTimer.RecordNewOnly) { - allPrograms = allPrograms.Where(epg => !epg.IsRepeat); + allPrograms = allPrograms.Where(epg => !epg.IsRepeat); } if (!seriesTimer.RecordAnyChannel) @@ -660,6 +647,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV allPrograms = allPrograms.Where(i => seriesTimer.Days.Contains(i.StartDate.DayOfWeek)); + if (string.IsNullOrWhiteSpace(seriesTimer.SeriesId)) + { + _logger.Error("seriesTimer.SeriesId is null. Cannot find programs for series"); + return new List(); + } + return allPrograms.Where(i => string.Equals(i.SeriesId, seriesTimer.SeriesId, StringComparison.OrdinalIgnoreCase)); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 8650d4bc4..c536d0e83 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -307,6 +307,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings imageLink = details.images; } + var showType = details.showType ?? string.Empty; + var info = new ProgramInfo { ChannelId = channel, @@ -315,32 +317,29 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings StartDate = startAt, EndDate = endAt, Name = details.titles[0].title120 ?? "Unkown", - OfficialRating = "0", + OfficialRating = null, CommunityRating = null, EpisodeTitle = episodeTitle, Audio = audioType, IsHD = hdtv, IsRepeat = repeat, - IsSeries = - ((details.showType ?? "No ShowType") == "Series") || - (details.showType ?? "No ShowType") == "Miniseries", + IsSeries = showType.IndexOf("series", StringComparison.OrdinalIgnoreCase) != -1, ImageUrl = imageLink, HasImage = details.hasImageArtwork, IsNews = false, IsKids = false, - IsSports = - ((details.showType ?? "No ShowType") == "Sports non-event") || - (details.showType ?? "No ShowType") == "Sports event", + IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1, IsLive = false, - IsMovie = - (details.showType ?? "No ShowType") == "Feature Film" || - (details.showType ?? "No ShowType") == "TV Movie" || - (details.showType ?? "No ShowType") == "Short Film", + IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1, IsPremiere = false, - ShowId = programInfo.programID, - SeriesId = programInfo.programID.Substring(0, 10) + ShowId = programInfo.programID }; + if (info.IsSeries) + { + info.SeriesId = programInfo.programID.Substring(0, 10); + } + if (!string.IsNullOrWhiteSpace(details.originalAirDate)) { info.OriginalAirDate = DateTime.Parse(details.originalAirDate); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index c01eb63ab..b09f8cfef 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -47,6 +47,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun get { return "hdhomerun"; } } + private const string ChannelIdPrefix = "hdhr_"; + public async Task> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) { var options = new HttpRequestOptions @@ -64,7 +66,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Name = i.GuideName, Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), - Id = i.GuideNumber.ToString(CultureInfo.InvariantCulture), + Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture), IsFavorite = i.Favorite }); @@ -320,6 +322,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var list = new List(); + if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) + { + return list; + } + list.Add(GetMediaSource(info, channelId, "native")); try @@ -339,7 +346,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun } catch (Exception ex) { - + } return list; @@ -347,6 +354,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { + if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + return GetMediaSource(info, channelId, streamId); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index bb31390f2..0755d2a39 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -35,6 +35,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts public Task> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) { + var urlHash = info.Url.GetMD5().ToString("N"); + int position = 0; string line; // Read the file and display it line by line. @@ -87,7 +89,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts switch (list[0]) { case "tvg-id": - channels.Last().Id = list[1]; + channels.Last().Id = urlHash + list[1]; channels.Last().Number = list[1]; break; case "tvg-name": @@ -126,6 +128,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts public async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { + var urlHash = info.Url.GetMD5().ToString("N"); + if (!channelId.StartsWith(urlHash, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + channelId = channelId.Substring(urlHash.Length); + var channels = await GetChannels(info, cancellationToken).ConfigureAwait(false); var m3uchannels = channels.Cast(); var channel = m3uchannels.FirstOrDefault(c => c.Id == channelId); @@ -191,7 +201,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } } - public Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { throw new NotImplementedException(); -- cgit v1.2.3 From ee94d7b1f68b6ce492594e804eae72e0a57da48a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Aug 2015 14:54:25 -0400 Subject: update channel ids --- .../LiveTv/EmbyTV/EmbyTV.cs | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 46b10703a..9ff8f7206 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -34,11 +34,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly TimerManager _timerProvider; private readonly LiveTvManager _liveTvManager; - private IFileSystem _fileSystem; + private readonly IFileSystem _fileSystem; public static EmbyTV Current; - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager) + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem) { Current = this; @@ -46,6 +46,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _logger = logger; _httpClient = httpClient; _config = config; + _fileSystem = fileSystem; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; @@ -108,8 +109,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return status; } - public async Task> GetChannelsAsync(CancellationToken cancellationToken) + private List _channelCache = null; + private async Task> GetChannelsAsync(bool enableCache, CancellationToken cancellationToken) { + if (enableCache && _channelCache != null) + { + + return _channelCache.ToList(); + } + var list = new List(); foreach (var hostInstance in GetTunerHosts()) @@ -144,10 +152,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } } - + _channelCache = list; return list; } + public Task> GetChannelsAsync(CancellationToken cancellationToken) + { + return GetChannelsAsync(false, cancellationToken); + } + private List> GetTunerHosts() { return GetConfiguration().TunerHosts @@ -306,9 +319,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { + var channels = await GetChannelsAsync(true, cancellationToken).ConfigureAwait(false); + var channel = channels.First(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase)); + foreach (var provider in GetListingProviders()) { - var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channelId, startDateUtc, endDateUtc, cancellationToken) + var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channel.Number, startDateUtc, endDateUtc, cancellationToken) .ConfigureAwait(false); var list = programs.ToList(); @@ -403,7 +419,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } catch (NotImplementedException) { - + } } @@ -586,7 +602,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV List epgData; if (seriesTimer.RecordAnyChannel) { - var channels = await GetChannelsAsync(CancellationToken.None).ConfigureAwait(false); + var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false); var channelIds = channels.Select(i => i.Id).ToList(); epgData = GetEpgDataForChannels(channelIds); } -- cgit v1.2.3 From f49417c703802a646910476dab38dc3f1adfb5c3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Aug 2015 16:26:49 -0400 Subject: update series recordings --- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 6 ++++++ MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs | 9 +++++++++ MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs | 6 ++++-- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 5 ++++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 ++ 6 files changed, 26 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index b54a7aaee..0a1735c23 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -60,6 +60,12 @@ namespace MediaBrowser.Controller.LiveTv /// true if this instance is repeat; otherwise, false. public bool IsRepeat { get; set; } + /// + /// Gets or sets the external series identifier. + /// + /// The external series identifier. + public string ExternalSeriesId { get; set; } + /// /// Gets or sets the episode title. /// diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs index 7c590307f..70c6892ef 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -6,6 +6,9 @@ using System.Runtime.Serialization; namespace MediaBrowser.Model.LiveTv { + /// + /// Class SeriesTimerInfoDto. + /// [DebuggerDisplay("Name = {Name}")] public class SeriesTimerInfoDto : BaseTimerInfoDto { @@ -45,6 +48,12 @@ namespace MediaBrowser.Model.LiveTv /// The image tags. public Dictionary ImageTags { get; set; } + /// + /// Gets or sets the external series identifier. + /// + /// The external series identifier. + public string ExternalSeriesId { get; set; } + /// /// Gets a value indicating whether this instance has primary image. /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 9ff8f7206..177a64ddc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -220,7 +220,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (enableDelay) { // A hack yes, but need to make sure the file is closed before attempting to delete it - await Task.Delay(3000).ConfigureAwait(false); + await Task.Delay(3000, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 9ffd8a500..2587b1005 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -105,7 +105,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv ExternalProgramId = info.ProgramId, ServiceName = service.Name, ChannelName = channelName, - ServerId = _appHost.SystemId + ServerId = _appHost.SystemId, + ExternalSeriesId = info.SeriesId }; if (!string.IsNullOrEmpty(info.ChannelId)) @@ -376,7 +377,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv RecordNewOnly = dto.RecordNewOnly, ProgramId = dto.ExternalProgramId, ChannelId = dto.ExternalChannelId, - Id = dto.ExternalId + Id = dto.ExternalId, + SeriesId = dto.ExternalSeriesId }; // Convert internal server id's to external tv provider id's diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 782473bea..9065a8ac2 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -627,6 +627,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; + item.ExternalSeriesId = info.SeriesId; if (isNew) { @@ -1786,7 +1787,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv ImagePath = program.ProviderImagePath, ImageUrl = program.ProviderImageUrl, Name = program.Name, - OfficialRating = program.OfficialRating + OfficialRating = program.OfficialRating, + SeriesId = program.ExternalSeriesId }; } @@ -1829,6 +1831,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv info.Overview = program.Overview; info.ProgramId = programDto.Id; info.ExternalProgramId = program.ExternalId; + info.ExternalSeriesId = program.ExternalSeriesId; if (program.EndDate.HasValue) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index b09f8cfef..35f77abcb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -326,6 +326,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { return list; } + channelId = channelId.Substring(ChannelIdPrefix.Length); list.Add(GetMediaSource(info, channelId, "native")); @@ -358,6 +359,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { return null; } + channelId = channelId.Substring(ChannelIdPrefix.Length); return GetMediaSource(info, channelId, streamId); } -- cgit v1.2.3 From 90843b218c9174b8697ddaa296594f9d364fa388 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Aug 2015 18:03:22 -0400 Subject: update recording styles --- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 6 --- MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs | 6 --- .../LiveTv/EmbyTV/EmbyTV.cs | 54 ++++++++++++++++------ .../LiveTv/LiveTvDtoService.cs | 6 +-- .../LiveTv/LiveTvManager.cs | 5 +- 5 files changed, 42 insertions(+), 35 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 0a1735c23..b54a7aaee 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -60,12 +60,6 @@ namespace MediaBrowser.Controller.LiveTv /// true if this instance is repeat; otherwise, false. public bool IsRepeat { get; set; } - /// - /// Gets or sets the external series identifier. - /// - /// The external series identifier. - public string ExternalSeriesId { get; set; } - /// /// Gets or sets the episode title. /// diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs index 70c6892ef..4b88e42f3 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -48,12 +48,6 @@ namespace MediaBrowser.Model.LiveTv /// The image tags. public Dictionary ImageTags { get; set; } - /// - /// Gets or sets the external series identifier. - /// - /// The external series identifier. - public string ExternalSeriesId { get; set; } - /// /// Gets a value indicating whether this instance has primary image. /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 177a64ddc..7273ac88e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -251,14 +251,50 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { info.Id = Guid.NewGuid().ToString("N"); - await UpdateTimersForSeriesTimer(info).ConfigureAwait(false); + List epgData; + if (info.RecordAnyChannel) + { + var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false); + var channelIds = channels.Select(i => i.Id).ToList(); + epgData = GetEpgDataForChannels(channelIds); + } + else + { + epgData = GetEpgDataForChannel(info.ChannelId); + } + + // populate info.seriesID + var program = epgData.FirstOrDefault(i => string.Equals(i.Id, info.ProgramId, StringComparison.OrdinalIgnoreCase)); + + if (program != null) + { + info.SeriesId = program.SeriesId; + } + else + { + throw new InvalidOperationException("SeriesId for program not found"); + } + _seriesTimerProvider.Add(info); + await UpdateTimersForSeriesTimer(epgData, info).ConfigureAwait(false); } public async Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken) { _seriesTimerProvider.Update(info); - await UpdateTimersForSeriesTimer(info).ConfigureAwait(false); + List epgData; + if (info.RecordAnyChannel) + { + var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false); + var channelIds = channels.Select(i => i.Id).ToList(); + epgData = GetEpgDataForChannels(channelIds); + } + else + { + epgData = GetEpgDataForChannel(info.ChannelId); + } + + await UpdateTimersForSeriesTimer(epgData, info).ConfigureAwait(false); } public Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken) @@ -597,20 +633,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return _config.GetConfiguration("livetv"); } - private async Task UpdateTimersForSeriesTimer(SeriesTimerInfo seriesTimer) + private async Task UpdateTimersForSeriesTimer(List epgData, SeriesTimerInfo seriesTimer) { - List epgData; - if (seriesTimer.RecordAnyChannel) - { - var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false); - var channelIds = channels.Select(i => i.Id).ToList(); - epgData = GetEpgDataForChannels(channelIds); - } - else - { - epgData = GetEpgDataForChannel(seriesTimer.ChannelId); - } - var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); var existingTimers = _timerProvider.GetAll() diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 2587b1005..9ffd8a500 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -105,8 +105,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv ExternalProgramId = info.ProgramId, ServiceName = service.Name, ChannelName = channelName, - ServerId = _appHost.SystemId, - ExternalSeriesId = info.SeriesId + ServerId = _appHost.SystemId }; if (!string.IsNullOrEmpty(info.ChannelId)) @@ -377,8 +376,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv RecordNewOnly = dto.RecordNewOnly, ProgramId = dto.ExternalProgramId, ChannelId = dto.ExternalChannelId, - Id = dto.ExternalId, - SeriesId = dto.ExternalSeriesId + Id = dto.ExternalId }; // Convert internal server id's to external tv provider id's diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 9065a8ac2..782473bea 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -627,7 +627,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; - item.ExternalSeriesId = info.SeriesId; if (isNew) { @@ -1787,8 +1786,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv ImagePath = program.ProviderImagePath, ImageUrl = program.ProviderImageUrl, Name = program.Name, - OfficialRating = program.OfficialRating, - SeriesId = program.ExternalSeriesId + OfficialRating = program.OfficialRating }; } @@ -1831,7 +1829,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv info.Overview = program.Overview; info.ProgramId = programDto.Id; info.ExternalProgramId = program.ExternalId; - info.ExternalSeriesId = program.ExternalSeriesId; if (program.EndDate.HasValue) { -- cgit v1.2.3 From 823cb53ce04d7034893360b298742c22349d8e20 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 17 Aug 2015 00:08:33 -0400 Subject: update recordings --- MediaBrowser.Server.Implementations/Dto/DtoService.cs | 3 ++- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 4 ---- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 5c9f72b7d..7b19589b7 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1526,10 +1526,11 @@ namespace MediaBrowser.Server.Implementations.Dto dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(tvChannel, true).ToList(); } + dto.ChannelId = item.ChannelId; + var channelItem = item as IChannelItem; if (channelItem != null) { - dto.ChannelId = channelItem.ChannelId; dto.ChannelName = _channelManagerFactory().GetChannel(channelItem.ChannelId).Name; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 7273ac88e..5779be84f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -515,7 +515,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV HttpRequestOptions httpRequestOptions = new HttpRequestOptions() { - Url = mediaStreamInfo.Path + "?duration=" + duration.TotalSeconds.ToString(CultureInfo.InvariantCulture) + Url = mediaStreamInfo.Path }; var info = GetProgramInfoFromCache(timer.ChannelId, timer.ProgramId); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 782473bea..1280c52b1 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1395,8 +1395,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N"); - dto.ChannelId = item.ChannelId; - dto.StartDate = program.StartDate; dto.IsRepeat = program.IsRepeat; dto.EpisodeTitle = program.EpisodeTitle; @@ -1463,8 +1461,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv ? null : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); - dto.ChannelId = item.ChannelId; - dto.StartDate = info.StartDate; dto.RecordingStatus = info.Status; dto.IsRepeat = info.IsRepeat; -- cgit v1.2.3 From 9849f522efa21097fcd827635ef75535bb821bf0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 17 Aug 2015 00:56:22 -0400 Subject: fix playlist runtime display --- MediaBrowser.Server.Implementations/Dto/DtoService.cs | 3 ++- MediaBrowser.Server.Implementations/Sync/SyncManager.cs | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 7b19589b7..aa6ab1d65 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1647,7 +1647,8 @@ namespace MediaBrowser.Server.Implementations.Dto IsFolder = false, Recursive = true, IsVirtualUnaired = false, - IsMissing = false + IsMissing = false, + User = user }).Result.Items; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 36f8984dd..5bd35a325 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,8 +1,8 @@ -using MediaBrowser.Common; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Drawing; @@ -32,7 +32,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.ScheduledTasks; namespace MediaBrowser.Server.Implementations.Sync { -- cgit v1.2.3 From 66ccb313c2037ddbce7a101c97bc5746547b3243 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 17 Aug 2015 12:52:56 -0400 Subject: recording fixes --- .../Library/UserViewManager.cs | 1 - MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 11 ++++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index a609c53ab..43f77ec49 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -224,7 +224,6 @@ namespace MediaBrowser.Server.Implementations.Library if (enableUserSpecificViews) { - viewType = enableRichView ? viewType : null; var view = await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); if (view.ParentId != parentId) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 5779be84f..14c3887df 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -177,6 +177,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) { + var timers = _timerProvider.GetAll().Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase)); + foreach (var timer in timers) + { + CancelTimerInternal(timer.Id); + } + var remove = _seriesTimerProvider.GetAll().FirstOrDefault(r => string.Equals(r.Id, timerId, StringComparison.OrdinalIgnoreCase)); if (remove != null) { @@ -583,7 +589,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { using (var output = File.Open(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { - await response.Content.CopyToAsync(output, 131072, linkedToken); + await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken); } } @@ -659,6 +665,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private IEnumerable GetTimersForSeries(SeriesTimerInfo seriesTimer, IEnumerable allPrograms, IReadOnlyList currentRecordings) { + // Exclude programs that have already ended + allPrograms = allPrograms.Where(i => i.EndDate > DateTime.UtcNow); + allPrograms = GetProgramsForSeries(seriesTimer, allPrograms); var recordingShowIds = currentRecordings.Select(i => i.ShowId).ToList(); -- cgit v1.2.3 From b7ca126410ea865dacaaa38212e226e4569aa6f2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 17 Aug 2015 14:04:58 -0400 Subject: fix cloud sync playback --- .../Sync/SyncedMediaSourceProvider.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs index 524bf9294..efd37fa00 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs @@ -97,12 +97,11 @@ namespace MediaBrowser.Server.Implementations.Sync } // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message. - private const char StreamIdDelimeter = '_'; - private const string StreamIdDelimeterString = "|"; + private const string StreamIdDelimeterString = "_"; public async Task OpenMediaSource(string openToken, CancellationToken cancellationToken) { - var openKeys = openToken.Split(new[] { StreamIdDelimeter }, 3); + var openKeys = openToken.Split(new[] { StreamIdDelimeterString[0] }, 3); var provider = _syncManager.ServerSyncProviders .FirstOrDefault(i => string.Equals(openKeys[0], i.GetType().FullName.GetMD5().ToString("N"), StringComparison.OrdinalIgnoreCase)); -- cgit v1.2.3 From 51f69bcb312b19952ef87ea81c4128bb4ac21ad0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 18 Aug 2015 00:22:45 -0400 Subject: update detail page --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 10 +++------- .../LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs | 6 ++++++ MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 14c3887df..a28e3faec 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -615,11 +615,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private ProgramInfo GetProgramInfoFromCache(string channelId, string programId) { var epgData = GetEpgDataForChannel(channelId); - if (epgData.Any()) - { - return epgData.FirstOrDefault(p => p.Id == programId); - } - return null; + return epgData.FirstOrDefault(p => string.Equals(p.Id, programId, StringComparison.OrdinalIgnoreCase)); } private string RecordingPath @@ -670,9 +666,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV allPrograms = GetProgramsForSeries(seriesTimer, allPrograms); - var recordingShowIds = currentRecordings.Select(i => i.ShowId).ToList(); + var recordingShowIds = currentRecordings.Select(i => i.ProgramId).Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); - allPrograms = allPrograms.Where(epg => !recordingShowIds.Contains(epg.ShowId, StringComparer.OrdinalIgnoreCase)); + allPrograms = allPrograms.Where(i => !recordingShowIds.Contains(i.Id, StringComparer.OrdinalIgnoreCase)); return allPrograms.Select(i => RecordingHelper.CreateTimer(i, seriesTimer)); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index fca1bb012..db6e8de3f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -78,6 +78,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby { // They don't have dashes so try to normalize program.OfficialRating = info.rating.Replace("TV", "TV-").Replace("--", "-"); + + var invalid = new[] { "N/A", "Approved", "Not Rated" }; + if (invalid.Contains(program.OfficialRating, StringComparer.OrdinalIgnoreCase)) + { + program.OfficialRating = null; + } } if (!string.IsNullOrWhiteSpace(info.year)) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index a90fbaec8..412bb4742 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -742,9 +742,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 2f2ccfe8f3217c64a33c1e81c4516358f95c363a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 18 Aug 2015 11:25:57 -0400 Subject: update recordings --- MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 3 +++ MediaBrowser.Controller/LiveTv/RecordingInfo.cs | 6 ++++++ .../LiveTv/EmbyTV/EmbyTV.cs | 4 +++- .../LiveTv/LiveTvManager.cs | 14 +++++++++++--- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 2 +- 5 files changed, 24 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 1dd267c93..9fc60beb9 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -42,5 +42,8 @@ namespace MediaBrowser.Controller.LiveTv RecordingStatus Status { get; set; } DateTime? EndDate { get; set; } ChannelType ChannelType { get; set; } + DateTime DateLastSaved { get; set; } + DateTime DateCreated { get; set; } + DateTime DateModified { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index 42064cf50..3006b9bbe 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -191,6 +191,12 @@ namespace MediaBrowser.Controller.LiveTv /// The show identifier. public string ShowId { get; set; } + /// + /// Gets or sets the date last updated. + /// + /// The date last updated. + public DateTime DateLastUpdated { get; set; } + public RecordingInfo() { Genres = new List(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index a28e3faec..51476e296 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -576,6 +576,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recording.Path = recordPath; recording.Status = RecordingStatus.InProgress; + recording.DateLastUpdated = DateTime.UtcNow; _recordingProvider.Update(recording); try @@ -598,7 +599,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } catch (OperationCanceledException) { - _logger.Info("Recording cancelled"); + _logger.Info("Recording stopped"); recording.Status = RecordingStatus.Completed; } catch (Exception ex) @@ -607,6 +608,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recording.Status = RecordingStatus.Error; } + recording.DateLastUpdated = DateTime.UtcNow; _recordingProvider.Update(recording); _timerProvider.Delete(timer); _logger.Info("Recording was a success"); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 1280c52b1..4c44f5c3b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1,6 +1,8 @@ -using MediaBrowser.Common; +using System.IO; +using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; @@ -61,8 +63,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly List _tunerHosts = new List(); private readonly List _listingProviders = new List(); + private readonly IFileSystem _fileSystem; - public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager) + public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager, IFileSystem fileSystem) { _config = config; _logger = logger; @@ -73,6 +76,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv _localization = localization; _jsonSerializer = jsonSerializer; _providerManager = providerManager; + _fileSystem = fileSystem; _dtoService = dtoService; _userDataManager = userDataManager; @@ -729,6 +733,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (!string.IsNullOrEmpty(info.Path)) { item.Path = info.Path; + var fileInfo = new FileInfo(info.Path); + + recording.DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo); + recording.DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo); } else if (!string.IsNullOrEmpty(info.Url)) { @@ -741,7 +749,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); } - else if (pathChanged) + else if (pathChanged || info.DateLastUpdated > recording.DateLastSaved) { await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 60ff36c6d..9ecd0764a 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -496,7 +496,7 @@ namespace MediaBrowser.Server.Startup.Common PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("PlaylistManager"), UserManager, ProviderManager); RegisterSingleInstance(PlaylistManager); - LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager); + LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager, FileSystemManager); RegisterSingleInstance(LiveTvManager); UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, PlaylistManager, CollectionManager, ServerConfigurationManager); -- cgit v1.2.3 From 865b3b6fbe9dc578e5db00e21e2f1bd5b46cf71b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 18 Aug 2015 12:32:18 -0400 Subject: update recording days --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 51476e296..cd166ddd3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -692,7 +692,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV allPrograms = allPrograms.Where(epg => string.Equals(epg.ChannelId, seriesTimer.ChannelId, StringComparison.OrdinalIgnoreCase)); } - allPrograms = allPrograms.Where(i => seriesTimer.Days.Contains(i.StartDate.DayOfWeek)); + allPrograms = allPrograms.Where(i => seriesTimer.Days.Contains(i.StartDate.ToLocalTime().DayOfWeek)); if (string.IsNullOrWhiteSpace(seriesTimer.SeriesId)) { -- cgit v1.2.3 From ede3746ea7772b09b740ae59f19c9e7343458534 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 18 Aug 2015 15:45:41 -0400 Subject: don't duplicate synced items --- .../Sync/IServerSyncProvider.cs | 11 +++++++ .../Listings/Emby/EmbyListingsNorthAmerica.cs | 8 ++++- .../Sync/AppSyncProvider.cs | 7 ++++- .../Sync/SyncJobProcessor.cs | 36 ++++++++++++++++++++++ .../Sync/SyncManager.cs | 15 +++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs index 860c736ea..36ad27290 100644 --- a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs +++ b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs @@ -63,4 +63,15 @@ namespace MediaBrowser.Controller.Sync /// Task<SyncedFileInfo>. Task SendFile(string path, string[] pathParts, SyncTarget target, IProgress progress, CancellationToken cancellationToken); } + + public interface IHasDuplicateCheck + { + /// + /// Allows the duplicate job item. + /// + /// The original. + /// The duplicate. + /// true if XXXX, false otherwise. + bool AllowDuplicateJobItem(SyncJobItem original, SyncJobItem duplicate); + } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs index db6e8de3f..2993740d6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -50,7 +50,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby { Id = info.listingID.ToString(CultureInfo.InvariantCulture), Name = GetStringValue(info.showName), - EpisodeTitle = GetStringValue(info.episodeTitle), HomePageUrl = GetStringValue(info.webLink), Overview = info.description, IsHD = info.hd, @@ -101,6 +100,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby program.SeriesId = info.seriesID.ToString(CultureInfo.InvariantCulture); program.IsSeries = true; program.IsRepeat = info.repeat; + + program.EpisodeTitle = GetStringValue(info.episodeTitle); + + if (string.Equals(program.Name, program.EpisodeTitle, StringComparison.OrdinalIgnoreCase)) + { + program.EpisodeTitle = null; + } } if (info.starRating > 0) diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs index 7b1fa4dec..03485012f 100644 --- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs @@ -9,7 +9,7 @@ using System.Linq; namespace MediaBrowser.Server.Implementations.Sync { - public class AppSyncProvider : ISyncProvider, IHasUniqueTargetIds, IHasSyncQuality + public class AppSyncProvider : ISyncProvider, IHasUniqueTargetIds, IHasSyncQuality, IHasDuplicateCheck { private readonly IDeviceManager _deviceManager; @@ -104,5 +104,10 @@ namespace MediaBrowser.Server.Implementations.Sync IsConverting = isConverting }; } + + public bool AllowDuplicateJobItem(SyncJobItem original, SyncJobItem duplicate) + { + return false; + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 04ebcd903..1061a373e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -466,6 +466,32 @@ namespace MediaBrowser.Server.Implementations.Sync return; } + // See if there's already another active job item for the same target + var existingJobItems = _syncManager.GetJobItems(new SyncJobItemQuery + { + AddMetadata = false, + ItemId = jobItem.ItemId, + TargetId = job.TargetId, + Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring } + }); + + var duplicateJobItems = existingJobItems.Items + .Where(i => !string.Equals(i.Id, jobItem.Id, StringComparison.OrdinalIgnoreCase)) + .ToList(); + + if (duplicateJobItems.Count > 0) + { + var syncProvider = _syncManager.GetSyncProvider(jobItem, job) as IHasDuplicateCheck; + + if (!duplicateJobItems.Any(i => AllowDuplicateJobItem(syncProvider, i, jobItem))) + { + _logger.Debug("Cancelling sync job item because there is already another active job for the same target."); + jobItem.Status = SyncJobItemStatus.Cancelled; + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); + return; + } + } + var video = item as Video; if (video != null) { @@ -488,6 +514,16 @@ namespace MediaBrowser.Server.Implementations.Sync } } + private bool AllowDuplicateJobItem(IHasDuplicateCheck provider, SyncJobItem original, SyncJobItem duplicate) + { + if (provider != null) + { + return provider.AllowDuplicateJobItem(original, duplicate); + } + + return true; + } + private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) { var jobOptions = _syncManager.GetVideoOptions(jobItem, job); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 5bd35a325..18fcb4e79 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1159,6 +1159,21 @@ namespace MediaBrowser.Server.Implementations.Sync return options; } + public ISyncProvider GetSyncProvider(SyncJobItem jobItem, SyncJob job) + { + foreach (var provider in _providers) + { + foreach (var target in GetSyncTargets(provider)) + { + if (string.Equals(target.Id, jobItem.TargetId, StringComparison.OrdinalIgnoreCase)) + { + return provider; + } + } + } + return null; + } + public SyncJobOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job) { var options = GetSyncJobOptions(jobItem.TargetId, job.Profile, job.Quality); -- cgit v1.2.3 From 615d1e2a53c9079e6b13789cbaa0410d9039f435 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 19 Aug 2015 02:12:58 -0400 Subject: update detail page --- MediaBrowser.Controller/LiveTv/ProgramInfo.cs | 17 ++++- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 13 ++++ .../LiveTv/Listings/SchedulesDirect.cs | 84 +++++++++++----------- .../LiveTv/LiveTvManager.cs | 26 ++----- 4 files changed, 75 insertions(+), 65 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index 3f8fc639f..467264e7a 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -33,6 +33,11 @@ namespace MediaBrowser.Controller.LiveTv /// /// The overview. public string Overview { get; set; } + /// + /// Gets or sets the short overview. + /// + /// The short overview. + public string ShortOverview { get; set; } /// /// The start date of the program, in UTC. @@ -165,7 +170,17 @@ namespace MediaBrowser.Controller.LiveTv /// /// The show identifier. public string ShowId { get; set; } - + /// + /// Gets or sets the season number. + /// + /// The season number. + public int? SeasonNumber { get; set; } + /// + /// Gets or sets the episode number. + /// + /// The episode number. + public int? EpisodeNumber { get; set; } + public ProgramInfo() { Genres = new List(); diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index 25514f1dc..390f44267 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -193,6 +193,9 @@ namespace MediaBrowser.Dlna.Didl if (string.Equals(subtitleMode, "CaptionInfoEx", StringComparison.OrdinalIgnoreCase)) { + // http://192.168.1.3:9999/video.srt + // http://192.168.1.3:9999/video.srt + //var res = container.OwnerDocument.CreateElement("SEC", "CaptionInfoEx"); //res.InnerText = info.Url; @@ -201,6 +204,16 @@ namespace MediaBrowser.Dlna.Didl //res.SetAttribute("type", info.Format.ToLower()); //container.AppendChild(res); } + else if (string.Equals(subtitleMode, "smi", StringComparison.OrdinalIgnoreCase)) + { + var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); + + res.InnerText = info.Url; + + res.SetAttribute("protocolInfo", "http-get:*:smi/caption:*"); + + container.AppendChild(res); + } else { var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index c536d0e83..230a79775 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -132,6 +132,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { StreamReader innerReader = new StreamReader(innerResponse.Content); responseString = innerReader.ReadToEnd(); + var programDetails = _jsonSerializer.DeserializeFromString>( responseString); @@ -142,10 +143,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings var schedules = dailySchedules.SelectMany(d => d.programs); foreach (ScheduleDirect.Program schedule in schedules) { - _logger.Debug("Proccesing Schedule for statio ID " + stationID + - " which corresponds to channel " + channelNumber + " and program id " + - schedule.programID + " which says it has images? " + - programDict[schedule.programID].hasImageArtwork); + //_logger.Debug("Proccesing Schedule for statio ID " + stationID + + // " which corresponds to channel " + channelNumber + " and program id " + + // schedule.programID + " which says it has images? " + + // programDict[schedule.programID].hasImageArtwork); var imageIndex = images.FindIndex(i => i.programID == schedule.programID.Substring(0, 10)); if (imageIndex > -1) @@ -244,7 +245,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings CultureInfo.InvariantCulture); DateTime endAt = startAt.AddSeconds(programInfo.duration); ProgramAudio audioType = ProgramAudio.Stereo; - bool hdtv = false; + bool repeat = (programInfo.@new == null); string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channel; @@ -268,43 +269,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } } - if ((programInfo.videoProperties != null)) - { - hdtv = programInfo.videoProperties.Exists(item => item == "hdtv"); - } - - string desc = ""; - if (details.descriptions != null) - { - if (details.descriptions.description1000 != null) - { - desc = details.descriptions.description1000[0].description; - } - else if (details.descriptions.description100 != null) - { - desc = details.descriptions.description100[0].description; - } - } - ScheduleDirect.Gracenote gracenote; string episodeTitle = null; - if (details.metadata != null) - { - gracenote = details.metadata.Find(x => x.Gracenote != null).Gracenote; - if ((details.showType ?? "No ShowType") == "Series") - { - episodeTitle = "Season: " + gracenote.season + " Episode: " + gracenote.episode; - } - } if (details.episodeTitle150 != null) { - episodeTitle = ((episodeTitle ?? string.Empty) + " " + details.episodeTitle150).Trim(); + episodeTitle = details.episodeTitle150; } - var imageLink = ""; + string imageUrl = null; if (details.hasImageArtwork) { - imageLink = details.images; + imageUrl = details.images; } var showType = details.showType ?? string.Empty; @@ -313,7 +288,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { ChannelId = channel, Id = newID, - Overview = desc, StartDate = startAt, EndDate = endAt, Name = details.titles[0].title120 ?? "Unkown", @@ -321,23 +295,48 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings CommunityRating = null, EpisodeTitle = episodeTitle, Audio = audioType, - IsHD = hdtv, IsRepeat = repeat, IsSeries = showType.IndexOf("series", StringComparison.OrdinalIgnoreCase) != -1, - ImageUrl = imageLink, + ImageUrl = imageUrl, HasImage = details.hasImageArtwork, - IsNews = false, - IsKids = false, + IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase), IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1, - IsLive = false, IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1, - IsPremiere = false, ShowId = programInfo.programID }; + if (programInfo.videoProperties != null) + { + info.IsHD = programInfo.videoProperties.Contains("hdtv", StringComparer.OrdinalIgnoreCase); + } + + if (details.contentRating != null && details.contentRating.Count > 0) + { + info.OfficialRating = details.contentRating[0].code.Replace("TV", "TV-").Replace("--", "-"); + } + + if (details.descriptions != null) + { + if (details.descriptions.description1000 != null) + { + info.Overview = details.descriptions.description1000[0].description; + } + else if (details.descriptions.description100 != null) + { + info.ShortOverview = details.descriptions.description100[0].description; + } + } + if (info.IsSeries) { info.SeriesId = programInfo.programID.Substring(0, 10); + + if (details.metadata != null) + { + var gracenote = details.metadata.Find(x => x.Gracenote != null).Gracenote; + info.SeasonNumber = gracenote.season; + info.EpisodeNumber = gracenote.episode; + } } if (!string.IsNullOrWhiteSpace(details.originalAirDate)) @@ -349,8 +348,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { info.Genres = details.genres.Where(g => !string.IsNullOrWhiteSpace(g)).ToList(); info.IsNews = details.genres.Contains("news", StringComparer.OrdinalIgnoreCase); - info.IsKids = false; } + return info; } @@ -888,6 +887,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings public class ProgramDetails { + public string audience { get; set; } public string programID { get; set; } public List titles { get; set; } public EventDetails eventDetails { get; set; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 4c44f5c3b..26007f145 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -632,6 +632,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; + item.IndexNumber = info.EpisodeNumber; + item.ParentIndexNumber = info.SeasonNumber; + if (isNew) { await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); @@ -641,24 +644,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } - var maxStartDate = DateTime.UtcNow.AddDays(3); - - _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions - { - ImageRefreshMode = info.StartDate <= maxStartDate ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly - }); + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); return item; } - private void RefreshIfNeeded(LiveTvProgram program) - { - if (_refreshedPrograms.TryAdd(program.Id, program.Id)) - { - _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions()); - } - } - private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken) { var isNew = false; @@ -763,8 +753,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var program = GetInternalProgram(id); - RefreshIfNeeded(program); - var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user); await AddRecordingInfo(new[] { dto }, cancellationToken).ConfigureAwait(false); @@ -832,7 +820,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv var returnArray = returnPrograms .Select(i => { - RefreshIfNeeded(i); return _dtoService.GetBaseItemDto(i, options, user); }) .ToArray(); @@ -907,11 +894,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv var returnArray = programList.ToArray(); - foreach (var program in returnArray) - { - RefreshIfNeeded(program); - } - var result = new QueryResult<LiveTvProgram> { Items = returnArray, -- cgit v1.2.3 From e5aea2b622d36e38380ac7e97bfb653931253e77 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 19 Aug 2015 12:43:23 -0400 Subject: pool tuners --- MediaBrowser.Controller/LiveTv/ITunerHost.cs | 6 +-- .../Movies/GenericMovieDbInfo.cs | 33 +++++++----- MediaBrowser.Providers/Omdb/OmdbItemProvider.cs | 4 +- MediaBrowser.Providers/Omdb/OmdbProvider.cs | 8 ++- .../LiveTv/EmbyTV/EmbyTV.cs | 8 +-- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 61 ++++++++++++++++++++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 62 +++++++++++++++++----- 7 files changed, 142 insertions(+), 40 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs index a6c8021d9..0d1852fe2 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -21,17 +21,15 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the channels. /// </summary> - /// <param name="info">The information.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<IEnumerable<ChannelInfo>>.</returns> - Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo info, CancellationToken cancellationToken); + Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken); /// <summary> /// Gets the tuner infos. /// </summary> - /// <param name="info">The information.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<List<LiveTvTunerInfo>>.</returns> - Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken); + Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken); /// <summary> /// Gets the channel stream. /// </summary> diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index 5b5afc6c7..f5ee33d6b 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -185,18 +185,25 @@ namespace MediaBrowser.Providers.Movies //release date and certification are retrieved based on configured country and we fall back on US if not there and to minimun release date if still no match if (movieData.releases != null && movieData.releases.countries != null) { - var ourRelease = movieData.releases.countries.FirstOrDefault(c => c.iso_3166_1.Equals(preferredCountryCode, StringComparison.OrdinalIgnoreCase)) ?? new MovieDbProvider.Country(); - var usRelease = movieData.releases.countries.FirstOrDefault(c => c.iso_3166_1.Equals("US", StringComparison.OrdinalIgnoreCase)) ?? new MovieDbProvider.Country(); - var minimunRelease = movieData.releases.countries.OrderBy(c => c.release_date).FirstOrDefault() ?? new MovieDbProvider.Country(); - - var ratingPrefix = string.Equals(preferredCountryCode, "us", StringComparison.OrdinalIgnoreCase) ? "" : preferredCountryCode + "-"; - movie.OfficialRating = !string.IsNullOrEmpty(ourRelease.certification) - ? ratingPrefix + ourRelease.certification - : !string.IsNullOrEmpty(usRelease.certification) - ? usRelease.certification - : !string.IsNullOrEmpty(minimunRelease.certification) - ? minimunRelease.iso_3166_1 + "-" + minimunRelease.certification - : null; + var releases = movieData.releases.countries.Where(i => !string.IsNullOrWhiteSpace(i.certification)).ToList(); + + var ourRelease = releases.FirstOrDefault(c => c.iso_3166_1.Equals(preferredCountryCode, StringComparison.OrdinalIgnoreCase)); + var usRelease = releases.FirstOrDefault(c => c.iso_3166_1.Equals("US", StringComparison.OrdinalIgnoreCase)); + var minimunRelease = releases.OrderBy(c => c.release_date).FirstOrDefault(); + + if (ourRelease != null) + { + var ratingPrefix = string.Equals(preferredCountryCode, "us", StringComparison.OrdinalIgnoreCase) ? "" : preferredCountryCode + "-"; + movie.OfficialRating = ratingPrefix + ourRelease.certification; + } + else if (usRelease != null) + { + movie.OfficialRating = usRelease.certification; + } + else if (minimunRelease != null) + { + movie.OfficialRating = minimunRelease.iso_3166_1 + "-" + minimunRelease.certification; + } } if (!string.IsNullOrWhiteSpace(movieData.release_date)) @@ -232,7 +239,7 @@ namespace MediaBrowser.Providers.Movies } resultItem.ResetPeople(); - + //Actors, Directors, Writers - all in People //actors come from cast if (movieData.casts != null && movieData.casts.cast != null) diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index dffabd83c..36e7697d7 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -172,7 +172,7 @@ namespace MediaBrowser.Providers.Omdb result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, cancellationToken).ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); } return result; @@ -211,7 +211,7 @@ namespace MediaBrowser.Providers.Omdb result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, cancellationToken).ConfigureAwait(false); + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); } return result; diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index 9208031f3..c7ce57fca 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Providers.Omdb Current = this; } - public async Task Fetch(BaseItem item, string imdbId, string language, CancellationToken cancellationToken) + public async Task Fetch(BaseItem item, string imdbId, string language, string country, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(imdbId)) { @@ -55,7 +55,11 @@ namespace MediaBrowser.Providers.Omdb if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) { item.Name = result.Title; - item.OfficialRating = result.Rated; + + if (string.Equals(country, "us", StringComparison.OrdinalIgnoreCase)) + { + item.OfficialRating = result.Rated; + } } int year; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index cd166ddd3..eb23fab80 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -88,11 +88,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var status = new LiveTvServiceStatusInfo(); var list = new List<LiveTvTunerInfo>(); - foreach (var hostInstance in GetTunerHosts()) + foreach (var hostInstance in _liveTvManager.TunerHosts) { try { - var tuners = await hostInstance.Item1.GetTunerInfos(hostInstance.Item2, cancellationToken).ConfigureAwait(false); + var tuners = await hostInstance.GetTunerInfos(cancellationToken).ConfigureAwait(false); list.AddRange(tuners); } @@ -120,11 +120,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var list = new List<ChannelInfo>(); - foreach (var hostInstance in GetTunerHosts()) + foreach (var hostInstance in _liveTvManager.TunerHosts) { try { - var channels = await hostInstance.Item1.GetChannels(hostInstance.Item2, cancellationToken).ConfigureAwait(false); + var channels = await hostInstance.GetChannels(cancellationToken).ConfigureAwait(false); list.AddRange(channels); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 35f77abcb..7607d5b9d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -49,7 +49,46 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private const string ChannelIdPrefix = "hdhr_"; - public async Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) + private List<TunerHostInfo> GetTunerHosts() + { + return GetConfiguration().TunerHosts + .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) + .ToList(); + } + + public async Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken) + { + var list = new List<ChannelInfo>(); + + var hosts = GetTunerHosts(); + + var ipAddresses = new List<string>(); + + foreach (var host in hosts) + { + var ip = GetApiUrl(host, false); + + if (ipAddresses.Contains(ip, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + + try + { + list.AddRange(await GetChannels(host, cancellationToken).ConfigureAwait(false)); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting channel list", ex); + } + + ipAddresses.Add(ip); + } + + return list; + } + + private async Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) { var options = new HttpRequestOptions { @@ -146,6 +185,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun } } + public async Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) + { + var list = new List<LiveTvTunerInfo>(); + + foreach (var host in GetConfiguration().TunerHosts + .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase))) + { + try + { + list.AddRange(await GetTunerInfos(host, cancellationToken).ConfigureAwait(false)); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting tuner info", ex); + } + } + + return list; + } + private string GetApiUrl(TunerHostInfo info, bool isPlayback) { var url = info.Url; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 0755d2a39..ec05cefd5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; @@ -27,20 +28,52 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } private readonly IConfigurationManager _config; + private readonly ILogger _logger; - public M3UTunerHost(IConfigurationManager config) + public M3UTunerHost(IConfigurationManager config, ILogger logger) { _config = config; + _logger = logger; } - public Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) + private List<TunerHostInfo> GetTunerHosts() { - var urlHash = info.Url.GetMD5().ToString("N"); - + return GetConfiguration().TunerHosts + .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) + .ToList(); + } + + public async Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken) + { + var list = new List<ChannelInfo>(); + + var urls = GetTunerHosts().Select(i => i.Url) + .Where(i => !string.IsNullOrWhiteSpace(i)) + .Distinct(StringComparer.OrdinalIgnoreCase); + + foreach (var url in urls) + { + try + { + list.AddRange(await GetChannels(url, cancellationToken).ConfigureAwait(false)); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting channel list", ex); + } + } + + return list; + } + + private Task<IEnumerable<ChannelInfo>> GetChannels(string url, CancellationToken cancellationToken) + { + var urlHash = url.GetMD5().ToString("N"); + int position = 0; string line; // Read the file and display it line by line. - var file = new StreamReader(info.Url); + var file = new StreamReader(url); var channels = new List<M3UChannel>(); while ((line = file.ReadLine()) != null) { @@ -105,19 +138,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return Task.FromResult((IEnumerable<ChannelInfo>)channels); } - public Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) + public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) { - var list = new List<LiveTvTunerInfo>(); - - list.Add(new LiveTvTunerInfo() + var list = GetConfiguration().TunerHosts + .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) + .Select(i => new LiveTvTunerInfo() { Name = Name, SourceType = Type, Status = LiveTvTunerStatus.Available, - Id = info.Url.GetMD5().ToString("N"), - Url = info.Url - }); - + Id = i.Url.GetMD5().ToString("N"), + Url = i.Url + }) + .ToList(); + return Task.FromResult(list); } @@ -136,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts channelId = channelId.Substring(urlHash.Length); - var channels = await GetChannels(info, cancellationToken).ConfigureAwait(false); + var channels = await GetChannels(info.Url, cancellationToken).ConfigureAwait(false); var m3uchannels = channels.Cast<M3UChannel>(); var channel = m3uchannels.FirstOrDefault(c => c.Id == channelId); if (channel != null) -- cgit v1.2.3 From 2c050d05f8872da16d4b634a13d73b88ca5bafd4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 19 Aug 2015 13:58:41 -0400 Subject: add base tuner host --- .../LiveTv/Listings/SchedulesDirect.cs | 5 ++ .../LiveTv/TunerHosts/BaseTunerHost.cs | 97 ++++++++++++++++++++++ .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 60 ++----------- .../LiveTv/TunerHosts/M3UTunerHost.cs | 59 +++---------- .../MediaBrowser.Server.Implementations.csproj | 1 + 5 files changed, 119 insertions(+), 103 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 230a79775..66053041c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -348,6 +348,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { info.Genres = details.genres.Where(g => !string.IsNullOrWhiteSpace(g)).ToList(); info.IsNews = details.genres.Contains("news", StringComparer.OrdinalIgnoreCase); + + if (info.Genres.Contains("children", StringComparer.OrdinalIgnoreCase)) + { + info.IsKids = true; + } } return info; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs new file mode 100644 index 000000000..b3c8bce26 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -0,0 +1,97 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts +{ + public abstract class BaseTunerHost + { + protected readonly IConfigurationManager Config; + protected readonly ILogger Logger; + + private readonly ConcurrentDictionary<string, ChannelCache> _channelCache = + new ConcurrentDictionary<string, ChannelCache>(StringComparer.OrdinalIgnoreCase); + + public BaseTunerHost(IConfigurationManager config, ILogger logger) + { + Config = config; + Logger = logger; + } + + protected abstract Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken); + public abstract string Type { get; } + + public async Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo tuner, bool enableCache, CancellationToken cancellationToken) + { + ChannelCache cache = null; + + if (enableCache && _channelCache.TryGetValue(tuner.Id, out cache)) + { + if ((DateTime.UtcNow - cache.Date) < TimeSpan.FromMinutes(60)) + { + return cache.Channels.ToList(); + } + } + + var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); + + cache = cache ?? new ChannelCache(); + + cache.Date = DateTime.UtcNow; + cache.Channels = result.ToList(); + + _channelCache.AddOrUpdate(tuner.Id, cache, (k, v) => cache); + + return cache.Channels.ToList(); + } + + private List<TunerHostInfo> GetTunerHosts() + { + return GetConfiguration().TunerHosts + .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) + .ToList(); + } + + public async Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken) + { + var list = new List<ChannelInfo>(); + + var hosts = GetTunerHosts(); + + foreach (var host in hosts) + { + try + { + var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false); + var newChannels = channels.Where(i => !list.Any(l => string.Equals(i.Id, l.Id, StringComparison.OrdinalIgnoreCase))).ToList(); + + list.AddRange(newChannels); + } + catch (Exception ex) + { + Logger.ErrorException("Error getting channel list", ex); + } + } + + return list; + } + + protected LiveTvOptions GetConfiguration() + { + return Config.GetConfiguration<LiveTvOptions>("livetv"); + } + + private class ChannelCache + { + public DateTime Date; + public List<ChannelInfo> Channels; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 7607d5b9d..a07ccd3a4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -17,19 +17,15 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { - public class HdHomerunHost : ITunerHost + public class HdHomerunHost : BaseTunerHost, ITunerHost { private readonly IHttpClient _httpClient; - private readonly ILogger _logger; private readonly IJsonSerializer _jsonSerializer; - private readonly IConfigurationManager _config; - public HdHomerunHost(IHttpClient httpClient, ILogger logger, IJsonSerializer jsonSerializer, IConfigurationManager config) + public HdHomerunHost(IConfigurationManager config, ILogger logger, IHttpClient httpClient, IJsonSerializer jsonSerializer) : base(config, logger) { _httpClient = httpClient; - _logger = logger; _jsonSerializer = jsonSerializer; - _config = config; } public string Name @@ -37,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun get { return "HD Homerun"; } } - public string Type + public override string Type { get { return DeviceType; } } @@ -49,46 +45,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private const string ChannelIdPrefix = "hdhr_"; - private List<TunerHostInfo> GetTunerHosts() - { - return GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - - public async Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken) - { - var list = new List<ChannelInfo>(); - - var hosts = GetTunerHosts(); - - var ipAddresses = new List<string>(); - - foreach (var host in hosts) - { - var ip = GetApiUrl(host, false); - - if (ipAddresses.Contains(ip, StringComparer.OrdinalIgnoreCase)) - { - continue; - } - - try - { - list.AddRange(await GetChannels(host, cancellationToken).ConfigureAwait(false)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting channel list", ex); - } - - ipAddresses.Add(ip); - } - - return list; - } - - private async Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) + protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { var options = new HttpRequestOptions { @@ -198,7 +155,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun } catch (Exception ex) { - _logger.ErrorException("Error getting tuner info", ex); + Logger.ErrorException("Error getting tuner info", ex); } } @@ -263,11 +220,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public bool DRM { get; set; } } - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration<LiveTvOptions>("livetv"); - } - private MediaSourceInfo GetMediaSource(TunerHostInfo info, string channelId, string profile) { int? width = null; @@ -425,7 +377,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public async Task Validate(TunerHostInfo info) { - await GetChannels(info, CancellationToken.None).ConfigureAwait(false); + await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index ec05cefd5..0dc170cfd 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -15,59 +15,25 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { - public class M3UTunerHost : ITunerHost + public class M3UTunerHost : BaseTunerHost, ITunerHost { - public string Type + public M3UTunerHost(IConfigurationManager config, ILogger logger) : base(config, logger) { - get { return "m3u"; } } - public string Name - { - get { return "M3U Tuner"; } - } - - private readonly IConfigurationManager _config; - private readonly ILogger _logger; - - public M3UTunerHost(IConfigurationManager config, ILogger logger) + public override string Type { - _config = config; - _logger = logger; - } - - private List<TunerHostInfo> GetTunerHosts() - { - return GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) - .ToList(); + get { return "m3u"; } } - public async Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken) + public string Name { - var list = new List<ChannelInfo>(); - - var urls = GetTunerHosts().Select(i => i.Url) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase); - - foreach (var url in urls) - { - try - { - list.AddRange(await GetChannels(url, cancellationToken).ConfigureAwait(false)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting channel list", ex); - } - } - - return list; + get { return "M3U Tuner"; } } - private Task<IEnumerable<ChannelInfo>> GetChannels(string url, CancellationToken cancellationToken) + protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { + var url = info.Url; var urlHash = url.GetMD5().ToString("N"); int position = 0; @@ -135,7 +101,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } } file.Close(); - return Task.FromResult((IEnumerable<ChannelInfo>)channels); + return channels; } public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) @@ -155,11 +121,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(list); } - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration<LiveTvOptions>("livetv"); - } - public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { var urlHash = info.Url.GetMD5().ToString("N"); @@ -170,7 +131,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts channelId = channelId.Substring(urlHash.Length); - var channels = await GetChannels(info.Url, cancellationToken).ConfigureAwait(false); + var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false); var m3uchannels = channels.Cast<M3UChannel>(); var channel = m3uchannels.FirstOrDefault(c => c.Id == channelId); if (channel != null) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 2571f9b2c..824f3e856 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -231,6 +231,7 @@ <Compile Include="LiveTv\LiveTvDtoService.cs" /> <Compile Include="LiveTv\LiveTvManager.cs" /> <Compile Include="LiveTv\LiveTvMediaSourceProvider.cs" /> + <Compile Include="LiveTv\TunerHosts\BaseTunerHost.cs" /> <Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHost.cs" /> <Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunDiscovery.cs" /> <Compile Include="LiveTv\TunerHosts\M3UTunerHost.cs" /> -- cgit v1.2.3 From 8c32aefb53ed6684a9cd492662460e0fe7b83b0f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 19 Aug 2015 15:25:18 -0400 Subject: update tuner pooling --- MediaBrowser.Controller/LiveTv/ITunerHost.cs | 6 +- .../LiveTv/EmbyTV/EmbyTV.cs | 39 +------- .../LiveTv/TunerHosts/BaseTunerHost.cs | 107 ++++++++++++++++++++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 15 ++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 28 ++++-- 5 files changed, 146 insertions(+), 49 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs index 0d1852fe2..bedbcffe3 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -33,20 +33,18 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the channel stream. /// </summary> - /// <param name="info">The information.</param> /// <param name="channelId">The channel identifier.</param> /// <param name="streamId">The stream identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<MediaSourceInfo>.</returns> - Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken); + Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken); /// <summary> /// Gets the channel stream media sources. /// </summary> - /// <param name="info">The information.</param> /// <param name="channelId">The channel identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<List<MediaSourceInfo>>.</returns> - Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken); + Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); /// <summary> /// Validates the specified information. /// </summary> diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index eb23fab80..7fbff31b2 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Drawing; @@ -13,7 +12,6 @@ using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -161,20 +159,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return GetChannelsAsync(false, cancellationToken); } - private List<Tuple<ITunerHost, TunerHostInfo>> GetTunerHosts() - { - return GetConfiguration().TunerHosts - .Where(i => i.IsEnabled) - .Select(i => - { - var provider = _liveTvManager.TunerHosts.FirstOrDefault(l => string.Equals(l.Type, i.Type, StringComparison.OrdinalIgnoreCase)); - - return provider == null ? null : new Tuple<ITunerHost, TunerHostInfo>(provider, i); - }) - .Where(i => i != null) - .ToList(); - } - public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) { var timers = _timerProvider.GetAll().Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase)); @@ -409,22 +393,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { _logger.Info("Streaming Channel " + channelId); - foreach (var hostInstance in GetTunerHosts()) + foreach (var hostInstance in _liveTvManager.TunerHosts) { - if (!string.IsNullOrWhiteSpace(streamId)) - { - var originalStreamId = string.Join("-", streamId.Split('-').Skip(1).ToArray()); - - if (!string.Equals(hostInstance.Item2.Id, originalStreamId, StringComparison.OrdinalIgnoreCase)) - { - continue; - } - } - MediaSourceInfo mediaSourceInfo = null; try { - mediaSourceInfo = await hostInstance.Item1.GetChannelStream(hostInstance.Item2, channelId, streamId, cancellationToken).ConfigureAwait(false); + mediaSourceInfo = await hostInstance.GetChannelStream(channelId, streamId, cancellationToken).ConfigureAwait(false); } catch (Exception e) { @@ -443,16 +417,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken) { - foreach (var hostInstance in GetTunerHosts()) + foreach (var hostInstance in _liveTvManager.TunerHosts) { try { - var sources = await hostInstance.Item1.GetChannelStreamMediaSources(hostInstance.Item2, channelId, cancellationToken).ConfigureAwait(false); - - foreach (var source in sources) - { - source.Id = hostInstance.Item2.Id + "-" + source.Id; - } + var sources = await hostInstance.GetChannelStreamMediaSources(channelId, cancellationToken).ConfigureAwait(false); if (sources.Count > 0) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index b3c8bce26..fb6fa9084 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using System; @@ -83,11 +84,115 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return list; } + protected abstract Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken); + + public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken) + { + if (IsValidChannelId(channelId)) + { + var hosts = GetTunerHosts(); + + var hostsWithChannel = new List<TunerHostInfo>(); + + foreach (var host in hosts) + { + var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false); + + if (channels.Any(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase))) + { + hostsWithChannel.Add(host); + } + } + + foreach (var host in hostsWithChannel) + { + // Check to make sure the tuner is available + // If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error + if (hostsWithChannel.Count > 1 && !await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false)) + { + Logger.Error("Tuner is not currently available"); + continue; + } + + var mediaSources = await GetChannelStreamMediaSources(host, channelId, cancellationToken).ConfigureAwait(false); + + // Prefix the id with the host Id so that we can easily find it + foreach (var mediaSource in mediaSources) + { + mediaSource.Id = host.Id + mediaSource.Id; + } + + return mediaSources; + } + } + + return new List<MediaSourceInfo>(); + } + + protected abstract Task<MediaSourceInfo> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken); + + public async Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken) + { + if (IsValidChannelId(channelId)) + { + var hosts = GetTunerHosts(); + + var hostsWithChannel = new List<TunerHostInfo>(); + + foreach (var host in hosts) + { + if (string.IsNullOrWhiteSpace(streamId)) + { + var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false); + + if (channels.Any(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase))) + { + hostsWithChannel.Add(host); + } + } + else if (streamId.StartsWith(host.Id, StringComparison.OrdinalIgnoreCase)) + { + hostsWithChannel = new List<TunerHostInfo> { host }; + streamId = streamId.Substring(host.Id.Length); + break; + } + } + + foreach (var host in hostsWithChannel) + { + // Check to make sure the tuner is available + // If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error + // If a streamId is specified then availibility has already been checked in GetChannelStreamMediaSources + if (string.IsNullOrWhiteSpace(streamId) && hostsWithChannel.Count > 1) + { + if (!await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false)) + { + Logger.Error("Tuner is not currently available"); + continue; + } + } + + var stream = await GetChannelStream(host, channelId, streamId, cancellationToken).ConfigureAwait(false); + + if (stream != null) + { + return null; + } + } + } + + throw new LiveTvConflictException(); + } + + protected abstract Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken); + + protected abstract bool IsValidChannelId(string channelId); + protected LiveTvOptions GetConfiguration() { return Config.GetConfiguration<LiveTvOptions>("livetv"); } - + private class ChannelCache { public DateTime Date; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index a07ccd3a4..307a61588 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -329,7 +329,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return mediaSource; } - public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) + protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { var list = new List<MediaSourceInfo>(); @@ -364,7 +364,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return list; } - public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) + protected override bool IsValidChannelId(string channelId) + { + return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); + } + + protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) { @@ -379,5 +384,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false); } + + protected override async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + // TODO + return true; + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 0dc170cfd..bd0feb573 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -17,7 +17,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { public class M3UTunerHost : BaseTunerHost, ITunerHost { - public M3UTunerHost(IConfigurationManager config, ILogger logger) : base(config, logger) + public M3UTunerHost(IConfigurationManager config, ILogger logger) + : base(config, logger) { } @@ -31,6 +32,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts get { return "M3U Tuner"; } } + private const string ChannelIdPrefix = "m3u_"; + protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { var url = info.Url; @@ -88,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts switch (list[0]) { case "tvg-id": - channels.Last().Id = urlHash + list[1]; + channels.Last().Id = ChannelIdPrefix + urlHash + list[1]; channels.Last().Number = list[1]; break; case "tvg-name": @@ -117,19 +120,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts Url = i.Url }) .ToList(); - + return Task.FromResult(list); } - public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) + protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { var urlHash = info.Url.GetMD5().ToString("N"); - if (!channelId.StartsWith(urlHash, StringComparison.OrdinalIgnoreCase)) + var prefix = ChannelIdPrefix + urlHash; + if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { return null; } - channelId = channelId.Substring(urlHash.Length); + channelId = channelId.Substring(prefix.Length); var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false); var m3uchannels = channels.Cast<M3UChannel>(); @@ -196,9 +200,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } } - public Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) + protected override bool IsValidChannelId(string channelId) + { + return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); + } + + protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { throw new NotImplementedException(); } + + protected override Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + return Task.FromResult(true); + } } } -- cgit v1.2.3 From 3787af4c9c22af35a22fa599809221c70eed173d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 19 Aug 2015 19:57:27 -0400 Subject: update guide --- MediaBrowser.Api/Music/InstantMixService.cs | 3 +- MediaBrowser.Controller/Library/ILibraryManager.cs | 7 ++ MediaBrowser.Controller/Library/IMusicManager.cs | 4 +- .../Library/LibraryManager.cs | 86 ++++++++++------------ .../Library/MusicManager.cs | 6 +- .../LiveTv/LiveTvManager.cs | 14 ++-- .../LiveTv/TunerHosts/BaseTunerHost.cs | 17 ++++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 9 ++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 +- 9 files changed, 76 insertions(+), 72 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index 506b7bc3a..905ead86c 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -138,8 +138,9 @@ namespace MediaBrowser.Api.Music public object Get(GetInstantMixFromArtist request) { var user = _userManager.GetUserById(request.UserId); + var artist = _libraryManager.GetArtist(request.Name); - var items = _musicManager.GetInstantMixFromArtist(request.Name, user); + var items = _musicManager.GetInstantMixFromArtist(artist, user); return GetResult(items, user, request); } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 6906a25fb..9331ca759 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -502,5 +502,12 @@ namespace MediaBrowser.Controller.Library /// <param name="query">The query.</param> /// <returns>List<System.String>.</returns> List<string> GetPeopleNames(InternalPeopleQuery query); + + /// <summary> + /// Queries the items. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>QueryResult<BaseItem>.</returns> + QueryResult<BaseItem> QueryItems(InternalItemsQuery query); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Library/IMusicManager.cs b/MediaBrowser.Controller/Library/IMusicManager.cs index 0ce0687cc..9baf8b6f1 100644 --- a/MediaBrowser.Controller/Library/IMusicManager.cs +++ b/MediaBrowser.Controller/Library/IMusicManager.cs @@ -16,10 +16,10 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Gets the instant mix from artist. /// </summary> - /// <param name="name">The name.</param> + /// <param name="artist">The artist.</param> /// <param name="user">The user.</param> /// <returns>IEnumerable{Audio}.</returns> - IEnumerable<Audio> GetInstantMixFromArtist(string name, User user); + IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user); /// <summary> /// Gets the instant mix from genre. /// </summary> diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 0cfd38479..a67e3d732 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -3,12 +3,14 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; @@ -243,10 +245,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - /// <summary> - /// The _items by name path - /// </summary> - private string _itemsByNamePath; /// <summary> /// The _season zero display name /// </summary> @@ -260,7 +258,6 @@ namespace MediaBrowser.Server.Implementations.Library private void RecordConfigurationValues(ServerConfiguration configuration) { _seasonZeroDisplayName = configuration.SeasonZeroDisplayName; - _itemsByNamePath = ConfigurationManager.ApplicationPaths.ItemsByNamePath; _wizardCompleted = configuration.IsStartupWizardCompleted; } @@ -273,56 +270,24 @@ namespace MediaBrowser.Server.Implementations.Library { var config = ConfigurationManager.Configuration; - var ibnPathChanged = !string.Equals(_itemsByNamePath, ConfigurationManager.ApplicationPaths.ItemsByNamePath, StringComparison.Ordinal); - - if (ibnPathChanged) - { - RemoveItemsByNameFromCache(); - } - var newSeasonZeroName = ConfigurationManager.Configuration.SeasonZeroDisplayName; var seasonZeroNameChanged = !string.Equals(_seasonZeroDisplayName, newSeasonZeroName, StringComparison.Ordinal); var wizardChanged = config.IsStartupWizardCompleted != _wizardCompleted; RecordConfigurationValues(config); - Task.Run(async () => + if (seasonZeroNameChanged || wizardChanged) { - if (seasonZeroNameChanged) - { - await UpdateSeasonZeroNames(newSeasonZeroName, CancellationToken.None).ConfigureAwait(false); - } - - if (seasonZeroNameChanged || ibnPathChanged || wizardChanged) - { - _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>(); - } - }); - } + _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>(); + } - private void RemoveItemsByNameFromCache() - { - RemoveItemsFromCache(i => i is Person); - RemoveItemsFromCache(i => i is Year); - RemoveItemsFromCache(i => i is Genre); - RemoveItemsFromCache(i => i is MusicGenre); - RemoveItemsFromCache(i => i is GameGenre); - RemoveItemsFromCache(i => i is Studio); - RemoveItemsFromCache(i => + if (seasonZeroNameChanged) { - var artist = i as MusicArtist; - return artist != null && artist.IsAccessedByName; - }); - } - - private void RemoveItemsFromCache(Func<BaseItem, bool> remove) - { - var items = _libraryItemsCache.ToList().Where(i => remove(i.Value)).ToList(); + Task.Run(async () => + { + await UpdateSeasonZeroNames(newSeasonZeroName, CancellationToken.None).ConfigureAwait(false); - foreach (var item in items) - { - BaseItem value; - _libraryItemsCache.TryRemove(item.Key, out value); + }); } } @@ -374,6 +339,21 @@ namespace MediaBrowser.Server.Implementations.Library private void RegisterItem(Guid id, BaseItem item) { + if (item is LiveTvProgram) + { + return; + } + if (item is IChannelItem) + { + return; + } + if (item is IItemByName) + { + if (!(item is MusicArtist)) + { + return; + } + } LibraryItemsCache.AddOrUpdate(id, item, delegate { return item; }); } @@ -951,11 +931,14 @@ namespace MediaBrowser.Server.Implementations.Library DateModified = DateTime.UtcNow, Path = path }; - } - if (isArtist) - { - (item as MusicArtist).IsAccessedByName = true; + if (isArtist) + { + (item as MusicArtist).IsAccessedByName = true; + } + + var task = item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None); + Task.WaitAll(task); } return item; @@ -1259,6 +1242,11 @@ namespace MediaBrowser.Server.Implementations.Library }; } + public QueryResult<BaseItem> QueryItems(InternalItemsQuery query) + { + return ItemRepository.GetItems(query); + } + public List<Guid> GetItemIds(InternalItemsQuery query) { return ItemRepository.GetItemIdsList(query); diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index 1a9e98268..b83256342 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -27,10 +27,8 @@ namespace MediaBrowser.Server.Implementations.Library return list.Concat(GetInstantMixFromGenres(item.Genres, user)); } - public IEnumerable<Audio> GetInstantMixFromArtist(string name, User user) + public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user) { - var artist = _libraryManager.GetArtist(name); - var genres = user.RootFolder .GetRecursiveChildren(user, i => i is Audio) .Cast<Audio>() @@ -107,7 +105,7 @@ namespace MediaBrowser.Server.Implementations.Library var artist = item as MusicArtist; if (artist != null) { - return GetInstantMixFromArtist(artist.Name, user); + return GetInstantMixFromArtist(artist, user); } var song = item as Audio; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 26007f145..cabe04f0f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1,5 +1,4 @@ -using System.IO; -using MediaBrowser.Common; +using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; @@ -26,6 +25,7 @@ using MoreLinq; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -59,8 +59,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1); - private readonly ConcurrentDictionary<Guid, Guid> _refreshedPrograms = new ConcurrentDictionary<Guid, Guid>(); - private readonly List<ITunerHost> _tunerHosts = new List<ITunerHost>(); private readonly List<IListingsProvider> _listingProviders = new List<IListingsProvider>(); private readonly IFileSystem _fileSystem; @@ -253,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var now = DateTime.UtcNow; - var programs = _libraryManager.GetItems(new InternalItemsQuery + var programs = _libraryManager.QueryItems(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, MaxStartDate = now, @@ -799,7 +797,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - IEnumerable<LiveTvProgram> programs = _libraryManager.GetItems(internalQuery).Items.Cast<LiveTvProgram>(); + IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>(); programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending) .Cast<LiveTvProgram>(); @@ -869,7 +867,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - IEnumerable<LiveTvProgram> programs = _libraryManager.GetItems(internalQuery).Items.Cast<LiveTvProgram>(); + IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>(); var programList = programs.ToList(); @@ -1081,8 +1079,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false); await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false); - _refreshedPrograms.Clear(); - // Load these now which will prefetch metadata var dtoOptions = new DtoOptions(); dtoOptions.Fields.Remove(ItemFields.SyncInfo); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index fb6fa9084..649cecc85 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -176,7 +176,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts if (stream != null) { - return null; + return stream; } } } @@ -184,7 +184,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts throw new LiveTvConflictException(); } - protected abstract Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken); + protected async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + try + { + return await IsAvailableInternal(tuner, channelId, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.ErrorException("Error checking tuner availability", ex); + return false; + } + } + + protected abstract Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken); protected abstract bool IsValidChannelId(string channelId); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 307a61588..5890e24eb 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun var name = line.Substring(0, index - 1); var currentChannel = line.Substring(index + 7); if (currentChannel != "none") { status = LiveTvTunerStatus.LiveTv; } else { status = LiveTvTunerStatus.Available; } - tuners.Add(new LiveTvTunerInfo() + tuners.Add(new LiveTvTunerInfo { Name = name, SourceType = string.IsNullOrWhiteSpace(model) ? Name : model, @@ -385,10 +385,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false); } - protected override async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) { - // TODO - return true; + var info = await GetTunerInfos(tuner, cancellationToken).ConfigureAwait(false); + + return info.Any(i => i.Status == LiveTvTunerStatus.Available); } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index bd0feb573..e19b17ca4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -210,7 +210,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts throw new NotImplementedException(); } - protected override Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) { return Task.FromResult(true); } -- cgit v1.2.3 From 332b72f821e9927a2eb139be5af5821ceac1f3e5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 19 Aug 2015 22:22:47 -0400 Subject: update detail layout --- .../LiveTv/TunerHosts/BaseTunerHost.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index 649cecc85..87d750783 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -32,8 +32,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts public async Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo tuner, bool enableCache, CancellationToken cancellationToken) { ChannelCache cache = null; + var key = tuner.Id; - if (enableCache && _channelCache.TryGetValue(tuner.Id, out cache)) + if (enableCache && !string.IsNullOrWhiteSpace(key) && _channelCache.TryGetValue(key, out cache)) { if ((DateTime.UtcNow - cache.Date) < TimeSpan.FromMinutes(60)) { @@ -48,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts cache.Date = DateTime.UtcNow; cache.Channels = result.ToList(); - _channelCache.AddOrUpdate(tuner.Id, cache, (k, v) => cache); + _channelCache.AddOrUpdate(key, cache, (k, v) => cache); return cache.Channels.ToList(); } -- cgit v1.2.3 From bc41dcbc7e28c20b7090c413d7960f6744b085a0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Thu, 20 Aug 2015 13:40:11 -0400 Subject: update tuner saving --- .../LiveTv/TunerHosts/BaseTunerHost.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index 87d750783..909e2bba5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -43,15 +43,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); + var list = result.ToList(); - cache = cache ?? new ChannelCache(); - - cache.Date = DateTime.UtcNow; - cache.Channels = result.ToList(); - - _channelCache.AddOrUpdate(key, cache, (k, v) => cache); + if (!string.IsNullOrWhiteSpace(key)) + { + cache = cache ?? new ChannelCache(); + cache.Date = DateTime.UtcNow; + cache.Channels = list; + _channelCache.AddOrUpdate(key, cache, (k, v) => cache); + } - return cache.Channels.ToList(); + return list; } private List<TunerHostInfo> GetTunerHosts() -- cgit v1.2.3 From 6dba423c2c06f2d31c1788e048480e7723581559 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Thu, 20 Aug 2015 16:54:00 -0400 Subject: add tuner setup to startup wizard --- MediaBrowser.Api/StartupWizardService.cs | 53 ++++++++++++++++++++++ .../LiveTv/EmbyTV/EmbyTV.cs | 4 +- .../MediaBrowser.WebDashboard.csproj | 6 +++ 3 files changed, 61 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 277e02bf9..3cd6843b7 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -3,8 +3,10 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Connect; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.LiveTv; using ServiceStack; using System; using System.Linq; @@ -49,6 +51,7 @@ namespace MediaBrowser.Api private readonly IServerApplicationHost _appHost; private readonly IUserManager _userManager; private readonly IConnectManager _connectManager; + private ILiveTvManager _liveTvManager; public StartupWizardService(IServerConfigurationManager config, IServerApplicationHost appHost, IUserManager userManager, IConnectManager connectManager) { @@ -101,6 +104,9 @@ namespace MediaBrowser.Api _config.Configuration.MetadataCountryCode = request.MetadataCountryCode; _config.Configuration.PreferredMetadataLanguage = request.PreferredMetadataLanguage; _config.SaveConfiguration(); + + var task = UpdateTuners(request); + Task.WaitAll(task); } public object Get(GetStartupUser request) @@ -141,6 +147,51 @@ namespace MediaBrowser.Api return result; } + + private async Task UpdateTuners(UpdateStartupConfiguration request) + { + var config = GetLiveTVConfiguration(); + var save = false; + + if (string.IsNullOrWhiteSpace(request.LiveTvTunerPath) || + string.IsNullOrWhiteSpace(request.LiveTvTunerType)) + { + if (config.TunerHosts.Count > 0) + { + config.TunerHosts.Clear(); + save = true; + } + } + else + { + if (!config.TunerHosts.Any(i => string.Equals(i.Type, request.LiveTvTunerType, StringComparison.OrdinalIgnoreCase) && string.Equals(i.Url, request.LiveTvTunerPath, StringComparison.OrdinalIgnoreCase))) + { + // Add tuner + await _liveTvManager.SaveTunerHost(new TunerHostInfo + { + IsEnabled = true, + Type = request.LiveTvTunerType, + Url = request.LiveTvTunerPath + + }).ConfigureAwait(false); + } + } + + if (save) + { + SaveLiveTVConfiguration(config); + } + } + + private void SaveLiveTVConfiguration(LiveTvOptions config) + { + _config.SaveConfiguration("livetv", config); + } + + private LiveTvOptions GetLiveTVConfiguration() + { + return _config.GetConfiguration<LiveTvOptions>("livetv"); + } } public class StartupConfiguration @@ -150,6 +201,8 @@ namespace MediaBrowser.Api public bool SaveLocalMeta { get; set; } public string MetadataCountryCode { get; set; } public string PreferredMetadataLanguage { get; set; } + public string LiveTvTunerType { get; set; } + public string LiveTvTunerPath { get; set; } } public class StartupInfo diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 7fbff31b2..355597fcf 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -322,8 +322,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { var defaults = new SeriesTimerInfo() { - PostPaddingSeconds = 60, - PrePaddingSeconds = 60, + PostPaddingSeconds = 0, + PrePaddingSeconds = 0, RecordAnyChannel = false, RecordAnyTime = false, RecordNewOnly = false diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index a05cd1b63..5ee76bbd1 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -261,6 +261,9 @@ <Content Include="dashboard-ui\scripts\sharingwidget.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="dashboard-ui\scripts\wizardlivetvtuner.js"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="dashboard-ui\secondaryitems.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> @@ -1780,6 +1783,9 @@ <Content Include="dashboard-ui\wizardagreement.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="dashboard-ui\wizardlivetvtuner.html"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="dashboard-ui\wizardservice.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> -- cgit v1.2.3 From 6d206bb9dcc457b573e5e5dc36651ff1246b52d9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Thu, 20 Aug 2015 19:55:23 -0400 Subject: update recording save path --- MediaBrowser.Controller/Entities/Movies/Movie.cs | 13 ++++++-- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 10 ++++++ .../LiveTv/LiveTvVideoRecording.cs | 11 +++++++ .../LiveTv/EmbyTV/EmbyTV.cs | 13 ++++++++ .../LiveTv/EmbyTV/RecordingHelper.cs | 38 +++++++++++++--------- 5 files changed, 67 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index fc07f6778..083ec0cb4 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -100,16 +100,23 @@ namespace MediaBrowser.Controller.Entities.Movies /// <returns>System.String.</returns> protected override string CreateUserDataKey() { - var key = this.GetProviderId(MetadataProviders.Tmdb); + var key = GetMovieUserDataKey(this); if (string.IsNullOrWhiteSpace(key)) { - key = this.GetProviderId(MetadataProviders.Imdb); + key = base.CreateUserDataKey(); } + return key; + } + + public static string GetMovieUserDataKey(BaseItem movie) + { + var key = movie.GetProviderId(MetadataProviders.Tmdb); + if (string.IsNullOrWhiteSpace(key)) { - key = base.CreateUserDataKey(); + key = movie.GetProviderId(MetadataProviders.Imdb); } return key; diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index b54a7aaee..14944d36f 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; @@ -17,6 +18,15 @@ namespace MediaBrowser.Controller.LiveTv /// <returns>System.String.</returns> protected override string CreateUserDataKey() { + if (IsMovie) + { + var key = Movie.GetMovieUserDataKey(this); + + if (!string.IsNullOrWhiteSpace(key)) + { + return key; + } + } return GetClientTypeName() + "-" + Name; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index aaaff6bdb..960f8054a 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -40,6 +41,16 @@ namespace MediaBrowser.Controller.LiveTv /// <returns>System.String.</returns> protected override string CreateUserDataKey() { + if (IsMovie) + { + var key = Movie.GetMovieUserDataKey(this); + + if (!string.IsNullOrWhiteSpace(key)) + { + return key; + } + } + var name = GetClientTypeName(); if (!string.IsNullOrEmpty(ProgramId)) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 355597fcf..ebb5037d0 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -495,10 +495,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var info = GetProgramInfoFromCache(timer.ChannelId, timer.ProgramId); var recordPath = RecordingPath; + if (info.IsMovie) { recordPath = Path.Combine(recordPath, "Movies", _fileSystem.GetValidFilename(info.Name)); } + else if (info.IsSeries) + { + recordPath = Path.Combine(recordPath, "Series", _fileSystem.GetValidFilename(info.Name)); + } + else if (info.IsKids) + { + recordPath = Path.Combine(recordPath, "Kids", _fileSystem.GetValidFilename(info.Name)); + } + else if (info.IsSports) + { + recordPath = Path.Combine(recordPath, "Sports", _fileSystem.GetValidFilename(info.Name)); + } else { recordPath = Path.Combine(recordPath, "TV", _fileSystem.GetValidFilename(info.Name)); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 09a5a3912..1b8cd2e61 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.LiveTv; using System; +using System.Globalization; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { @@ -36,26 +37,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { if (info == null) { - return (timer.ProgramId + ".ts"); + return timer.ProgramId + ".ts"; } - var fancyName = info.Name; - if (info.ProductionYear != null) - { - fancyName += "_(" + info.ProductionYear + ")"; - } - if (info.IsSeries && !string.IsNullOrWhiteSpace(info.EpisodeTitle)) - { - fancyName += "_" + info.EpisodeTitle.Replace("Season: ", "S").Replace(" Episode: ", "E"); - } - if (info.IsHD ?? false) + + var name = info.Name; + + if (info.IsSeries) { - fancyName += "_HD"; + if (info.SeasonNumber.HasValue && info.EpisodeNumber.HasValue) + { + name += string.Format(" S{0}E{1}", info.SeasonNumber.Value.ToString("00", CultureInfo.InvariantCulture), info.EpisodeNumber.Value.ToString("00", CultureInfo.InvariantCulture)); + } + else if (info.OriginalAirDate.HasValue) + { + name += " " + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); + } + else if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) + { + name += " " + info.EpisodeTitle; + } } - if (info.OriginalAirDate != null) + + else if (info.ProductionYear != null) { - fancyName += "_" + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); + name += " (" + info.ProductionYear + ")"; } - return fancyName + ".ts"; + + return name + ".ts"; } } } -- cgit v1.2.3 From ddcebc4ff704d08e5f0a4dab5d14fe40e244b6d1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Thu, 20 Aug 2015 22:36:30 -0400 Subject: add tv suggestions --- MediaBrowser.Api/Library/LibraryService.cs | 126 ++++++++++++++++++++- MediaBrowser.Api/Movies/MoviesService.cs | 29 ++++- MediaBrowser.Api/Movies/TrailersService.cs | 39 +------ MediaBrowser.Api/Music/AlbumsService.cs | 50 ++++++++ MediaBrowser.Api/UserLibrary/GenresService.cs | 2 - .../Entities/IHasProgramAttributes.cs | 1 + MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 1 - MediaBrowser.Model/ApiClient/IApiClient.cs | 48 +------- MediaBrowser.Model/Dto/BaseItemDto.cs | 9 ++ .../LiveTv/EmbyTV/EmbyTV.cs | 4 +- .../LiveTv/EmbyTV/RecordingHelper.cs | 7 +- 11 files changed, 217 insertions(+), 99 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 50c4ad14f..945e803b2 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -1,4 +1,7 @@ -using MediaBrowser.Controller.Activity; +using MediaBrowser.Api.Movies; +using MediaBrowser.Api.Music; +using MediaBrowser.Controller.Activity; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -9,7 +12,9 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.TV; using MediaBrowser.Model.Activity; +using MediaBrowser.Model.Channels; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; @@ -238,6 +243,12 @@ namespace MediaBrowser.Api.Library public string Id { get; set; } } + [Route("/Items/{Id}/Similar", "GET", Summary = "Downloads item media")] + [Authenticated(Roles = "download")] + public class GetSimilarItems : BaseGetSimilarItemsFromItem + { + } + /// <summary> /// Class LibraryService /// </summary> @@ -257,12 +268,14 @@ namespace MediaBrowser.Api.Library private readonly IActivityManager _activityManager; private readonly ILocalizationManager _localization; private readonly ILiveTvManager _liveTv; + private readonly IChannelManager _channelManager; + private readonly ITVSeriesManager _tvManager; /// <summary> /// Initializes a new instance of the <see cref="LibraryService" /> class. /// </summary> public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, - IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv) + IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv, IChannelManager channelManager, ITVSeriesManager tvManager) { _itemRepo = itemRepo; _libraryManager = libraryManager; @@ -273,6 +286,115 @@ namespace MediaBrowser.Api.Library _activityManager = activityManager; _localization = localization; _liveTv = liveTv; + _channelManager = channelManager; + _tvManager = tvManager; + } + + public object Get(GetSimilarItems request) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + if (item is Game) + { + return new GamesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarGames + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + if (item is MusicAlbum) + { + return new AlbumsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarAlbums + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + if (item is MusicArtist) + { + return new AlbumsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarArtists + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + + var program = item as IHasProgramAttributes; + var channelItem = item as ChannelVideoItem; + + if (item is Movie || (program != null && program.IsMovie) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Movie && channelItem.ContentType == ChannelMediaContentType.MovieExtra)) + { + return new MoviesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _channelManager) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarMovies + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + + if (item is Series || (program != null && program.IsSeries) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Episode)) + { + return new TvShowsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _tvManager) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarShows + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + + return new ItemsResult(); } public object Get(GetMediaFolders request) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 97e9aa9c8..fe8bae1a5 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -28,6 +28,14 @@ namespace MediaBrowser.Api.Movies { } + /// <summary> + /// Class GetSimilarTrailers + /// </summary> + [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] + public class GetSimilarTrailers : BaseGetSimilarItemsFromItem + { + } + [Route("/Movies/Recommendations", "GET", Summary = "Gets movie recommendations")] public class GetMovieRecommendations : IReturn<RecommendationDto[]>, IHasItemFields { @@ -117,6 +125,17 @@ namespace MediaBrowser.Api.Movies return ToOptimizedSerializedResultUsingCache(result); } + public async Task<object> Get(GetSimilarTrailers request) + { + var result = await GetSimilarItemsResult( + // Strip out secondary versions + request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue, + + SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + + return ToOptimizedSerializedResultUsingCache(result); + } + public async Task<object> Get(GetMovieRecommendations request) { var user = _userManager.GetUserById(request.UserId); @@ -126,7 +145,7 @@ namespace MediaBrowser.Api.Movies movies = _libraryManager.ReplaceVideosWithPrimaryVersions(movies); var listEligibleForCategories = new List<BaseItem>(); - var listEligibleForSuggestion = new List<BaseItem> (); + var listEligibleForSuggestion = new List<BaseItem>(); var list = movies.ToList(); @@ -159,7 +178,7 @@ namespace MediaBrowser.Api.Movies var dtoOptions = GetDtoOptions(request); dtoOptions.Fields = request.GetItemFields().ToList(); - + var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); return ToOptimizedResult(result); @@ -174,14 +193,14 @@ namespace MediaBrowser.Api.Movies _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); Func<BaseItem, bool> filter = i => i.Id != item.Id && includeInSearch(i); - + var inputItems = user == null ? _libraryManager.RootFolder.GetRecursiveChildren(filter) : user.RootFolder.GetRecursiveChildren(user, filter); var list = inputItems.ToList(); - if (item is Movie && user != null && user.Configuration.IncludeTrailersInSuggestions) + if (user != null && user.Configuration.IncludeTrailersInSuggestions) { var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery { @@ -224,7 +243,7 @@ namespace MediaBrowser.Api.Movies } var dtoOptions = GetDtoOptions(request); - + var result = new ItemsResult { Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs index 0847fc7ed..ed197911a 100644 --- a/MediaBrowser.Api/Movies/TrailersService.cs +++ b/MediaBrowser.Api/Movies/TrailersService.cs @@ -2,15 +2,12 @@ using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using ServiceStack; -using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -18,14 +15,6 @@ using System.Threading.Tasks; namespace MediaBrowser.Api.Movies { - /// <summary> - /// Class GetSimilarTrailers - /// </summary> - [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] - public class GetSimilarTrailers : BaseGetSimilarItemsFromItem - { - } - [Route("/Trailers", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] public class Getrailers : BaseItemsRequest, IReturn<ItemsResult> { @@ -51,7 +40,6 @@ namespace MediaBrowser.Api.Movies /// </summary> private readonly ILibraryManager _libraryManager; - private readonly IItemRepository _itemRepo; private readonly IDtoService _dtoService; private readonly IChannelManager _channelManager; @@ -61,40 +49,15 @@ namespace MediaBrowser.Api.Movies /// <param name="userManager">The user manager.</param> /// <param name="userDataRepository">The user data repository.</param> /// <param name="libraryManager">The library manager.</param> - public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService, IChannelManager channelManager) + public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IDtoService dtoService, IChannelManager channelManager) { _userManager = userManager; _userDataRepository = userDataRepository; _libraryManager = libraryManager; - _itemRepo = itemRepo; _dtoService = dtoService; _channelManager = channelManager; } - /// <summary> - /// Gets the specified request. - /// </summary> - /// <param name="request">The request.</param> - /// <returns>System.Object.</returns> - public object Get(GetSimilarTrailers request) - { - var dtoOptions = GetDtoOptions(request); - - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, - _itemRepo, - _libraryManager, - _userDataRepository, - _dtoService, - Logger, - - // Strip out secondary versions - request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue, - - SimilarItemsHelper.GetSimiliarityScore); - - return ToOptimizedSerializedResultUsingCache(result); - } - public async Task<object> Get(Getrailers request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index ea87c3ad3..548598d42 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Querying; using ServiceStack; using System; using System.Collections.Generic; @@ -16,6 +17,11 @@ namespace MediaBrowser.Api.Music { } + [Route("/Artists/{Id}/Similar", "GET", Summary = "Finds albums similar to a given album.")] + public class GetSimilarArtists : BaseGetSimilarItemsFromItem + { + } + [Authenticated] public class AlbumsService : BaseApiService { @@ -44,6 +50,17 @@ namespace MediaBrowser.Api.Music _dtoService = dtoService; } + public object Get(GetSimilarArtists request) + { + var result = GetSimilarItemsResult( + + request, + + SimilarItemsHelper.GetSimiliarityScore); + + return ToOptimizedSerializedResultUsingCache(result); + } + /// <summary> /// Gets the specified request. /// </summary> @@ -65,6 +82,39 @@ namespace MediaBrowser.Api.Music return ToOptimizedSerializedResultUsingCache(result); } + private ItemsResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + var inputItems = _libraryManager.GetArtists(user.RootFolder.GetRecursiveChildren(user, i => i is IHasArtist).OfType<IHasArtist>()); + + var list = inputItems.ToList(); + + var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList(); + + IEnumerable<BaseItem> returnItems = items; + + if (request.Limit.HasValue) + { + returnItems = returnItems.Take(request.Limit.Value); + } + + var dtoOptions = GetDtoOptions(request); + + var result = new ItemsResult + { + Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), + + TotalRecordCount = items.Count + }; + + return result; + } + /// <summary> /// Gets the album similarity score. /// </summary> diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index 9e56907da..d383bd0ad 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -1,12 +1,10 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Querying; using ServiceStack; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs index 391c8f7a7..9938a4489 100644 --- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs +++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs @@ -11,6 +11,7 @@ namespace MediaBrowser.Controller.Entities bool IsKids { get; set; } bool IsRepeat { get; set; } bool? IsHD { get; set; } + bool IsSeries { get; set; } bool IsLive { get; set; } bool IsPremiere { get; set; } ProgramAudio? Audio { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 9fc60beb9..ba0b82a0b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -37,7 +37,6 @@ namespace MediaBrowser.Controller.LiveTv string ExternalId { get; set; } string EpisodeTitle { get; set; } - bool IsSeries { get; set; } string SeriesTimerId { get; set; } RecordingStatus Status { get; set; } DateTime? EndDate { get; set; } diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index e52e7535b..6d441ccf8 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -353,39 +353,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="query">The query.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarMoviesAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar trailers async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarTrailersAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar series async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarSeriesAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar albums async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarAlbumsAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar games async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarGamesAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task<ItemsResult> GetSimilarItemsAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Gets the people async. @@ -442,20 +410,6 @@ namespace MediaBrowser.Model.ApiClient /// <returns>Task{ItemsResult}.</returns> Task<ItemsResult> GetGenresAsync(ItemsByNameQuery query); - /// <summary> - /// Gets the music genres async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetMusicGenresAsync(ItemsByNameQuery query); - - /// <summary> - /// Gets the game genres async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetGameGenresAsync(ItemsByNameQuery query); - /// <summary> /// Gets the studios async. /// </summary> diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index aa68e09a0..ac8fa3370 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1081,6 +1081,15 @@ namespace MediaBrowser.Model.Dto get { return StringHelper.EqualsIgnoreCase(Type, "Studio"); } } + [IgnoreDataMember] + public bool SupportsSimilarItems + { + get + { + return IsType("Movie") || IsType("Series") || IsType("MusicAlbum") || IsType("MusicArtist") || IsType("Program") || IsType("Recording") || IsType("ChannelVideoItem") || IsType("Game"); + } + } + /// <summary> /// Occurs when [property changed]. /// </summary> diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index ebb5037d0..200c6c9a6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -517,7 +517,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recordPath = Path.Combine(recordPath, "TV", _fileSystem.GetValidFilename(info.Name)); } - recordPath = Path.Combine(recordPath, _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info))); + var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts"; + + recordPath = Path.Combine(recordPath, recordingFileName); Directory.CreateDirectory(Path.GetDirectoryName(recordPath)); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 1b8cd2e61..f8f65c6d5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { if (info == null) { - return timer.ProgramId + ".ts"; + return timer.ProgramId; } var name = info.Name; @@ -52,7 +52,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { name += " " + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); } - else if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) + + if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) { name += " " + info.EpisodeTitle; } @@ -63,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV name += " (" + info.ProductionYear + ")"; } - return name + ".ts"; + return name; } } } -- cgit v1.2.3 From 918aa4cfd754d055c80f3aff0bab945be28ee55d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 21 Aug 2015 01:00:56 -0400 Subject: add slideshows to now playing page --- .../LiveTv/Listings/SchedulesDirect.cs | 23 ++++++++++++++++++---- .../MediaBrowser.WebDashboard.csproj | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 66053041c..1958cdb03 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -1,9 +1,11 @@ -using MediaBrowser.Common; +using System.Net; +using MediaBrowser.Common; using MediaBrowser.Common.Net; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; @@ -620,11 +622,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings options.RequestHeaders["token"] = token; - using (var response = await _httpClient.Get(options).ConfigureAwait(false)) + try + { + using (var response = await _httpClient.Get(options).ConfigureAwait(false)) + { + var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Lineups>(response); + + return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase)); + } + } + catch (HttpException ex) { - var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Lineups>(response); + // Apparently we're supposed to swallow this + if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.BadRequest) + { + return false; + } - return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase)); + throw; } } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5ee76bbd1..e256cdb7c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -261,6 +261,9 @@ <Content Include="dashboard-ui\scripts\sharingwidget.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="dashboard-ui\scripts\slideshow.js"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="dashboard-ui\scripts\wizardlivetvtuner.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> -- cgit v1.2.3 From 63f02be8d2e97d0199ca1747b816050a6de16d8e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 21 Aug 2015 11:34:42 -0400 Subject: restore people fields --- .../LiveTv/Listings/SchedulesDirect.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 1958cdb03..7a6860d65 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -315,6 +315,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings if (details.contentRating != null && details.contentRating.Count > 0) { info.OfficialRating = details.contentRating[0].code.Replace("TV", "TV-").Replace("--", "-"); + + var invalid = new[] { "N/A", "Approved", "Not Rated" }; + if (invalid.Contains(info.OfficialRating, StringComparer.OrdinalIgnoreCase)) + { + info.OfficialRating = null; + } } if (details.descriptions != null) -- cgit v1.2.3 From 0e9c9a53ba2ba705c6da3e80dbbbec7434479fe3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 21 Aug 2015 11:55:11 -0400 Subject: update channels --- .../Channels/ChannelDownloadScheduledTask.cs | 409 --------------------- .../Channels/ChannelPostScanTask.cs | 12 +- .../MediaBrowser.Server.Implementations.csproj | 1 - 3 files changed, 11 insertions(+), 411 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs deleted file mode 100644 index 337e26e8d..000000000 --- a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs +++ /dev/null @@ -1,409 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Progress; -using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Channels; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Model.Querying; -using MoreLinq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Channels -{ - public class ChannelDownloadScheduledTask : IScheduledTask, IConfigurableScheduledTask - { - private readonly IChannelManager _manager; - private readonly IServerConfigurationManager _config; - private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; - private readonly ILibraryManager _libraryManager; - private readonly IUserManager _userManager; - - public ChannelDownloadScheduledTask(IChannelManager manager, IServerConfigurationManager config, ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager, IUserManager userManager) - { - _manager = manager; - _config = config; - _logger = logger; - _fileSystem = fileSystem; - _libraryManager = libraryManager; - _userManager = userManager; - } - - public string Name - { - get { return "Download channel content"; } - } - - public string Description - { - get { return "Downloads channel content based on configuration."; } - } - - public string Category - { - get { return "Channels"; } - } - - public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) - { - CleanChannelContent(cancellationToken); - - var users = _userManager.Users - .DistinctBy(GetUserDistinctValue) - .Select(i => i.Id.ToString("N")) - .ToList(); - - var numComplete = 0; - - foreach (var user in users) - { - double percentPerUser = 1; - percentPerUser /= users.Count; - var startingPercent = numComplete * percentPerUser * 100; - - var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerUser * p))); - - await DownloadContent(user, cancellationToken, innerProgress).ConfigureAwait(false); - - numComplete++; - double percent = numComplete; - percent /= users.Count; - progress.Report(percent * 100); - } - - progress.Report(100); - } - - public static string GetUserDistinctValue(User user) - { - var channels = user.Policy.EnabledChannels - .OrderBy(i => i) - .ToList(); - - return string.Join("|", channels.ToArray()); - } - - private async Task DownloadContent(string user, - CancellationToken cancellationToken, - IProgress<double> progress) - { - var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(0 + (.8 * p))); - await DownloadAllChannelContent(user, cancellationToken, innerProgress).ConfigureAwait(false); - progress.Report(80); - - innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(80 + (.2 * p))); - await DownloadLatestChannelContent(user, cancellationToken, progress).ConfigureAwait(false); - progress.Report(100); - } - - private async Task DownloadLatestChannelContent(string userId, - CancellationToken cancellationToken, - IProgress<double> progress) - { - var result = await _manager.GetLatestChannelItemsInternal(new AllChannelMediaQuery - { - UserId = userId - - }, cancellationToken).ConfigureAwait(false); - - progress.Report(5); - - var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(5 + (.95 * p))); - - var path = _manager.ChannelDownloadPath; - - await DownloadChannelContent(result, path, cancellationToken, innerProgress).ConfigureAwait(false); - } - - private async Task DownloadAllChannelContent(string userId, - CancellationToken cancellationToken, - IProgress<double> progress) - { - var result = await _manager.GetAllMediaInternal(new AllChannelMediaQuery - { - UserId = userId - - }, cancellationToken).ConfigureAwait(false); - - progress.Report(5); - - var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(5 + (.95 * p))); - - var path = _manager.ChannelDownloadPath; - - await DownloadChannelContent(result, path, cancellationToken, innerProgress).ConfigureAwait(false); - } - - private async Task DownloadChannelContent(QueryResult<BaseItem> result, - string path, - CancellationToken cancellationToken, - IProgress<double> progress) - { - var numComplete = 0; - - var options = _config.GetChannelsConfiguration(); - - foreach (var item in result.Items) - { - var channelItem = item as IChannelMediaItem; - - if (channelItem != null) - { - var channelFeatures = _manager.GetChannelFeatures(channelItem.ChannelId); - - if (channelFeatures.SupportsContentDownloading) - { - if (options.DownloadingChannels.Contains(channelItem.ChannelId)) - { - try - { - await DownloadChannelItem(channelItem, options, cancellationToken, path); - } - catch (OperationCanceledException) - { - break; - } - catch (ChannelDownloadException) - { - // Logged at lower levels - } - catch (Exception ex) - { - _logger.ErrorException("Error downloading channel content for {0}", ex, item.Name); - } - } - } - } - - numComplete++; - double percent = numComplete; - percent /= result.Items.Length; - progress.Report(percent * 100); - } - - progress.Report(100); - } - - private double? GetDownloadLimit(ChannelOptions channelOptions) - { - return channelOptions.DownloadSizeLimit; - } - - private async Task DownloadChannelItem(IChannelMediaItem item, - ChannelOptions channelOptions, - CancellationToken cancellationToken, - string path) - { - var itemId = item.Id.ToString("N"); - var sources = await _manager.GetStaticMediaSources(item, true, cancellationToken) - .ConfigureAwait(false); - - var cachedVersions = sources.Where(i => i.Protocol == MediaProtocol.File).ToList(); - - if (cachedVersions.Count > 0) - { - await RefreshMediaSourceItems(cachedVersions, cancellationToken).ConfigureAwait(false); - return; - } - - var limit = GetDownloadLimit(channelOptions); - - if (limit.HasValue) - { - if (IsSizeLimitReached(path, limit.Value)) - { - return; - } - } - - var destination = Path.Combine(path, item.ChannelId, itemId); - - await _manager.DownloadChannelItem(item, destination, new Progress<double>(), cancellationToken) - .ConfigureAwait(false); - - await RefreshMediaSourceItem(destination, cancellationToken).ConfigureAwait(false); - } - - private async Task RefreshMediaSourceItems(IEnumerable<MediaSourceInfo> items, CancellationToken cancellationToken) - { - foreach (var item in items) - { - await RefreshMediaSourceItem(item.Path, cancellationToken).ConfigureAwait(false); - } - } - - private async Task RefreshMediaSourceItem(string path, CancellationToken cancellationToken) - { - var item = _libraryManager.ResolvePath(new FileInfo(path)); - - if (item != null) - { - var forceSave = false; - - // Get the version from the database - var dbItem = _libraryManager.GetItemById(item.Id); - - if (dbItem == null) - { - forceSave = true; - } - else - { - item = dbItem; - } - - await item.RefreshMetadata(new MetadataRefreshOptions - { - ForceSave = forceSave - - }, cancellationToken).ConfigureAwait(false); - } - } - - private bool IsSizeLimitReached(string path, double gbLimit) - { - try - { - var byteLimit = gbLimit * 1000000000; - - long total = 0; - - foreach (var file in new DirectoryInfo(path).EnumerateFiles("*", SearchOption.AllDirectories)) - { - total += file.Length; - - if (total >= byteLimit) - { - return true; - } - } - - return false; - } - catch (DirectoryNotFoundException) - { - return false; - } - } - - public IEnumerable<ITaskTrigger> GetDefaultTriggers() - { - return new ITaskTrigger[] - { - new IntervalTrigger{ Interval = TimeSpan.FromHours(3)}, - }; - } - - private void CleanChannelContent(CancellationToken cancellationToken) - { - var options = _config.GetChannelsConfiguration(); - - if (!options.MaxDownloadAge.HasValue) - { - return; - } - - var minDateModified = DateTime.UtcNow.AddDays(0 - options.MaxDownloadAge.Value); - - var path = _manager.ChannelDownloadPath; - - try - { - DeleteCacheFilesFromDirectory(cancellationToken, path, minDateModified, new Progress<double>()); - } - catch (DirectoryNotFoundException) - { - // No biggie here. Nothing to delete - } - } - - /// <summary> - /// Deletes the cache files from directory with a last write time less than a given date - /// </summary> - /// <param name="cancellationToken">The task cancellation token.</param> - /// <param name="directory">The directory.</param> - /// <param name="minDateModified">The min date modified.</param> - /// <param name="progress">The progress.</param> - private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<double> progress) - { - var filesToDelete = new DirectoryInfo(directory).EnumerateFiles("*", SearchOption.AllDirectories) - .Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified) - .ToList(); - - var index = 0; - - foreach (var file in filesToDelete) - { - double percent = index; - percent /= filesToDelete.Count; - - progress.Report(100 * percent); - - cancellationToken.ThrowIfCancellationRequested(); - - DeleteFile(file.FullName); - - index++; - } - - progress.Report(100); - } - - /// <summary> - /// Deletes the file. - /// </summary> - /// <param name="path">The path.</param> - private void DeleteFile(string path) - { - try - { - _fileSystem.DeleteFile(path); - } - catch (IOException ex) - { - _logger.ErrorException("Error deleting file {0}", ex, path); - } - } - - /// <summary> - /// Gets a value indicating whether this instance is hidden. - /// </summary> - /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value> - public bool IsHidden - { - get - { - return !_manager.GetAllChannelFeatures().Any(); - } - } - - /// <summary> - /// Gets a value indicating whether this instance is enabled. - /// </summary> - /// <value><c>true</c> if this instance is enabled; otherwise, <c>false</c>.</value> - public bool IsEnabled - { - get - { - return true; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs index baf446942..b9f03fbc6 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Logging; @@ -28,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.Channels public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var users = _userManager.Users - .DistinctBy(ChannelDownloadScheduledTask.GetUserDistinctValue) + .DistinctBy(GetUserDistinctValue) .Select(i => i.Id.ToString("N")) .ToList(); @@ -54,6 +55,15 @@ namespace MediaBrowser.Server.Implementations.Channels progress.Report(100); } + public static string GetUserDistinctValue(User user) + { + var channels = user.Policy.EnabledChannels + .OrderBy(i => i) + .ToList(); + + return string.Join("|", channels.ToArray()); + } + private async Task DownloadContent(string user, CancellationToken cancellationToken, IProgress<double> progress) { var channels = await _channelManager.GetChannelsInternal(new ChannelQuery diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 824f3e856..74329b08f 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -109,7 +109,6 @@ <Compile Include="Activity\ActivityRepository.cs" /> <Compile Include="Branding\BrandingConfigurationFactory.cs" /> <Compile Include="Channels\ChannelConfigurations.cs" /> - <Compile Include="Channels\ChannelDownloadScheduledTask.cs" /> <Compile Include="Channels\ChannelDynamicMediaSourceProvider.cs" /> <Compile Include="Channels\ChannelImageProvider.cs" /> <Compile Include="Channels\ChannelItemImageProvider.cs" /> -- cgit v1.2.3 From 4307c67b5e518ef2514740b0a874f5832f31e537 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 21 Aug 2015 15:25:35 -0400 Subject: update setup wizard --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 21 +++++++++++++++ .../LiveTv/IHasRegistrationInfo.cs | 15 +++++++++++ MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 10 +++++++ .../MediaBrowser.Controller.csproj | 1 + .../LiveTv/EmbyTV/EmbyTV.cs | 31 +++++++++++++++++++--- .../LiveTv/LiveTvManager.cs | 29 ++++++++++++++++++++ 6 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index e55103230..c1f8ac3ea 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -456,6 +456,20 @@ namespace MediaBrowser.Api.LiveTv { } + [Route("/LiveTv/Registration", "GET")] + [Authenticated] + public class GetLiveTvRegistrationInfo : IReturn<MBRegistrationRecord> + { + [ApiMember(Name = "ChannelId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ChannelId { get; set; } + + [ApiMember(Name = "ProgramId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string ProgramId { get; set; } + + [ApiMember(Name = "Feature", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string Feature { get; set; } + } + public class LiveTvService : BaseApiService { private readonly ILiveTvManager _liveTvManager; @@ -471,6 +485,13 @@ namespace MediaBrowser.Api.LiveTv _httpClient = httpClient; } + public async Task<object> Get(GetLiveTvRegistrationInfo request) + { + var result = await _liveTvManager.GetRegistrationInfo(request.ChannelId, request.ProgramId, request.Feature).ConfigureAwait(false); + + return ToOptimizedResult(result); + } + public async Task<object> Get(GetSchedulesDirectCountries request) { // https://json.schedulesdirect.org/20141201/available/countries diff --git a/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs b/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs new file mode 100644 index 000000000..3626c18e5 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs @@ -0,0 +1,15 @@ +using MediaBrowser.Model.Entities; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface IHasRegistrationInfo + { + /// <summary> + /// Gets the registration information. + /// </summary> + /// <param name="feature">The feature.</param> + /// <returns>Task<MBRegistrationRecord>.</returns> + Task<MBRegistrationRecord> GetRegistrationInfo(string feature); + } +} diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index df09d39b2..2b121eeeb 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; using System.Collections.Generic; @@ -362,5 +363,14 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="location">The location.</param> /// <returns>Task<List<NameIdPair>>.</returns> Task<List<NameIdPair>> GetLineups(string providerType, string providerId, string country, string location); + + /// <summary> + /// Gets the registration information. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="programId">The program identifier.</param> + /// <param name="feature">The feature.</param> + /// <returns>Task<MBRegistrationRecord>.</returns> + Task<MBRegistrationRecord> GetRegistrationInfo(string channelId, string programId, string feature); } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index b84fe3c71..24309734f 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -199,6 +199,7 @@ <Compile Include="Library\NameExtensions.cs" /> <Compile Include="Library\PlaybackStopEventArgs.cs" /> <Compile Include="Library\UserDataSaveEventArgs.cs" /> + <Compile Include="LiveTv\IHasRegistrationInfo.cs" /> <Compile Include="LiveTv\IListingsProvider.cs" /> <Compile Include="LiveTv\ILiveTvItem.cs" /> <Compile Include="LiveTv\ITunerHost.cs" /> diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 200c6c9a6..708828d47 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -2,9 +2,11 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; +using MediaBrowser.Common.Security; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; @@ -19,7 +21,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { - public class EmbyTV : ILiveTvService, IDisposable + public class EmbyTV : ILiveTvService, IHasRegistrationInfo, IDisposable { private readonly IApplicationHost _appHpst; private readonly ILogger _logger; @@ -33,10 +35,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly LiveTvManager _liveTvManager; private readonly IFileSystem _fileSystem; + private readonly ISecurityManager _security; public static EmbyTV Current; - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem) + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security) { Current = this; @@ -45,6 +48,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _httpClient = httpClient; _config = config; _fileSystem = fileSystem; + _security = security; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; @@ -629,9 +633,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV .Where(i => string.Equals(i.SeriesTimerId, seriesTimer.Id, StringComparison.OrdinalIgnoreCase)) .ToList(); - foreach (var timer in newTimers) + var registration = await GetRegistrationInfo("seriesrecordings").ConfigureAwait(false); + + if (registration.IsValid) { - _timerProvider.AddOrUpdate(timer); + foreach (var timer in newTimers) + { + _timerProvider.AddOrUpdate(timer); + } } var newTimerIds = newTimers.Select(i => i.Id).ToList(); @@ -728,5 +737,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV pair.Value.Cancel(); } } + + public Task<MBRegistrationRecord> GetRegistrationInfo(string feature) + { + if (string.Equals(feature, "seriesrecordings", StringComparison.OrdinalIgnoreCase)) + { + return _security.GetRegistrationStatus("embytvseriesrecordings"); + } + + return Task.FromResult(new MBRegistrationRecord + { + IsValid = true, + IsRegistered = true + }); + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index cabe04f0f..4109617db 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2286,5 +2286,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv return provider.GetLineups(info, country, location); } } + + public Task<MBRegistrationRecord> GetRegistrationInfo(string channelId, string programId, string feature) + { + ILiveTvService service; + + if (string.IsNullOrWhiteSpace(programId)) + { + var channel = GetInternalChannel(channelId); + service = GetService(channel); + } + else + { + var program = GetInternalProgram(programId); + service = GetService(program); + } + + var hasRegistration = service as IHasRegistrationInfo; + + if (hasRegistration != null) + { + return hasRegistration.GetRegistrationInfo(feature); + } + + return Task.FromResult(new MBRegistrationRecord + { + IsValid = true, + IsRegistered = true + }); + } } } -- cgit v1.2.3 From de133cb8aa2b078ba653ee7c3e1cef4fd16996d6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 21 Aug 2015 22:59:10 -0400 Subject: update search --- MediaBrowser.Controller/Entities/BaseItem.cs | 1 + MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 6 + MediaBrowser.Controller/LiveTv/ProgramInfo.cs | 5 + .../Library/SearchEngine.cs | 272 ++++++--------------- .../Library/Validators/GameGenresValidator.cs | 27 +- .../Library/Validators/GenresValidator.cs | 27 +- .../Library/Validators/MusicGenresValidator.cs | 28 ++- .../Library/Validators/StudiosValidator.cs | 28 ++- .../LiveTv/EmbyTV/EmbyTV.cs | 18 +- .../LiveTv/Listings/SchedulesDirect.cs | 5 +- .../LiveTv/LiveTvManager.cs | 9 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 2 +- .../MediaBrowser.WebDashboard.csproj | 18 +- 13 files changed, 224 insertions(+), 222 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index c4917b0d1..cd5c39173 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -485,6 +485,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the parent. /// </summary> /// <value>The parent.</value> + [IgnoreDataMember] public Folder Parent { get diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 14944d36f..12052905f 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -30,6 +30,12 @@ namespace MediaBrowser.Controller.LiveTv return GetClientTypeName() + "-" + Name; } + /// <summary> + /// Gets or sets the etag. + /// </summary> + /// <value>The etag.</value> + public string Etag { get; set; } + /// <summary> /// Id of the program. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index 467264e7a..a6a3e6108 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -180,6 +180,11 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The episode number.</value> public int? EpisodeNumber { get; set; } + /// <summary> + /// Gets or sets the etag. + /// </summary> + /// <value>The etag.</value> + public string Etag { get; set; } public ProgramInfo() { diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 21e92786d..d4ff89b4f 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -33,26 +33,17 @@ namespace MediaBrowser.Server.Implementations.Library public async Task<QueryResult<SearchHintInfo>> GetSearchHints(SearchQuery query) { - IEnumerable<BaseItem> inputItems; - - Func<BaseItem, bool> filter = i => !(i is ICollectionFolder); - User user = null; if (string.IsNullOrWhiteSpace(query.UserId)) { - inputItems = _libraryManager.RootFolder.GetRecursiveChildren(filter); } else { user = _userManager.GetUserById(query.UserId); - - inputItems = user.RootFolder.GetRecursiveChildren(user, filter); } - inputItems = _libraryManager.ReplaceVideosWithPrimaryVersions(inputItems); - - var results = await GetSearchHints(inputItems, query, user).ConfigureAwait(false); + var results = await GetSearchHints(query, user).ConfigureAwait(false); var searchResultArray = results.ToArray(); results = searchResultArray; @@ -77,15 +68,22 @@ namespace MediaBrowser.Server.Implementations.Library }; } + private void AddIfMissing(List<string> list, string value) + { + if (!list.Contains(value, StringComparer.OrdinalIgnoreCase)) + { + list.Add(value); + } + } + /// <summary> /// Gets the search hints. /// </summary> - /// <param name="inputItems">The input items.</param> /// <param name="query">The query.</param> /// <param name="user">The user.</param> /// <returns>IEnumerable{SearchHintResult}.</returns> /// <exception cref="System.ArgumentNullException">searchTerm</exception> - private Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, SearchQuery query, User user) + private Task<IEnumerable<SearchHintInfo>> GetSearchHints(SearchQuery query, User user) { var searchTerm = query.SearchTerm; @@ -100,207 +98,80 @@ namespace MediaBrowser.Server.Implementations.Library var hints = new List<Tuple<BaseItem, string, int>>(); - var items = inputItems.Where(i => !(i is MusicArtist)).ToList(); + var excludeItemTypes = new List<string>(); + var includeItemTypes = (query.IncludeItemTypes ?? new string[] { }).ToList(); - if (query.IncludeMedia) - { - var mediaItems = _libraryManager.GetItems(new InternalItemsQuery - { - NameContains = searchTerm, - ExcludeItemTypes = new[] - { - typeof (Person).Name, - typeof (Genre).Name, - typeof (MusicArtist).Name, - typeof (GameGenre).Name, - typeof (MusicGenre).Name, - typeof (Year).Name, - typeof (Studio).Name - }, - IncludeItemTypes = query.IncludeItemTypes - - }).Items; - - // Add search hints based on item name - hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && (user == null || i.IsVisibleStandalone(user)) && !(i is CollectionFolder)).Select(item => - { - var index = GetIndex(item.Name, searchTerm, terms); + excludeItemTypes.Add(typeof(Year).Name); - return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2); - })); - } - - if (query.IncludeArtists && (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains("MusicArtist", StringComparer.OrdinalIgnoreCase))) + if (query.IncludeGenres && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Genre", StringComparer.OrdinalIgnoreCase))) { - // Find artists - var artists = items.OfType<Audio>() - .SelectMany(i => i.AllArtists) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .DistinctNames() - .ToList(); - - foreach (var item in artists) + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var artist = _libraryManager.GetArtist(item); - - hints.Add(new Tuple<BaseItem, string, int>(artist, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(Genre).Name); + AddIfMissing(includeItemTypes, typeof(GameGenre).Name); + AddIfMissing(includeItemTypes, typeof(MusicGenre).Name); } } - - if (query.IncludeGenres && (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains("Genre", StringComparer.OrdinalIgnoreCase))) + else { - // Find genres, from non-audio items - var genres = items.Where(i => !(i is IHasMusicGenres) && !(i is Game)) - .SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - foreach (var item in genres) - { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var genre = _libraryManager.GetGenre(item); - - hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } - } - - // Find music genres - var musicGenres = items.Where(i => i is IHasMusicGenres) - .SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + AddIfMissing(excludeItemTypes, typeof(Genre).Name); + AddIfMissing(excludeItemTypes, typeof(GameGenre).Name); + AddIfMissing(excludeItemTypes, typeof(MusicGenre).Name); + } - foreach (var item in musicGenres) + if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains("People", StringComparer.OrdinalIgnoreCase))) + { + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var genre = _libraryManager.GetMusicGenre(item); - - hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(Person).Name); } + } + else + { + AddIfMissing(excludeItemTypes, typeof(Person).Name); + } - // Find music genres - var gameGenres = items.OfType<Game>() - .SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - foreach (var item in gameGenres) + if (query.IncludeStudios && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Studio", StringComparer.OrdinalIgnoreCase))) + { + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var genre = _libraryManager.GetGameGenre(item); - - hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(Studio).Name); } } - - if (query.IncludeStudios && (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains("Studio", StringComparer.OrdinalIgnoreCase))) + else { - // Find studios - var studios = items.SelectMany(i => i.Studios) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + AddIfMissing(excludeItemTypes, typeof(Studio).Name); + } - foreach (var item in studios) + if (query.IncludeArtists && (includeItemTypes.Count == 0 || includeItemTypes.Contains("MusicArtist", StringComparer.OrdinalIgnoreCase))) + { + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var studio = _libraryManager.GetStudio(item); - - hints.Add(new Tuple<BaseItem, string, int>(studio, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(MusicArtist).Name); } } + else + { + AddIfMissing(excludeItemTypes, typeof(MusicArtist).Name); + } - if (query.IncludePeople && (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains("Person", StringComparer.OrdinalIgnoreCase))) + var mediaItems = _libraryManager.GetItems(new InternalItemsQuery { - var itemIds = items.Select(i => i.Id).ToList(); + NameContains = searchTerm, + ExcludeItemTypes = excludeItemTypes.ToArray(), + IncludeItemTypes = includeItemTypes.ToArray(), + MaxParentalRating = user == null ? null : user.Policy.MaxParentalRating, + Limit = query.Limit.HasValue ? query.Limit * 3 : null - // Find persons - var persons = _libraryManager.GetPeople(new InternalPeopleQuery - { - NameContains = searchTerm - }) - .Where(i => itemIds.Contains(i.ItemId)) - .Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - foreach (var item in persons) - { - var index = GetIndex(item, searchTerm, terms); + }).Items; - if (index.Item2 != -1) - { - try - { - var person = _libraryManager.GetPerson(item); - - hints.Add(new Tuple<BaseItem, string, int>(person, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } - } - } + // Add search hints based on item name + hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && IsVisible(i, user) && !(i is CollectionFolder)).Select(item => + { + var index = GetIndex(item.Name, searchTerm, terms); + + return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2); + })); var returnValue = hints.Where(i => i.Item3 >= 0).OrderBy(i => i.Item3).Select(i => new SearchHintInfo { @@ -311,13 +182,32 @@ namespace MediaBrowser.Server.Implementations.Library return Task.FromResult(returnValue); } + private bool IsVisible(BaseItem item, User user) + { + if (user == null) + { + return true; + } + + if (item is IItemByName) + { + var dual = item as IHasDualAccess; + if (dual == null || dual.IsAccessedByName) + { + return true; + } + } + + return item.IsVisibleStandalone(user); + } + private bool IncludeInSearch(BaseItem item) { var episode = item as Episode; if (episode != null) { - if (episode.IsVirtualUnaired || episode.IsMissingEpisode) + if (episode.IsMissingEpisode) { return false; } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index fe2e6a114..ee06fecdf 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using System.Collections.Generic; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; @@ -42,12 +43,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; + var validIds = new List<Guid>(); + foreach (var name in items) { try { var itemByName = _libraryManager.GetGameGenre(name); + validIds.Add(itemByName.Id); + await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -68,6 +73,26 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(GameGenre).Name } + }); + + var invalidIds = allIds + .Except(validIds) + .ToList(); + + foreach (var id in invalidIds) + { + var item = _libraryManager.GetItemById(id); + + await _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); + } + progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index fac5cfc35..6ab70ea22 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using System.Collections.Generic; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; @@ -43,12 +44,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; + var validIds = new List<Guid>(); + foreach (var name in items) { try { var itemByName = _libraryManager.GetGenre(name); + validIds.Add(itemByName.Id); + await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -69,6 +74,26 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Genre).Name } + }); + + var invalidIds = allIds + .Except(validIds) + .ToList(); + + foreach (var id in invalidIds) + { + var item = _libraryManager.GetItemById(id); + + await _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); + } + progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index e3be75e9b..8be0f4349 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Entities.Audio; +using System.Collections.Generic; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; @@ -42,12 +44,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; + var validIds = new List<Guid>(); + foreach (var name in items) { try { var itemByName = _libraryManager.GetMusicGenre(name); + validIds.Add(itemByName.Id); + await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -68,6 +74,26 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(MusicGenre).Name } + }); + + var invalidIds = allIds + .Except(validIds) + .ToList(); + + foreach (var id in invalidIds) + { + var item = _libraryManager.GetItemById(id); + + await _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); + } + progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index 066b96853..c90cbb2f0 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -1,6 +1,8 @@ -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -41,12 +43,16 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var numComplete = 0; var count = items.Count; + var validIds = new List<Guid>(); + foreach (var name in items) { try { var itemByName = _libraryManager.GetStudio(name); + validIds.Add(itemByName.Id); + await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) @@ -67,6 +73,26 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(percent); } + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Studio).Name } + }); + + var invalidIds = allIds + .Except(validIds) + .ToList(); + + foreach (var id in invalidIds) + { + var item = _libraryManager.GetItemById(id); + + await _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); + } + progress.Report(100); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 708828d47..3c65ac739 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -627,31 +627,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private async Task UpdateTimersForSeriesTimer(List<ProgramInfo> epgData, SeriesTimerInfo seriesTimer) { - var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); - - var existingTimers = _timerProvider.GetAll() - .Where(i => string.Equals(i.SeriesTimerId, seriesTimer.Id, StringComparison.OrdinalIgnoreCase)) - .ToList(); - var registration = await GetRegistrationInfo("seriesrecordings").ConfigureAwait(false); if (registration.IsValid) { + var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList(); + foreach (var timer in newTimers) { _timerProvider.AddOrUpdate(timer); } } - - var newTimerIds = newTimers.Select(i => i.Id).ToList(); - - foreach (var timer in existingTimers) - { - if (!newTimerIds.Contains(timer.Id, StringComparer.OrdinalIgnoreCase)) - { - CancelTimerInternal(timer.Id); - } - } } private IEnumerable<TimerInfo> GetTimersForSeries(SeriesTimerInfo seriesTimer, IEnumerable<ProgramInfo> allPrograms, IReadOnlyList<RecordingInfo> currentRecordings) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 7a6860d65..129f922b3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -304,7 +304,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings IsKids = string.Equals(details.audience, "children", StringComparison.OrdinalIgnoreCase), IsSports = showType.IndexOf("sports", StringComparison.OrdinalIgnoreCase) != -1, IsMovie = showType.IndexOf("movie", StringComparison.OrdinalIgnoreCase) != -1 || showType.IndexOf("film", StringComparison.OrdinalIgnoreCase) != -1, - ShowId = programInfo.programID + ShowId = programInfo.programID, + Etag = programInfo.md5 }; if (programInfo.videoProperties != null) @@ -408,7 +409,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings ; }); imageIdString = imageIdString.TrimEnd(',') + "]"; - _logger.Debug("Json for show images = " + imageIdString); + var httpOptions = new HttpRequestOptions() { Url = ApiUrl + "/metadata/programs", diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 4109617db..1721d6101 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -593,7 +593,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv Name = info.Name, Id = id, DateCreated = DateTime.UtcNow, - DateModified = DateTime.UtcNow + DateModified = DateTime.UtcNow, + Etag = info.Etag }; } @@ -639,7 +640,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv } else { - await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + if (string.IsNullOrWhiteSpace(info.Etag) || !string.Equals(info.Etag, item.Etag, StringComparison.OrdinalIgnoreCase)) + { + item.Etag = info.Etag; + await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + } } _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 104d02bcf..463c8829c 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.WebDashboard.Api // jQuery ajax doesn't seem to handle if-modified-since correctly if (IsFormat(path, "html")) { - if (IsCoreHtml(path)) + if (IsCoreHtml(path) && path.IndexOf(".template.html", StringComparison.OrdinalIgnoreCase) == -1) { resourceStream = await ModifyHtml(resourceStream, mode, appVersion, localizationCulture, enableMinification).ConfigureAwait(false); } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index e256cdb7c..4820535d0 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -186,9 +186,6 @@ <Content Include="dashboard-ui\css\nowplayingbar.css"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="dashboard-ui\livetvguideprovider-scd.html"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </Content> <Content Include="dashboard-ui\livetvguideprovider.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> @@ -222,9 +219,6 @@ <Content Include="dashboard-ui\scripts\homeupcoming.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <Content Include="dashboard-ui\scripts\livetvguideprovider-scd.js"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </Content> <Content Include="dashboard-ui\scripts\livetvguideprovider.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> @@ -264,6 +258,9 @@ <Content Include="dashboard-ui\scripts\slideshow.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="dashboard-ui\scripts\wizardlivetvguide.js"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="dashboard-ui\scripts\wizardlivetvtuner.js"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> @@ -377,6 +374,12 @@ <Content Include="dashboard-ui\thirdparty\viblast\worker.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="dashboard-ui\tvproviders\schedulesdirect.js"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="dashboard-ui\tvproviders\schedulesdirect.template.html"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="dashboard-ui\voice\voice.css"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> @@ -1786,6 +1789,9 @@ <Content Include="dashboard-ui\wizardagreement.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="dashboard-ui\wizardlivetvguide.html"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="dashboard-ui\wizardlivetvtuner.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> -- cgit v1.2.3 From d9bbe9302e6a3cea337e9f500422ca2fa009e875 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sat, 22 Aug 2015 11:54:29 -0400 Subject: update components --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 3c65ac739..9b7e83894 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -518,7 +518,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } else { - recordPath = Path.Combine(recordPath, "TV", _fileSystem.GetValidFilename(info.Name)); + recordPath = Path.Combine(recordPath, "Other", _fileSystem.GetValidFilename(info.Name)); } var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts"; -- cgit v1.2.3 From fafa879eef6c1fd7590bab78f842cf997251f5ab Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sat, 22 Aug 2015 13:50:37 -0400 Subject: keep channels db clean --- .../Channels/ChannelPostScanTask.cs | 61 +++++++++++++++++++++- .../Channels/RefreshChannelsScheduledTask.cs | 6 ++- .../Library/Validators/GameGenresValidator.cs | 2 + .../Library/Validators/GenresValidator.cs | 2 + .../Library/Validators/MusicGenresValidator.cs | 2 + .../Library/Validators/PeopleValidator.cs | 42 +++++++++++++-- .../Library/Validators/StudiosValidator.cs | 2 + .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- 8 files changed, 110 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs index b9f03fbc6..976fa5615 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs @@ -18,12 +18,14 @@ namespace MediaBrowser.Server.Implementations.Channels private readonly IChannelManager _channelManager; private readonly IUserManager _userManager; private readonly ILogger _logger; + private readonly ILibraryManager _libraryManager; - public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger) + public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager) { _channelManager = channelManager; _userManager = userManager; _logger = logger; + _libraryManager = libraryManager; } public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) @@ -52,6 +54,8 @@ namespace MediaBrowser.Server.Implementations.Channels progress.Report(percent * 100); } + await CleanDatabase(cancellationToken).ConfigureAwait(false); + progress.Report(100); } @@ -63,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.Channels return string.Join("|", channels.ToArray()); } - + private async Task DownloadContent(string user, CancellationToken cancellationToken, IProgress<double> progress) { var channels = await _channelManager.GetChannelsInternal(new ChannelQuery @@ -116,6 +120,59 @@ namespace MediaBrowser.Server.Implementations.Channels progress.Report(100); } + private async Task CleanDatabase(CancellationToken cancellationToken) + { + var allChannels = await _channelManager.GetChannelsInternal(new ChannelQuery { }, cancellationToken); + + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Channel).Name } + }); + + var invalidIds = allIds + .Except(allChannels.Items.Select(i => i.Id).ToList()) + .ToList(); + + foreach (var id in invalidIds) + { + cancellationToken.ThrowIfCancellationRequested(); + + await CleanChannel(id, cancellationToken).ConfigureAwait(false); + } + } + + private async Task CleanChannel(Guid id, CancellationToken cancellationToken) + { + _logger.Debug("Cleaning channel {0} from database", id); + + // Delete all channel items + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + ChannelIds = new[] { id.ToString("N") } + }); + + foreach (var deleteId in allIds) + { + cancellationToken.ThrowIfCancellationRequested(); + + await DeleteItem(deleteId).ConfigureAwait(false); + } + + // Finally, delete the channel itself + await DeleteItem(id).ConfigureAwait(false); + } + + private Task DeleteItem(Guid id) + { + var item = _libraryManager.GetItemById(id); + + return _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + + }); + } + private async Task GetAllItems(string user, string channelId, string folderId, int currentRefreshLevel, int maxRefreshLevel, IProgress<double> progress, CancellationToken cancellationToken) { var folderItems = new List<string>(); diff --git a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index df94580a5..005bbb852 100644 --- a/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -13,12 +13,14 @@ namespace MediaBrowser.Server.Implementations.Channels private readonly IChannelManager _channelManager; private readonly IUserManager _userManager; private readonly ILogger _logger; + private readonly ILibraryManager _libraryManager; - public RefreshChannelsScheduledTask(IChannelManager channelManager, IUserManager userManager, ILogger logger) + public RefreshChannelsScheduledTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager) { _channelManager = channelManager; _userManager = userManager; _logger = logger; + _libraryManager = libraryManager; } public string Name @@ -42,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Channels await manager.RefreshChannels(new Progress<double>(), cancellationToken).ConfigureAwait(false); - await new ChannelPostScanTask(_channelManager, _userManager, _logger).Run(progress, cancellationToken) + await new ChannelPostScanTask(_channelManager, _userManager, _logger, _libraryManager).Run(progress, cancellationToken) .ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index ee06fecdf..b57e128d3 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -84,6 +84,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators foreach (var id in invalidIds) { + cancellationToken.ThrowIfCancellationRequested(); + var item = _libraryManager.GetItemById(id); await _libraryManager.DeleteItem(item, new DeleteOptions diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index 6ab70ea22..11d4c9f16 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -85,6 +85,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators foreach (var id in invalidIds) { + cancellationToken.ThrowIfCancellationRequested(); + var item = _libraryManager.GetItemById(id); await _libraryManager.DeleteItem(item, new DeleteOptions diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 8be0f4349..0a66b4b41 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -85,6 +85,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators foreach (var id in invalidIds) { + cancellationToken.ThrowIfCancellationRequested(); + var item = _libraryManager.GetItemById(id); await _libraryManager.DeleteItem(item, new DeleteOptions diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index ef9dee8b5..a4c43af5d 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -92,15 +92,25 @@ namespace MediaBrowser.Server.Implementations.Library.Validators foreach (var person in people) { - bool current; - if (!dict.TryGetValue(person.Name, out current) || !current) + var isMetadataEnabled = DownloadMetadata(person, peopleOptions); + + bool currentValue; + if (dict.TryGetValue(person.Name, out currentValue)) + { + if (!currentValue && isMetadataEnabled) + { + dict[person.Name] = true; + } + } + else { - dict[person.Name] = DownloadMetadata(person, peopleOptions); + dict[person.Name] = isMetadataEnabled; } } var numComplete = 0; - + var validIds = new List<Guid>(); + foreach (var person in dict) { cancellationToken.ThrowIfCancellationRequested(); @@ -109,6 +119,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { var item = _libraryManager.GetPerson(person.Key); + validIds.Add(item.Id); + var options = new MetadataRefreshOptions { MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly, @@ -130,6 +142,28 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100 * percent); } + var allIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Person).Name } + }); + + var invalidIds = allIds + .Except(validIds) + .ToList(); + + foreach (var id in invalidIds) + { + cancellationToken.ThrowIfCancellationRequested(); + + var item = _libraryManager.GetItemById(id); + + await _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + + }).ConfigureAwait(false); + } + progress.Report(100); _logger.Info("People validation complete"); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index c90cbb2f0..c122d64d3 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -84,6 +84,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators foreach (var id in invalidIds) { + cancellationToken.ThrowIfCancellationRequested(); + var item = _libraryManager.GetItemById(id); await _libraryManager.DeleteItem(item, new DeleteOptions diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 9b7e83894..d4b02568a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -21,7 +21,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { - public class EmbyTV : ILiveTvService, IHasRegistrationInfo, IDisposable + public class EmbyTV : ILiveTvService/*, IHasRegistrationInfo*/, IDisposable { private readonly IApplicationHost _appHpst; private readonly ILogger _logger; -- cgit v1.2.3 From 1ddee6724ae4afa098f0ef4539245b4f20c86756 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sat, 22 Aug 2015 14:29:12 -0400 Subject: retry failed recordings --- .../LiveTv/EmbyTV/EmbyTV.cs | 11 +++++++-- .../LiveTv/EmbyTV/TimerManager.cs | 26 +++++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index d4b02568a..5b82b0a1f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -463,13 +463,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV async void _timerProvider_TimerFired(object sender, GenericEventArgs<TimerInfo> e) { + var timer = e.Argument; + try { var cancellationTokenSource = new CancellationTokenSource(); - if (_activeRecordings.TryAdd(e.Argument.Id, cancellationTokenSource)) + if (_activeRecordings.TryAdd(timer.Id, cancellationTokenSource)) { - await RecordStream(e.Argument, cancellationTokenSource.Token).ConfigureAwait(false); + await RecordStream(timer, cancellationTokenSource.Token).ConfigureAwait(false); } } catch (OperationCanceledException) @@ -479,6 +481,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV catch (Exception ex) { _logger.ErrorException("Error recording stream", ex); + + const int retryIntervalSeconds = 60; + _logger.Debug("Retrying recording in {0} seconds.", retryIntervalSeconds); + + _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 0c8d2ca2b..3ae38f382 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -44,12 +44,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public override void Delete(TimerInfo item) { base.Delete(item); - - Timer timer; - if (_timers.TryRemove(item.Id, out timer)) - { - timer.Dispose(); - } + StopTimer(item); } public override void Update(TimerInfo item) @@ -104,9 +99,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return; } - var timespan = startDate - now; + var timerLength = startDate - now; + StartTimer(item, timerLength); + } - var timer = new Timer(TimerCallback, item.Id, timespan, TimeSpan.Zero); + public void StartTimer(TimerInfo item, TimeSpan length) + { + StopTimer(item); + + var timer = new Timer(TimerCallback, item.Id, length, TimeSpan.Zero); if (!_timers.TryAdd(item.Id, timer)) { @@ -114,6 +115,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } + private void StopTimer(TimerInfo item) + { + Timer timer; + if (_timers.TryRemove(item.Id, out timer)) + { + timer.Dispose(); + } + } + private void TimerCallback(object state) { var timerId = (string)state; -- cgit v1.2.3 From de8bf2b396be38fadf05c830c243d96691326e85 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sat, 22 Aug 2015 14:31:17 -0400 Subject: retry failed recordings --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 5b82b0a1f..2f1b9d03e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -482,10 +482,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { _logger.ErrorException("Error recording stream", ex); - const int retryIntervalSeconds = 60; - _logger.Debug("Retrying recording in {0} seconds.", retryIntervalSeconds); + if (DateTime.UtcNow < timer.EndDate) + { + const int retryIntervalSeconds = 60; + _logger.Debug("Retrying recording in {0} seconds.", retryIntervalSeconds); - _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); + _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); + } } } -- cgit v1.2.3 From 795a8ab33b6a8937ee7c6c4d3524d4a8b1e2ba33 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sat, 22 Aug 2015 15:46:55 -0400 Subject: added auto-organize setting --- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 1 + .../FileOrganization/EpisodeFileOrganizer.cs | 11 ++++- .../FileOrganization/TvFolderOrganizer.cs | 15 +------ .../LiveTv/EmbyTV/EmbyTV.cs | 51 ++++++++++++++++++++-- 4 files changed, 59 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index c5e8f4636..7881231a2 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -7,6 +7,7 @@ namespace MediaBrowser.Model.LiveTv public int? GuideDays { get; set; } public bool EnableMovieProviders { get; set; } public string RecordingPath { get; set; } + public bool EnableAutoOrganize { get; set; } public List<TunerHostInfo> TunerHosts { get; set; } public List<ListingsProviderInfo> ListingProviders { get; set; } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index e134670e3..06b72e4ef 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -43,6 +43,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _providerManager = providerManager; } + public Task<FileOrganizationResult> OrganizeEpisodeFile(string path, CancellationToken cancellationToken) + { + var options = _config.GetAutoOrganizeOptions().TvOptions; + + return OrganizeEpisodeFile(path, options, false, cancellationToken); + } + public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, TvFileOrganizationOptions options, bool overwriteExisting, CancellationToken cancellationToken) { _logger.Info("Sorting file {0}", path); @@ -56,7 +63,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization FileSize = new FileInfo(path).Length }; - var namingOptions = ((LibraryManager) _libraryManager).GetNamingOptions(); + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); var resolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger()); var episodeInfo = resolver.Resolve(path, false) ?? @@ -254,7 +261,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization .ToList(); var targetFilenameWithoutExtension = Path.GetFileNameWithoutExtension(targetPath); - + foreach (var file in files) { directory = Path.GetDirectoryName(file); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs index 557b531b4..0caa8c26e 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs @@ -48,8 +48,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization progress.Report(10); - var scanLibrary = false; - if (eligibleFiles.Count > 0) { var numComplete = 0; @@ -61,12 +59,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization try { - var result = await organizer.OrganizeEpisodeFile(file.FullName, options, options.OverwriteExistingEpisodes, cancellationToken).ConfigureAwait(false); - - if (result.Status == FileSortingStatus.Success) - { - scanLibrary = true; - } + await organizer.OrganizeEpisodeFile(file.FullName, options, options.OverwriteExistingEpisodes, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -106,12 +99,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - if (scanLibrary) - { - await _libraryManager.ValidateMediaLibrary(new Progress<double>(), CancellationToken.None) - .ConfigureAwait(false); - } - progress.Report(100); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2f1b9d03e..96e14a21c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -3,14 +3,20 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.FileOrganization; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; +using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; +using MediaBrowser.Server.Implementations.FileOrganization; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -21,12 +27,12 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { - public class EmbyTV : ILiveTvService/*, IHasRegistrationInfo*/, IDisposable + public class EmbyTV : ILiveTvService, IHasRegistrationInfo, IDisposable { private readonly IApplicationHost _appHpst; private readonly ILogger _logger; private readonly IHttpClient _httpClient; - private readonly IConfigurationManager _config; + private readonly IServerConfigurationManager _config; private readonly IJsonSerializer _jsonSerializer; private readonly ItemDataProvider<RecordingInfo> _recordingProvider; @@ -37,9 +43,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly IFileSystem _fileSystem; private readonly ISecurityManager _security; + private readonly ILibraryMonitor _libraryMonitor; + private readonly ILibraryManager _libraryManager; + private readonly IProviderManager _providerManager; + private readonly IFileOrganizationService _organizationService; + public static EmbyTV Current; - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security) + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService) { Current = this; @@ -49,6 +60,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _config = config; _fileSystem = fileSystem; _security = security; + _libraryManager = libraryManager; + _libraryMonitor = libraryMonitor; + _providerManager = providerManager; + _organizationService = organizationService; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; @@ -610,6 +625,36 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _recordingProvider.Update(recording); _timerProvider.Delete(timer); _logger.Info("Recording was a success"); + + if (recording.Status == RecordingStatus.Completed) + { + OnSuccessfulRecording(recording); + } + } + + private async void OnSuccessfulRecording(RecordingInfo recording) + { + if (GetConfiguration().EnableAutoOrganize) + { + if (recording.IsSeries) + { + try + { + var organize = new EpisodeFileOrganizer(_organizationService, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); + + var result = await organize.OrganizeEpisodeFile(recording.Path, CancellationToken.None).ConfigureAwait(false); + + if (result.Status == FileSortingStatus.Success) + { + _recordingProvider.Delete(recording); + } + } + catch (Exception ex) + { + _logger.ErrorException("Error processing new recording", ex); + } + } + } } private ProgramInfo GetProgramInfoFromCache(string channelId, string programId) -- cgit v1.2.3 From 474cbbb87a51cb0fe82c408789c75b3971b58227 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sun, 23 Aug 2015 22:08:20 -0400 Subject: added default padding settings --- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 5 ++++- .../Library/LibraryManager.cs | 2 +- .../Library/MediaSourceManager.cs | 5 ++++- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 6 ++++-- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 3 +-- .../LiveTv/LiveTvMediaSourceProvider.cs | 7 ++++++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 13 +++++++++++-- SharedVersion.cs | 4 ++-- 8 files changed, 33 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 7881231a2..2b45422ec 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -11,7 +11,10 @@ namespace MediaBrowser.Model.LiveTv public List<TunerHostInfo> TunerHosts { get; set; } public List<ListingsProviderInfo> ListingProviders { get; set; } - + + public int PrePaddingSeconds { get; set; } + public int PostPaddingSeconds { get; set; } + public LiveTvOptions() { EnableMovieProviders = true; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index a67e3d732..cc9d9551c 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -937,7 +937,7 @@ namespace MediaBrowser.Server.Implementations.Library (item as MusicArtist).IsAccessedByName = true; } - var task = item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None); + var task = CreateItem(item, CancellationToken.None); Task.WaitAll(task); } diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index c5ff100f9..1f4dff277 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -483,7 +483,10 @@ namespace MediaBrowser.Server.Implementations.Library var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N"), keys[0], StringComparison.OrdinalIgnoreCase)); - return new Tuple<IMediaSourceProvider, string>(provider, keys[1]); + var splitIndex = key.IndexOf(LiveStreamIdDelimeter); + var keyId = key.Substring(splitIndex + 1); + + return new Tuple<IMediaSourceProvider, string>(provider, keyId); } private Timer _closeTimer; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 96e14a21c..b69cdacef 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -339,10 +339,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task<SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null) { + var config = GetConfiguration(); + var defaults = new SeriesTimerInfo() { - PostPaddingSeconds = 0, - PrePaddingSeconds = 0, + PostPaddingSeconds = Math.Max(config.PostPaddingSeconds, 0), + PrePaddingSeconds = Math.Max(config.PrePaddingSeconds, 0), RecordAnyChannel = false, RecordAnyTime = false, RecordNewOnly = false diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 1721d6101..653adb716 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -889,8 +889,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (query.Limit.HasValue) { - programs = programs.Take(query.Limit.Value) - .OrderBy(i => i.StartDate); + programs = programs.Take(query.Limit.Value); } programList = programs.ToList(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index 66a21830e..d9d9b76b9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -125,7 +125,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv const bool isAudio = false; var keys = openToken.Split(new[] { StreamIdDelimeter }, 3); - var mediaSourceId = keys.Length >= 3 ? keys[2] : null; + string mediaSourceId = null; + + if (keys.Length >= 3) + { + mediaSourceId = openToken.Substring(keys[0].Length + keys[1].Length + 2); + } if (string.Equals(keys[0], typeof(LiveTvChannel).Name, StringComparison.OrdinalIgnoreCase)) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 5890e24eb..4bbbf5a4d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -22,7 +22,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private readonly IHttpClient _httpClient; private readonly IJsonSerializer _jsonSerializer; - public HdHomerunHost(IConfigurationManager config, ILogger logger, IHttpClient httpClient, IJsonSerializer jsonSerializer) : base(config, logger) + public HdHomerunHost(IConfigurationManager config, ILogger logger, IHttpClient httpClient, IJsonSerializer jsonSerializer) + : base(config, logger) { _httpClient = httpClient; _jsonSerializer = jsonSerializer; @@ -166,6 +167,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var url = info.Url; + if (string.IsNullOrWhiteSpace(url)) + { + throw new ArgumentException("Invalid tuner info"); + } + if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { url = "http://" + url; @@ -382,7 +388,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public async Task Validate(TunerHostInfo info) { - await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false); + if (info.IsEnabled) + { + await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false); + } } protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) diff --git a/SharedVersion.cs b/SharedVersion.cs index 3d8be801e..2b8644211 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5713.0")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5713.0")] -- cgit v1.2.3 From 9e387b2ecf44bf5613221fdbfbb873d725abe7b0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Mon, 24 Aug 2015 08:54:10 -0400 Subject: 3.0.5713.1 --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- .../Library/MediaSourceManager.cs | 5 +++++ .../LiveTv/LiveTvMediaSourceProvider.cs | 12 +++--------- SharedVersion.cs | 4 ++-- 4 files changed, 11 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 6fba6052f..33f3210a9 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -854,7 +854,7 @@ namespace MediaBrowser.Api.Playback state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false); } - if (state.MediaSource.RequiresOpening) + if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.Request.LiveStreamId)) { var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest { diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 1f4dff277..e3ec99392 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -479,6 +479,11 @@ namespace MediaBrowser.Server.Implementations.Library private Tuple<IMediaSourceProvider, string> GetProvider(string key) { + if (string.IsNullOrWhiteSpace(key)) + { + throw new ArgumentException("key"); + } + var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2); var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N"), keys[0], StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index d9d9b76b9..ff102b0f7 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -90,6 +90,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv foreach (var source in list) { source.Type = MediaSourceType.Default; + source.BufferMs = source.BufferMs ?? 1500; if (source.RequiresOpening || forceRequireOpening) { @@ -103,9 +104,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv openKeys.Add(item.Id.ToString("N")); openKeys.Add(source.Id ?? string.Empty); source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray()); - } - - source.BufferMs = source.BufferMs ?? 1500; + } // Dummy this up so that direct play checks can still run if (string.IsNullOrEmpty(source.Path) && source.Protocol == MediaProtocol.Http) @@ -125,12 +124,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv const bool isAudio = false; var keys = openToken.Split(new[] { StreamIdDelimeter }, 3); - string mediaSourceId = null; - - if (keys.Length >= 3) - { - mediaSourceId = openToken.Substring(keys[0].Length + keys[1].Length + 2); - } + var mediaSourceId = keys.Length >= 3 ? keys[2] : null; if (string.Equals(keys[0], typeof(LiveTvChannel).Name, StringComparison.OrdinalIgnoreCase)) { diff --git a/SharedVersion.cs b/SharedVersion.cs index 2b8644211..d77ca5d8f 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5713.0")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5713.1")] -- cgit v1.2.3 From 8046a514187f0ef003c2d828dcf31de6e85ecedb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Mon, 24 Aug 2015 23:13:04 -0400 Subject: add more live tv buttons --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 11 +++++- MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs | 6 ++++ .../LiveTv/LiveTvManager.cs | 40 +++++++--------------- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 4 +-- .../Persistence/SqliteItemRepository.cs | 34 +++++++++++++++++- 5 files changed, 64 insertions(+), 31 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index d47a7e2d6..07e64c98d 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -78,6 +78,14 @@ namespace MediaBrowser.Api.LiveTv /// <value>The fields.</value> [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } + + [ApiMember(Name = "AddCurrentProgram", Description = "Optional. Adds current program info to each channel", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public bool AddCurrentProgram { get; set; } + + public GetChannels() + { + AddCurrentProgram = true; + } } [Route("/LiveTv/Channels/{Id}", "GET", Summary = "Gets a live tv channel")] @@ -582,7 +590,8 @@ namespace MediaBrowser.Api.LiveTv IsFavorite = request.IsFavorite, IsLiked = request.IsLiked, IsDisliked = request.IsDisliked, - EnableFavoriteSorting = request.EnableFavoriteSorting + EnableFavoriteSorting = request.EnableFavoriteSorting, + AddCurrentProgram = request.AddCurrentProgram }, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs index 900537b7a..3a6ad0444 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs @@ -53,5 +53,11 @@ namespace MediaBrowser.Model.LiveTv /// </summary> /// <value>The limit.</value> public int? Limit { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether [add current program]. + /// </summary> + /// <value><c>true</c> if [add current program]; otherwise, <c>false</c>.</value> + public bool AddCurrentProgram { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 653adb716..9cd4a2334 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -251,13 +251,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv var now = DateTime.UtcNow; - var programs = _libraryManager.QueryItems(new InternalItemsQuery + var programs = query.AddCurrentProgram ? _libraryManager.QueryItems(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, MaxStartDate = now, - MinEndDate = now + MinEndDate = now, + ChannelIds = internalResult.Items.Select(i => i.Id.ToString("N")).ToArray() - }).Items.Cast<LiveTvProgram>().OrderBy(i => i.StartDate).ToList(); + }).Items.Cast<LiveTvProgram>().OrderBy(i => i.StartDate).ToList() : new List<LiveTvProgram>(); foreach (var channel in internalResult.Items) { @@ -776,7 +777,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv IsMovie = query.IsMovie, IsSports = query.IsSports, IsKids = query.IsKids, - Genres = query.Genres + Genres = query.Genres, + StartIndex = query.StartIndex, + Limit = query.Limit, + SortBy = query.SortBy, + SortOrder = query.SortOrder ?? SortOrder.Ascending }; var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -802,29 +807,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>(); - - programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending) - .Cast<LiveTvProgram>(); - - var programList = programs.ToList(); - IEnumerable<LiveTvProgram> returnPrograms = programList; - - if (query.StartIndex.HasValue) - { - returnPrograms = returnPrograms.Skip(query.StartIndex.Value); - } + var queryResult = _libraryManager.QueryItems(internalQuery); - if (query.Limit.HasValue) - { - returnPrograms = returnPrograms.Take(query.Limit.Value); - } - - var returnArray = returnPrograms - .Select(i => - { - return _dtoService.GetBaseItemDto(i, options, user); - }) + var returnArray = queryResult.Items + .Select(i => _dtoService.GetBaseItemDto(i, options, user)) .ToArray(); await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false); @@ -832,7 +818,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var result = new QueryResult<BaseItemDto> { Items = returnArray, - TotalRecordCount = programList.Count + TotalRecordCount = queryResult.TotalRecordCount }; return result; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 4bbbf5a4d..cab21bc3a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public async Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) { - string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); + var model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); using (var stream = await _httpClient.Get(new HttpRequestOptions() { @@ -398,7 +398,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var info = await GetTunerInfos(tuner, cancellationToken).ConfigureAwait(false); - return info.Any(i => i.Status == LiveTvTunerStatus.Available); + return info.Any(i => i.Status == LiveTvTunerStatus.Available || string.Equals(i.ChannelId, channelId, StringComparison.OrdinalIgnoreCase)); } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 3ec45c4de..f6a04f303 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -712,6 +712,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; + cmd.CommandText += GetOrderByText(query); + if (query.Limit.HasValue) { cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); @@ -719,6 +721,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; + _logger.Debug(cmd.CommandText); + var list = new List<BaseItem>(); var count = 0; @@ -747,6 +751,28 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + private string GetOrderByText(InternalItemsQuery query) + { + if (query.SortBy == null || query.SortBy.Length == 0) + { + return string.Empty; + } + + var sortOrder = query.SortOrder == SortOrder.Descending ? "DESC" : "ASC"; + + return " ORDER BY " + string.Join(",", query.SortBy.Select(i => MapOrderByField(i) + " " + sortOrder).ToArray()); + } + + private string MapOrderByField(string name) + { + if (string.Equals(name, "sortname", StringComparison.OrdinalIgnoreCase)) + { + return "name"; + } + + return name; + } + public List<Guid> GetItemIdsList(InternalItemsQuery query) { if (query == null) @@ -768,6 +794,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; + cmd.CommandText += GetOrderByText(query); + if (query.Limit.HasValue) { cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); @@ -816,6 +844,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; + cmd.CommandText += GetOrderByText(query); + if (query.Limit.HasValue) { cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture); @@ -985,7 +1015,9 @@ namespace MediaBrowser.Server.Implementations.Persistence string.Empty : " where " + string.Join(" AND ", whereClauses.ToArray()); - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM TypedBaseItems {0} ORDER BY DateCreated DESC LIMIT {1})", + var orderBy = GetOrderByText(query); + + whereClauses.Add(string.Format("guid NOT IN (SELECT guid FROM TypedBaseItems {0}" + orderBy + " LIMIT {1})", pagingWhereText, query.StartIndex.Value.ToString(CultureInfo.InvariantCulture))); } -- cgit v1.2.3 From 23519642132d3b4ed39e42336fd860c2e00dcd3b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Tue, 25 Aug 2015 22:13:28 -0400 Subject: update movie filters --- .../LiveTv/EmbyTV/RecordingHelper.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index f8f65c6d5..5b83d63b1 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -44,15 +44,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (info.IsSeries) { + var addHyphen = true; + if (info.SeasonNumber.HasValue && info.EpisodeNumber.HasValue) { name += string.Format(" S{0}E{1}", info.SeasonNumber.Value.ToString("00", CultureInfo.InvariantCulture), info.EpisodeNumber.Value.ToString("00", CultureInfo.InvariantCulture)); + addHyphen = false; } else if (info.OriginalAirDate.HasValue) { name += " " + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); } + if (addHyphen) + { + name += " -"; + } + if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) { name += " " + info.EpisodeTitle; -- cgit v1.2.3 From 3e1bbcdcea8d78fd3845e13a4edf107cbcdf0640 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 26 Aug 2015 01:10:04 -0400 Subject: add clean db task --- .../Entities/InternalItemsQuery.cs | 2 + .../MediaBrowser.Server.Implementations.csproj | 1 + .../Persistence/CleanDatabaseScheduledTask.cs | 89 ++++++++++++++++++++++ .../Persistence/SqliteItemRepository.cs | 23 +++++- 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 227a6bd0e..53667c6e1 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -96,6 +96,8 @@ namespace MediaBrowser.Controller.Entities internal List<Guid> ItemIdsFromPersonFilters { get; set; } public int? MaxParentalRating { get; set; } + public bool? IsCurrentSchema { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 74329b08f..b2da2489d 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -241,6 +241,7 @@ <Compile Include="Logging\PatternsLogger.cs" /> <Compile Include="MediaEncoder\EncodingManager.cs" /> <Compile Include="Persistence\BaseSqliteRepository.cs" /> + <Compile Include="Persistence\CleanDatabaseScheduledTask.cs" /> <Compile Include="Social\SharingManager.cs" /> <Compile Include="Social\SharingRepository.cs" /> <Compile Include="Sorting\StartDateComparer.cs" /> diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs new file mode 100644 index 000000000..c29204702 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -0,0 +1,89 @@ +using MediaBrowser.Common.Progress; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + class CleanDatabaseScheduledTask : IScheduledTask + { + private readonly ILibraryManager _libraryManager; + private readonly IItemRepository _itemRepo; + private readonly ILogger _logger; + + public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger) + { + _libraryManager = libraryManager; + _itemRepo = itemRepo; + _logger = logger; + } + + public string Name + { + get { return "Clean Database"; } + } + + public string Description + { + get { return "Deletes obsolete content from the database."; } + } + + public string Category + { + get { return "Library"; } + } + + public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) + { + var innerProgress = new ActionableProgress<double>(); + innerProgress.RegisterAction(progress.Report); + + await UpdateToLatestSchema(cancellationToken, innerProgress).ConfigureAwait(false); + } + + private async Task UpdateToLatestSchema(CancellationToken cancellationToken, IProgress<double> progress) + { + var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + IsCurrentSchema = false, + Limit = 50000 + }); + + var numComplete = 0; + var numItems = itemIds.Count; + + _logger.Debug("Upgrading schema for {0} items", numItems); + + foreach (var itemId in itemIds) + { + var item = _libraryManager.GetItemById(itemId); + + if (item != null) + { + await _itemRepo.SaveItem(item, cancellationToken).ConfigureAwait(false); + } + + numComplete++; + double percent = numComplete; + percent /= numItems; + progress.Report(percent * 100); + } + + progress.Report(100); + } + + public IEnumerable<ITaskTrigger> GetDefaultTriggers() + { + return new ITaskTrigger[] + { + new IntervalTrigger{ Interval = TimeSpan.FromDays(1)} + }; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index f6a04f303..73f292622 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -71,6 +71,9 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; + + private const int LatestSchemaVersion = 2; + /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. /// </summary> @@ -159,6 +162,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "ParentId", "GUID"); _connection.AddColumn(_logger, "TypedBaseItems", "Genres", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "ParentalRatingValue", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "SchemaVersion", "INT"); PrepareStatements(); @@ -201,10 +205,11 @@ namespace MediaBrowser.Server.Implementations.Persistence "ProductionYear", "ParentId", "Genres", - "ParentalRatingValue" + "ParentalRatingValue", + "SchemaVersion" }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24, @25)"; for (var i = 1; i <= saveColumns.Count; i++) { _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); @@ -350,6 +355,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue(); + _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -883,6 +890,18 @@ namespace MediaBrowser.Server.Implementations.Persistence { var whereClauses = new List<string>(); + if (query.IsCurrentSchema.HasValue) + { + if (query.IsCurrentSchema.Value) + { + whereClauses.Add("(SchemaVersion not null AND SchemaVersion=@SchemaVersion)"); + } + else + { + whereClauses.Add("(SchemaVersion is null or SchemaVersion<>@SchemaVersion)"); + } + cmd.Parameters.Add(cmd, "@SchemaVersion", DbType.Int32).Value = LatestSchemaVersion; + } if (query.IsMovie.HasValue) { whereClauses.Add("IsMovie=@IsMovie"); -- cgit v1.2.3 From d4050fbf2cbec98306d3f39c2cf7b620147afdee Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 26 Aug 2015 14:17:38 -0400 Subject: update photos --- .../LiveTv/Listings/SchedulesDirect.cs | 2 +- .../Persistence/CleanDatabaseScheduledTask.cs | 8 +++- .../Persistence/SqliteItemRepository.cs | 49 +++++++++++++++++----- SharedVersion.cs | 4 +- 4 files changed, 49 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 129f922b3..708891e68 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -317,7 +317,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { info.OfficialRating = details.contentRating[0].code.Replace("TV", "TV-").Replace("--", "-"); - var invalid = new[] { "N/A", "Approved", "Not Rated" }; + var invalid = new[] { "N/A", "Approved", "Not Rated", "Passed" }; if (invalid.Contains(info.OfficialRating, StringComparer.OrdinalIgnoreCase)) { info.OfficialRating = null; diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index c29204702..69e04c072 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -2,6 +2,7 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using System; using System.Collections.Generic; @@ -52,7 +53,10 @@ namespace MediaBrowser.Server.Implementations.Persistence var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery { IsCurrentSchema = false, - Limit = 50000 + Limit = 100000, + + // These are constantly getting regenerated so don't bother with them here + ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name } }); var numComplete = 0; @@ -62,6 +66,8 @@ namespace MediaBrowser.Server.Implementations.Persistence foreach (var itemId in itemIds) { + cancellationToken.ThrowIfCancellationRequested(); + var item = _libraryManager.GetItemById(itemId); if (item != null) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 73f292622..71578d1e0 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; - private const int LatestSchemaVersion = 2; + private const int LatestSchemaVersion = 4; /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. @@ -163,6 +163,15 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "Genres", "Text"); _connection.AddColumn(_logger, "TypedBaseItems", "ParentalRatingValue", "INT"); _connection.AddColumn(_logger, "TypedBaseItems", "SchemaVersion", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "SortName", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "RunTimeTicks", "BIGINT"); + + _connection.AddColumn(_logger, "TypedBaseItems", "OfficialRatingDescription", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "HomePageUrl", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "VoteCount", "INT"); + _connection.AddColumn(_logger, "TypedBaseItems", "DisplayMediaType", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "DateCreated", "DATETIME"); + _connection.AddColumn(_logger, "TypedBaseItems", "DateModified", "DATETIME"); PrepareStatements(); @@ -206,14 +215,30 @@ namespace MediaBrowser.Server.Implementations.Persistence "ParentId", "Genres", "ParentalRatingValue", - "SchemaVersion" + "SchemaVersion", + "SortName", + "RunTimeTicks", + "OfficialRatingDescription", + "HomePageUrl", + "VoteCount", + "DisplayMediaType", + "DateCreated", + "DateModified" }; _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20, @21, @22, @23, @24, @25)"; + _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; + for (var i = 1; i <= saveColumns.Count; i++) { + if (i > 1) + { + _saveItemCommand.CommandText += ","; + } + _saveItemCommand.CommandText += "@" + i.ToString(CultureInfo.InvariantCulture); + _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); } + _saveItemCommand.CommandText += ")"; _deleteChildrenCommand = _connection.CreateCommand(); _deleteChildrenCommand.CommandText = "delete from ChildrenIds where ParentId=@ParentId"; @@ -356,7 +381,16 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue(); _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; - + _saveItemCommand.GetParameter(index++).Value = item.SortName; + _saveItemCommand.GetParameter(index++).Value = item.RunTimeTicks; + + _saveItemCommand.GetParameter(index++).Value = item.OfficialRatingDescription; + _saveItemCommand.GetParameter(index++).Value = item.HomePageUrl; + _saveItemCommand.GetParameter(index++).Value = item.VoteCount; + _saveItemCommand.GetParameter(index++).Value = item.DisplayMediaType; + _saveItemCommand.GetParameter(index++).Value = item.DateCreated; + _saveItemCommand.GetParameter(index++).Value = item.DateModified; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -729,7 +763,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; _logger.Debug(cmd.CommandText); - + var list = new List<BaseItem>(); var count = 0; @@ -772,11 +806,6 @@ namespace MediaBrowser.Server.Implementations.Persistence private string MapOrderByField(string name) { - if (string.Equals(name, "sortname", StringComparison.OrdinalIgnoreCase)) - { - return "name"; - } - return name; } diff --git a/SharedVersion.cs b/SharedVersion.cs index bef2d6af2..ec5cb5676 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5713.3")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5713.3")] -- cgit v1.2.3 From 5b21ec6747f5c1eef8b44ad8ead4f89ed715a501 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Wed, 26 Aug 2015 21:31:54 -0400 Subject: update interval trigger --- MediaBrowser.Api/StartupWizardService.cs | 1 + .../ScheduledTasks/IntervalTrigger.cs | 13 ++- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Dlna/DlnaManager.cs | 3 +- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 4 +- MediaBrowser.Dlna/Profiles/KodiProfile.cs | 97 ++++++++++++++++++++++ .../Configuration/ServerConfiguration.cs | 6 ++ .../MediaInfo/SubtitleScheduledTask.cs | 2 +- .../IO/LibraryMonitor.cs | 20 +++++ .../LiveTv/Listings/SchedulesDirect.cs | 9 +- .../Persistence/CleanDatabaseScheduledTask.cs | 14 +++- .../Persistence/SqliteItemRepository.cs | 26 +++++- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 22 +++-- 13 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 MediaBrowser.Dlna/Profiles/KodiProfile.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 9eb96873b..e9ac45fa2 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -72,6 +72,7 @@ namespace MediaBrowser.Api _config.Configuration.EnableUserSpecificUserViews = true; _config.Configuration.EnableCustomPathSubFolders = true; _config.Configuration.DisableXmlSavers = true; + _config.Configuration.DisableStartupScan = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs index 15109be4f..b615adf81 100644 --- a/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs +++ b/MediaBrowser.Common/ScheduledTasks/IntervalTrigger.cs @@ -30,6 +30,17 @@ namespace MediaBrowser.Common.ScheduledTasks /// </value> public TaskExecutionOptions TaskOptions { get; set; } + /// <summary> + /// Gets or sets the first run delay. + /// </summary> + /// <value>The first run delay.</value> + public TimeSpan FirstRunDelay { get; set; } + + public IntervalTrigger() + { + FirstRunDelay = TimeSpan.FromHours(1); + } + /// <summary> /// Stars waiting for the trigger action /// </summary> @@ -41,7 +52,7 @@ namespace MediaBrowser.Common.ScheduledTasks var triggerDate = lastResult != null ? lastResult.EndTimeUtc.Add(Interval) : - DateTime.UtcNow.Add(Interval); + DateTime.UtcNow.Add(FirstRunDelay); if (DateTime.UtcNow > triggerDate) { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cd5c39173..a333fc6e9 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Entities public virtual string Path { get; set; } [IgnoreDataMember] - protected internal bool IsOffline { get; set; } + public bool IsOffline { get; set; } /// <summary> /// Returns the folder containing the item. diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 9ce62034b..124d0e675 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -547,7 +547,8 @@ namespace MediaBrowser.Dlna new DefaultProfile(), new PopcornHourProfile(), new VlcProfile(), - new BubbleUpnpProfile() + new BubbleUpnpProfile(), + new KodiProfile() }; foreach (var item in list) diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 2a495638a..055173a7c 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -166,7 +166,9 @@ <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282010%29.xml" /> <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282011%29.xml" /> <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282012%29.xml" /> - <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282013%29.xml" /> + <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282013%29.xml"> + <SubType>Designer</SubType> + </EmbeddedResource> <EmbeddedResource Include="Profiles\Xml\Sony PlayStation 3.xml" /> <EmbeddedResource Include="Profiles\Xml\WDTV Live.xml" /> <EmbeddedResource Include="Profiles\Xml\Xbox 360.xml"> diff --git a/MediaBrowser.Dlna/Profiles/KodiProfile.cs b/MediaBrowser.Dlna/Profiles/KodiProfile.cs new file mode 100644 index 000000000..75c323a1a --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/KodiProfile.cs @@ -0,0 +1,97 @@ +using MediaBrowser.Model.Dlna; +using System.Xml.Serialization; + +namespace MediaBrowser.Dlna.Profiles +{ + [XmlRoot("Profile")] + public class KodiProfile : DefaultProfile + { + public KodiProfile() + { + Name = "Kodi"; + + MaxStreamingBitrate = 100000000; + MaxStaticBitrate = 100000000; + MusicStreamingTranscodingBitrate = 1280000; + MusicSyncBitrate = 1280000; + + TimelineOffsetSeconds = 5; + + Identification = new DeviceIdentification + { + ModelName = "Kodi", + + Headers = new[] + { + new HttpHeaderInfo {Name = "User-Agent", Value = "Kodi", Match = HeaderMatchType.Substring} + } + }; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + + new TranscodingProfile + { + Container = "ts", + Type = DlnaProfileType.Video, + AudioCodec = "aac", + VideoCodec = "h264" + }, + + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "", + Type = DlnaProfileType.Photo, + } + }; + + ResponseProfiles = new ResponseProfile[] { }; + + ContainerProfiles = new ContainerProfile[] { }; + + CodecProfiles = new CodecProfile[] { }; + + SubtitleProfiles = new[] + { + new SubtitleProfile + { + Format = "srt", + Method = SubtitleDeliveryMethod.External, + }, + + new SubtitleProfile + { + Format = "sub", + Method = SubtitleDeliveryMethod.External, + } + }; + } + } +} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 46f9db580..07d5905c6 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -98,6 +98,12 @@ namespace MediaBrowser.Model.Configuration /// <value><c>true</c> if [enable localized guids]; otherwise, <c>false</c>.</value> public bool EnableLocalizedGuids { get; set; } + /// <summary> + /// Gets or sets a value indicating whether [disable startup scan]. + /// </summary> + /// <value><c>true</c> if [disable startup scan]; otherwise, <c>false</c>.</value> + public bool DisableStartupScan { get; set; } + /// <summary> /// Gets or sets a value indicating whether [enable library metadata sub folder]. /// </summary> diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs index 0f092b554..4953621f5 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs @@ -131,7 +131,7 @@ namespace MediaBrowser.Providers.MediaInfo { return new ITaskTrigger[] { - new DailyTrigger { TimeOfDay = TimeSpan.FromHours(3) }, + new IntervalTrigger{ Interval = TimeSpan.FromHours(8)} }; } } diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index e1c529187..5bd26ce18 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations.ScheduledTasks; @@ -700,4 +701,23 @@ namespace MediaBrowser.Server.Implementations.IO } } } + + public class LibraryMonitorStartup : IServerEntryPoint + { + private readonly ILibraryMonitor _monitor; + + public LibraryMonitorStartup(ILibraryMonitor monitor) + { + _monitor = monitor; + } + + public void Run() + { + _monitor.Start(); + } + + public void Dispose() + { + } + } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 708891e68..cb5a37401 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -438,8 +438,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return lineups; } - _logger.Info("Headends on account "); - var options = new HttpRequestOptions() { Url = ApiUrl + "/headends?country=" + country + "&postalcode=" + location, @@ -454,16 +452,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings using (Stream responce = await _httpClient.Get(options).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream<List<ScheduleDirect.Headends>>(responce); - _logger.Info("Lineups on account "); + if (root != null) { foreach (ScheduleDirect.Headends headend in root) { - _logger.Info("Headend: " + headend.headend); foreach (ScheduleDirect.Lineup lineup in headend.lineups) { - _logger.Info("Headend: " + lineup.uri); - lineups.Add(new NameIdPair { Name = string.IsNullOrWhiteSpace(lineup.name) ? lineup.lineup : lineup.name, @@ -474,7 +469,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } else { - _logger.Info("No lineups on account"); + _logger.Info("No lineups available"); } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 69e04c072..7a993b7db 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -1,14 +1,15 @@ using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.Persistence { @@ -17,12 +18,14 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly ILibraryManager _libraryManager; private readonly IItemRepository _itemRepo; private readonly ILogger _logger; + private readonly IServerConfigurationManager _config; - public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger) + public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config) { _libraryManager = libraryManager; _itemRepo = itemRepo; _logger = logger; + _config = config; } public string Name @@ -53,7 +56,6 @@ namespace MediaBrowser.Server.Implementations.Persistence var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery { IsCurrentSchema = false, - Limit = 100000, // These are constantly getting regenerated so don't bother with them here ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name } @@ -81,6 +83,12 @@ namespace MediaBrowser.Server.Implementations.Persistence progress.Report(percent * 100); } + if (!_config.Configuration.DisableStartupScan) + { + _config.Configuration.DisableStartupScan = true; + _config.SaveConfiguration(); + } + progress.Report(100); } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 71578d1e0..806e86a5a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deletePeopleCommand; private IDbCommand _savePersonCommand; - private const int LatestSchemaVersion = 4; + private const int LatestSchemaVersion = 6; /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. @@ -173,6 +173,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(_logger, "TypedBaseItems", "DateCreated", "DATETIME"); _connection.AddColumn(_logger, "TypedBaseItems", "DateModified", "DATETIME"); + _connection.AddColumn(_logger, "TypedBaseItems", "ForcedSortName", "Text"); + _connection.AddColumn(_logger, "TypedBaseItems", "IsOffline", "BIT"); + PrepareStatements(); _mediaStreamsRepository.Initialize(); @@ -223,7 +226,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "VoteCount", "DisplayMediaType", "DateCreated", - "DateModified" + "DateModified", + "ForcedSortName", + "IsOffline" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -391,6 +396,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.DateCreated; _saveItemCommand.GetParameter(index++).Value = item.DateModified; + _saveItemCommand.GetParameter(index++).Value = item.ForcedSortName; + _saveItemCommand.GetParameter(index++).Value = item.IsOffline; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -948,7 +956,6 @@ namespace MediaBrowser.Server.Implementations.Persistence } var includeTypes = query.IncludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray(); - if (includeTypes.Length == 1) { whereClauses.Add("type=@type"); @@ -959,6 +966,19 @@ namespace MediaBrowser.Server.Implementations.Persistence var inClause = string.Join(",", includeTypes.Select(i => "'" + i + "'").ToArray()); whereClauses.Add(string.Format("type in ({0})", inClause)); } + + var excludeTypes = query.ExcludeItemTypes.SelectMany(MapIncludeItemTypes).ToArray(); + if (excludeTypes.Length == 1) + { + whereClauses.Add("type<>@type"); + cmd.Parameters.Add(cmd, "@type", DbType.String).Value = excludeTypes[0]; + } + else if (excludeTypes.Length > 1) + { + var inClause = string.Join(",", excludeTypes.Select(i => "'" + i + "'").ToArray()); + whereClauses.Add(string.Format("type not in ({0})", inClause)); + } + if (query.ChannelIds.Length == 1) { whereClauses.Add("ChannelId=@ChannelId"); diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index ed284a90d..8cb76393e 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Common.ScheduledTasks; +using System.Linq; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Server.Implementations.Library; using System; @@ -17,14 +19,16 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// The _library manager /// </summary> private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; /// <summary> /// Initializes a new instance of the <see cref="RefreshMediaLibraryTask" /> class. /// </summary> /// <param name="libraryManager">The library manager.</param> - public RefreshMediaLibraryTask(ILibraryManager libraryManager) + public RefreshMediaLibraryTask(ILibraryManager libraryManager, IServerConfigurationManager config) { _libraryManager = libraryManager; + _config = config; } /// <summary> @@ -33,12 +37,18 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// <returns>IEnumerable{BaseTaskTrigger}.</returns> public IEnumerable<ITaskTrigger> GetDefaultTriggers() { - return new ITaskTrigger[] { - - new StartupTrigger(), + var list = new ITaskTrigger[] { new IntervalTrigger{ Interval = TimeSpan.FromHours(8)} - }; + + }.ToList(); + + if (!_config.Configuration.DisableStartupScan) + { + list.Add(new StartupTrigger()); + } + + return list; } /// <summary> -- cgit v1.2.3 From 4ca526979ddb665ce905cd5943738a2c5657ab31 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Thu, 27 Aug 2015 11:58:07 -0400 Subject: 3.0.5713.4 --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 17 +-- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 32 ++++- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 152 +++++++++------------ MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 4 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 26 ++-- MediaBrowser.Model/Entities/MediaStream.cs | 7 +- .../MediaInfo/FFProbeVideoInfo.cs | 16 +-- .../Persistence/SqliteItemRepository.cs | 33 ++++- .../Persistence/SqliteMediaStreamsRepository.cs | 58 +++++++- SharedVersion.cs | 4 +- 10 files changed, 213 insertions(+), 136 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 33f3210a9..45e0e8b8a 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1634,11 +1634,6 @@ namespace MediaBrowser.Api.Playback private void TryStreamCopy(StreamState state, VideoStreamRequest videoRequest) { - if (!EnableStreamCopy) - { - return; - } - if (state.VideoStream != null && CanStreamCopyVideo(videoRequest, state.VideoStream)) { state.OutputVideoCodec = "copy"; @@ -1650,14 +1645,6 @@ namespace MediaBrowser.Api.Playback } } - protected virtual bool EnableStreamCopy - { - get - { - return true; - } - } - private void AttachMediaSourceInfo(StreamState state, MediaSourceInfo mediaSource, VideoStreamRequest videoRequest, @@ -1741,7 +1728,7 @@ namespace MediaBrowser.Api.Playback state.MediaSource = mediaSource; } - private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) + protected virtual bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) { if (videoStream.IsInterlaced) { @@ -1889,7 +1876,7 @@ namespace MediaBrowser.Api.Playback return Array.FindIndex(list.ToArray(), t => string.Equals(t, profile, StringComparison.OrdinalIgnoreCase)); } - private bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs) + protected virtual bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs) { // Source and target codecs must match if (string.IsNullOrEmpty(audioStream.Codec) || !supportedAudioCodecs.Contains(audioStream.Codec, StringComparer.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index b2ffeca3d..1a152790a 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -1,9 +1,11 @@ -using MediaBrowser.Common.IO; +using System.Linq; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; @@ -310,5 +312,33 @@ namespace MediaBrowser.Api.Playback.Hls { return 0; } + + protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) + { + if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) + { + return false; + } + + var previousSegment = 0; + foreach (var frame in videoStream.KeyFrames) + { + var length = frame - previousSegment; + + // Don't allow really long segments because this could result in long download times + if (length > 10000) + { + return false; + } + previousSegment = frame; + } + + return base.CanStreamCopyVideo(request, videoStream); + } + + protected override bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs) + { + return false; + } } } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 27429b8db..04979fc3a 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -160,7 +160,6 @@ namespace MediaBrowser.Api.Playback.Hls var playlistPath = Path.ChangeExtension(state.OutputFilePath, ".m3u8"); var segmentPath = GetSegmentPath(state, playlistPath, requestedIndex); - var segmentLength = state.SegmentLength; var segmentExtension = GetSegmentFileExtension(state); @@ -169,7 +168,7 @@ namespace MediaBrowser.Api.Playback.Hls if (File.Exists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); - return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); + return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false); @@ -178,7 +177,7 @@ namespace MediaBrowser.Api.Playback.Hls if (File.Exists(segmentPath)) { job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); - return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); + return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } else { @@ -214,7 +213,7 @@ namespace MediaBrowser.Api.Playback.Hls DeleteLastFile(playlistPath, segmentExtension, 0); } - request.StartTimeTicks = GetSeekPositionTicks(state, playlistPath, requestedIndex); + request.StartTimeTicks = GetStartPositionTicks(state, requestedIndex); job = await StartFfMpeg(state, playlistPath, cancellationTokenSource).ConfigureAwait(false); } @@ -249,37 +248,76 @@ namespace MediaBrowser.Api.Playback.Hls Logger.Info("returning {0}", segmentPath); job = job ?? ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType); - return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); + return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false); } // 256k private const int BufferSize = 262144; - private long GetSeekPositionTicks(StreamState state, string playlist, int requestedIndex) + private long GetStartPositionTicks(StreamState state, int requestedIndex) { double startSeconds = 0; + var lengths = GetSegmentLengths(state); for (var i = 0; i < requestedIndex; i++) { - var segmentPath = GetSegmentPath(state, playlist, i); + startSeconds += lengths[requestedIndex]; + } + + var position = TimeSpan.FromSeconds(startSeconds).Ticks; + return position; + } - //double length; - //if (SegmentLengths.TryGetValue(Path.GetFileName(segmentPath), out length)) - //{ - // Logger.Debug("Found segment length of {0} for index {1}", length, i); - // startSeconds += length; - //} - //else - //{ - // startSeconds += state.SegmentLength; - //} - startSeconds += state.SegmentLength; + private long GetEndPositionTicks(StreamState state, int requestedIndex) + { + double startSeconds = 0; + var lengths = GetSegmentLengths(state); + + for (var i = 0; i <= requestedIndex; i++) + { + startSeconds += lengths[requestedIndex]; } var position = TimeSpan.FromSeconds(startSeconds).Ticks; return position; } + private double[] GetSegmentLengths(StreamState state) + { + var result = new List<double>(); + var encoder = GetVideoEncoder(state); + + if (string.Equals(encoder, "copy", StringComparison.OrdinalIgnoreCase)) + { + var videoStream = state.VideoStream; + if (videoStream.KeyFrames != null && videoStream.KeyFrames.Count > 0) + { + foreach (var frame in videoStream.KeyFrames) + { + var seconds = TimeSpan.FromMilliseconds(frame).TotalSeconds; + seconds -= result.Sum(); + result.Add(seconds); + } + return result.ToArray(); + } + } + + var ticks = state.RunTimeTicks ?? 0; + + var segmentLengthTicks = TimeSpan.FromSeconds(state.SegmentLength).Ticks; + + while (ticks > 0) + { + var length = ticks >= segmentLengthTicks ? segmentLengthTicks : ticks; + + result.Add(TimeSpan.FromTicks(length).TotalSeconds); + + ticks -= length; + } + + return result.ToArray(); + } + public int? GetCurrentTranscodingIndex(string playlist, string segmentExtension) { var job = ApiEntryPoint.Instance.GetTranscodingJob(playlist, TranscodingJobType); @@ -384,17 +422,16 @@ namespace MediaBrowser.Api.Playback.Hls return Path.Combine(folder, filename + index.ToString(UsCulture) + GetSegmentFileExtension(state)); } - private async Task<object> GetSegmentResult(string playlistPath, + private async Task<object> GetSegmentResult(StreamState state, string playlistPath, string segmentPath, int segmentIndex, - int segmentLength, TranscodingJob transcodingJob, CancellationToken cancellationToken) { // If all transcoding has completed, just return immediately if (transcodingJob != null && transcodingJob.HasExited && File.Exists(segmentPath)) { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } var segmentFilename = Path.GetFileName(segmentPath); @@ -414,7 +451,7 @@ namespace MediaBrowser.Api.Playback.Hls { if (File.Exists(segmentPath)) { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } //break; } @@ -465,13 +502,12 @@ namespace MediaBrowser.Api.Playback.Hls //} cancellationToken.ThrowIfCancellationRequested(); - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + return GetSegmentResult(state, segmentPath, segmentIndex, transcodingJob); } - private object GetSegmentResult(string segmentPath, int index, int segmentLength, TranscodingJob transcodingJob) + private object GetSegmentResult(StreamState state, string segmentPath, int index, TranscodingJob transcodingJob) { - var segmentEndingSeconds = (1 + index) * segmentLength; - var segmentEndingPositionTicks = TimeSpan.FromSeconds(segmentEndingSeconds).Ticks; + var segmentEndingPositionTicks = GetEndPositionTicks(state, index); return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { @@ -698,26 +734,22 @@ namespace MediaBrowser.Api.Playback.Hls { var state = await GetState(request, CancellationToken.None).ConfigureAwait(false); + var segmentLengths = GetSegmentLengths(state); + var builder = new StringBuilder(); builder.AppendLine("#EXTM3U"); builder.AppendLine("#EXT-X-VERSION:3"); - builder.AppendLine("#EXT-X-TARGETDURATION:" + (state.SegmentLength).ToString(UsCulture)); + builder.AppendLine("#EXT-X-TARGETDURATION:" + Math.Ceiling((segmentLengths.Length > 0 ? segmentLengths.Max() : state.SegmentLength)).ToString(UsCulture)); builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); var queryStringIndex = Request.RawUrl.IndexOf('?'); var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex); - var seconds = TimeSpan.FromTicks(state.RunTimeTicks ?? 0).TotalSeconds; - var index = 0; - double segmentLength = state.SegmentLength; - - while (seconds > 0) + foreach (var length in segmentLengths) { - var length = seconds >= state.SegmentLength ? segmentLength : seconds; - builder.AppendLine("#EXTINF:" + length.ToString("0.000000", UsCulture) + ","); builder.AppendLine(string.Format("hlsdynamic/{0}/{1}{2}{3}", @@ -727,7 +759,6 @@ namespace MediaBrowser.Api.Playback.Hls GetSegmentFileExtension(isOutputVideo), queryString)); - seconds -= length; index++; } @@ -850,11 +881,6 @@ namespace MediaBrowser.Api.Playback.Hls args += " -flags +loop-global_header -sc_threshold 0"; } - if (!EnableSplitTranscoding(state)) - { - //args += " -copyts"; - } - return args; } @@ -870,21 +896,6 @@ namespace MediaBrowser.Api.Playback.Hls var toTimeParam = string.Empty; var timestampOffsetParam = string.Empty; - if (EnableSplitTranscoding(state)) - { - var startTime = state.Request.StartTimeTicks ?? 0; - var durationSeconds = ApiEntryPoint.Instance.GetEncodingOptions().ThrottleThresholdInSeconds; - - var endTime = startTime + TimeSpan.FromSeconds(durationSeconds).Ticks; - endTime = Math.Min(endTime, state.RunTimeTicks.Value); - - if (endTime < state.RunTimeTicks.Value) - { - //toTimeParam = " -to " + MediaEncoder.GetTimeParameter(endTime); - toTimeParam = " -t " + MediaEncoder.GetTimeParameter(TimeSpan.FromSeconds(durationSeconds).Ticks); - } - } - if (state.IsOutputVideo && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && (state.Request.StartTimeTicks ?? 0) > 0) { timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0).ToString(CultureInfo.InvariantCulture); @@ -927,36 +938,7 @@ namespace MediaBrowser.Api.Playback.Hls protected override bool EnableThrottling(StreamState state) { - return !EnableSplitTranscoding(state); - } - - private bool EnableSplitTranscoding(StreamState state) - { - return false; - if (string.Equals(Request.QueryString["EnableSplitTranscoding"], "false", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - return state.RunTimeTicks.HasValue && state.IsOutputVideo; - } - - protected override bool EnableStreamCopy - { - get - { - return false; - } + return true; } /// <summary> diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index a8cd3257c..c49cbc654 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -226,7 +226,9 @@ </EmbeddedResource> </ItemGroup> <ItemGroup> - <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282014%29.xml" /> + <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282014%29.xml"> + <SubType>Designer</SubType> + </EmbeddedResource> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 1005decb1..d30b105a5 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -248,8 +248,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { try { - //stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken) - // .ConfigureAwait(false); + //stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -283,7 +282,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private async Task<List<int>> GetKeyFrames(string inputPath, int videoStreamIndex, CancellationToken cancellationToken) { - const string args = "-i {0} -select_streams v:{1} -show_frames -show_entries frame=pkt_dts,key_frame -print_format compact"; + const string args = "-i {0} -select_streams v:{1} -show_packets -print_format compact -show_entries packet=flags -show_entries packet=pts_time"; var process = new Process { @@ -318,7 +317,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { process.BeginErrorReadLine(); - await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false); + await StartReadingOutput(process.StandardOutput.BaseStream, lines, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -336,7 +335,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - private async Task StartReadingOutput(Stream source, List<int> lines, int timeoutMs, CancellationToken cancellationToken) + private async Task StartReadingOutput(Stream source, List<int> lines, CancellationToken cancellationToken) { try { @@ -354,14 +353,15 @@ namespace MediaBrowser.MediaEncoding.Encoder .Where(i => i.Length == 2) .ToDictionary(i => i[0], i => i[1]); - string pktDts; - int frameMs; - if (values.TryGetValue("pkt_dts", out pktDts) && int.TryParse(pktDts, NumberStyles.Any, CultureInfo.InvariantCulture, out frameMs)) + string flags; + if (values.TryGetValue("flags", out flags) && string.Equals(flags, "k", StringComparison.OrdinalIgnoreCase)) { - string keyFrame; - if (values.TryGetValue("key_frame", out keyFrame) && string.Equals(keyFrame, "1", StringComparison.OrdinalIgnoreCase)) + string pts_time; + double frameSeconds; + if (values.TryGetValue("pts_time", out pts_time) && double.TryParse(pts_time, NumberStyles.Any, CultureInfo.InvariantCulture, out frameSeconds)) { - lines.Add(frameMs); + var ms = frameSeconds * 1000; + lines.Add(Convert.ToInt32(ms)); } } } @@ -376,7 +376,6 @@ namespace MediaBrowser.MediaEncoding.Encoder _logger.ErrorException("Error reading ffprobe output", ex); } } - /// <summary> /// The us culture /// </summary> @@ -802,7 +801,7 @@ namespace MediaBrowser.MediaEncoding.Encoder public ProcessWrapper(Process process, MediaEncoder mediaEncoder, ILogger logger) { Process = process; - this._mediaEncoder = mediaEncoder; + _mediaEncoder = mediaEncoder; _logger = logger; Process.Exited += Process_Exited; } @@ -819,7 +818,6 @@ namespace MediaBrowser.MediaEncoding.Encoder } catch (Exception ex) { - _logger.ErrorException("Error determing process exit code", ex); } lock (_mediaEncoder._runningProcesses) diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 0aaa8035c..519d3a04c 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Model.Dlna; +using System.Collections.Generic; +using System.Runtime.Serialization; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Extensions; using System.Diagnostics; @@ -225,5 +227,8 @@ namespace MediaBrowser.Model.Entities /// </summary> /// <value><c>null</c> if [is cabac] contains no value, <c>true</c> if [is cabac]; otherwise, <c>false</c>.</value> public bool? IsCabac { get; set; } + + [IgnoreDataMember] + public List<int> KeyFrames { get; set; } } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 395d95cc5..9fc8e1f8a 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Providers.MediaInfo return ItemUpdateType.MetadataImport; } - private const string SchemaVersion = "5"; + private const string SchemaVersion = "6"; private async Task<Model.MediaInfo.MediaInfo> GetMediaInfo(Video item, IIsoMount isoMount, @@ -140,14 +140,14 @@ namespace MediaBrowser.Providers.MediaInfo { cancellationToken.ThrowIfCancellationRequested(); - var idString = item.Id.ToString("N"); - var cachePath = Path.Combine(_appPaths.CachePath, - "ffprobe-video", - idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json"); + //var idString = item.Id.ToString("N"); + //var cachePath = Path.Combine(_appPaths.CachePath, + // "ffprobe-video", + // idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json"); try { - return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath); + //return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath); } catch (FileNotFoundException) { @@ -174,8 +174,8 @@ namespace MediaBrowser.Providers.MediaInfo }, cancellationToken).ConfigureAwait(false); - Directory.CreateDirectory(Path.GetDirectoryName(cachePath)); - _json.SerializeToFile(result, cachePath); + //Directory.CreateDirectory(Path.GetDirectoryName(cachePath)); + //_json.SerializeToFile(result, cachePath); return result; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 806e86a5a..04f09602f 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -187,6 +187,13 @@ namespace MediaBrowser.Server.Implementations.Persistence /// </summary> private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1); + private string[] _retriveItemColumns = + { + "type", + "data", + "IsOffline" + }; + /// <summary> /// Prepares the statements. /// </summary> @@ -398,7 +405,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.ForcedSortName; _saveItemCommand.GetParameter(index++).Value = item.IsOffline; - + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -455,7 +462,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select type,data from TypedBaseItems where guid = @guid"; + cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems where guid = @guid"; cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = id; using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) @@ -482,11 +489,18 @@ namespace MediaBrowser.Server.Implementations.Persistence return null; } + BaseItem item; + using (var stream = reader.GetMemoryStream(1)) { try { - return _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem; + item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem; + + if (item == null) + { + return null; + } } catch (SerializationException ex) { @@ -494,6 +508,13 @@ namespace MediaBrowser.Server.Implementations.Persistence return null; } } + + if (!reader.IsDBNull(2)) + { + item.IsOffline = reader.GetBoolean(2); + } + + return item; } /// <summary> @@ -685,7 +706,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select type,data from TypedBaseItems where guid in (select ItemId from ChildrenIds where ParentId = @ParentId)"; + cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems where guid in (select ItemId from ChildrenIds where ParentId = @ParentId)"; cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = parentId; @@ -715,7 +736,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select type,data from TypedBaseItems where type = @type"; + cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems where type = @type"; cmd.Parameters.Add(cmd, "@type", DbType.String).Value = type.FullName; @@ -745,7 +766,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select type,data from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems"; var whereClauses = GetWhereClauses(query, cmd, false); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs index 994397624..9e97858d0 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Persistence; +using System.Globalization; +using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; @@ -38,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Persistence // Add PixelFormat column - createTableCommand += "(ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, PRIMARY KEY (ItemId, StreamIndex))"; + createTableCommand += "(ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, KeyFrames TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; string[] queries = { @@ -58,6 +59,7 @@ namespace MediaBrowser.Server.Implementations.Persistence AddBitDepthCommand(); AddIsAnamorphicColumn(); AddIsCabacColumn(); + AddKeyFramesColumn(); AddRefFramesCommand(); PrepareStatements(); @@ -187,6 +189,37 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.RunQueries(new[] { builder.ToString() }, _logger); } + private void AddKeyFramesColumn() + { + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "PRAGMA table_info(mediastreams)"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + if (!reader.IsDBNull(1)) + { + var name = reader.GetString(1); + + if (string.Equals(name, "KeyFrames", StringComparison.OrdinalIgnoreCase)) + { + return; + } + } + } + } + } + + var builder = new StringBuilder(); + + builder.AppendLine("alter table mediastreams"); + builder.AppendLine("add column KeyFrames TEXT NULL"); + + _connection.RunQueries(new[] { builder.ToString() }, _logger); + } + private void AddIsAnamorphicColumn() { using (var cmd = _connection.CreateCommand()) @@ -245,7 +278,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "BitDepth", "IsAnamorphic", "RefFrames", - "IsCabac" + "IsCabac", + "KeyFrames" }; /// <summary> @@ -429,6 +463,15 @@ namespace MediaBrowser.Server.Implementations.Persistence item.IsCabac = reader.GetBoolean(25); } + if (!reader.IsDBNull(26)) + { + var frames = reader.GetString(26); + if (!string.IsNullOrWhiteSpace(frames)) + { + item.KeyFrames = frames.Split(',').Select(i => int.Parse(i, CultureInfo.InvariantCulture)).ToList(); + } + } + return item; } @@ -498,6 +541,15 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStreamCommand.GetParameter(index++).Value = stream.RefFrames; _saveStreamCommand.GetParameter(index++).Value = stream.IsCabac; + if (stream.KeyFrames == null || stream.KeyFrames.Count == 0) + { + _saveStreamCommand.GetParameter(index++).Value = null; + } + else + { + _saveStreamCommand.GetParameter(index++).Value = string.Join(",", stream.KeyFrames.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()); + } + _saveStreamCommand.Transaction = transaction; _saveStreamCommand.ExecuteNonQuery(); } diff --git a/SharedVersion.cs b/SharedVersion.cs index ec5cb5676..732202201 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5713.3")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5713.4")] -- cgit v1.2.3 From f4c25b24711ddc1e042bf691d5b4c5dfdbf4a8e3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Thu, 27 Aug 2015 15:59:42 -0400 Subject: update m3u tuners --- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- .../LiveTv/TunerHosts/M3UTunerHost.cs | 153 +++++++++------------ SharedVersion.cs | 4 +- 3 files changed, 70 insertions(+), 89 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index b69cdacef..8b717e5d4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -455,7 +455,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - throw new ApplicationException("Tuner not found."); + throw new NotImplementedException(); } public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index e19b17ca4..3783e4b08 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -39,68 +39,45 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts var url = info.Url; var urlHash = url.GetMD5().ToString("N"); - int position = 0; string line; // Read the file and display it line by line. var file = new StreamReader(url); var channels = new List<M3UChannel>(); + + string channnelName = null; + string channelNumber = null; + while ((line = file.ReadLine()) != null) { line = line.Trim(); - if (!String.IsNullOrWhiteSpace(line)) + if (string.IsNullOrWhiteSpace(line)) { - if (position == 0 && !line.StartsWith("#EXTM3U")) - { - throw new ApplicationException("wrong file"); - } - if (position % 2 == 0) - { - if (position != 0) - { - channels.Last().Path = line; - } - else - { - line = line.Replace("#EXTM3U", ""); - line = line.Trim(); - var vars = line.Split(' ').ToList(); - foreach (var variable in vars) - { - var list = variable.Replace('"', ' ').Split('='); - switch (list[0]) - { - case ("id"): - //_id = list[1]; - break; - } - } - } - } - else + continue; + } + + if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) + { + var parts = line.Split(new[] { ':' }, 2).Last().Split(new[] { ',' }, 2); + channelNumber = parts[0]; + channnelName = parts[1]; + } + else if (!string.IsNullOrWhiteSpace(channelNumber)) + { + channels.Add(new M3UChannel { - if (!line.StartsWith("#EXTINF:")) { throw new ApplicationException("Bad file"); } - line = line.Replace("#EXTINF:", ""); - var nameStart = line.LastIndexOf(','); - line = line.Substring(0, nameStart); - var vars = line.Split(' ').ToList(); - vars.RemoveAt(0); - channels.Add(new M3UChannel()); - foreach (var variable in vars) - { - var list = variable.Replace('"', ' ').Split('='); - switch (list[0]) - { - case "tvg-id": - channels.Last().Id = ChannelIdPrefix + urlHash + list[1]; - channels.Last().Number = list[1]; - break; - case "tvg-name": - channels.Last().Name = list[1]; - break; - } - } - } - position++; + Name = channnelName, + Number = channelNumber, + Id = ChannelIdPrefix + urlHash + channelNumber, + Path = line + }); + + channelNumber = null; + channnelName = null; } } file.Close(); @@ -125,6 +102,35 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) + { + var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false); + + return sources.First(); + } + + class M3UChannel : ChannelInfo + { + public string Path { get; set; } + + public M3UChannel() + { + } + } + + public async Task Validate(TunerHostInfo info) + { + if (!File.Exists(info.Url)) + { + throw new FileNotFoundException(); + } + } + + protected override bool IsValidChannelId(string channelId) + { + return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); + } + + protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { var urlHash = info.Url.GetMD5().ToString("N"); var prefix = ChannelIdPrefix + urlHash; @@ -133,29 +139,29 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return null; } - channelId = channelId.Substring(prefix.Length); + //channelId = channelId.Substring(prefix.Length); var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false); var m3uchannels = channels.Cast<M3UChannel>(); - var channel = m3uchannels.FirstOrDefault(c => c.Id == channelId); + var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase)); if (channel != null) { var path = channel.Path; MediaProtocol protocol = MediaProtocol.File; - if (path.StartsWith("http")) + if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { protocol = MediaProtocol.Http; } - else if (path.StartsWith("rtmp")) + else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase)) { protocol = MediaProtocol.Rtmp; } - else if (path.StartsWith("rtsp")) + else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase)) { protocol = MediaProtocol.Rtsp; } - return new MediaSourceInfo + var mediaSource = new MediaSourceInfo { Path = channel.Path, Protocol = protocol, @@ -179,35 +185,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts RequiresOpening = false, RequiresClosing = false }; - } - throw new ApplicationException("Host doesnt provide this channel"); - } - - class M3UChannel : ChannelInfo - { - public string Path { get; set; } - - public M3UChannel() - { - } - } - public async Task Validate(TunerHostInfo info) - { - if (!File.Exists(info.Url)) - { - throw new FileNotFoundException(); + return new List<MediaSourceInfo> { mediaSource }; } - } - - protected override bool IsValidChannelId(string channelId) - { - return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); - } - - protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) - { - throw new NotImplementedException(); + return new List<MediaSourceInfo> { }; } protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) diff --git a/SharedVersion.cs b/SharedVersion.cs index 732202201..f22c8a5cb 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5713.4")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5713.4")] -- cgit v1.2.3 From a0c3bb03809612763f7b06d4f82d2a44a6ed4182 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 28 Aug 2015 00:19:08 -0400 Subject: update live tv image --- MediaBrowser.Api/Music/InstantMixService.cs | 16 +++ MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 7 +- MediaBrowser.Controller/Entities/BaseItem.cs | 4 + .../Entities/InternalItemsQuery.cs | 3 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 15 ++- MediaBrowser.Model/ApiClient/IApiClient.cs | 27 +--- .../Folders/DefaultImageProvider.cs | 147 +++++++++++++++++++++ .../MediaBrowser.Providers.csproj | 1 + .../Connect/ConnectEntryPoint.cs | 2 +- .../Connect/ConnectManager.cs | 2 +- .../Library/MusicManager.cs | 18 +++ .../MediaBrowser.Server.Implementations.csproj | 8 -- .../Persistence/CleanDatabaseScheduledTask.cs | 46 ++++++- .../Persistence/SqliteItemRepository.cs | 8 ++ .../UserViews/DynamicImageProvider.cs | 39 +----- .../UserViews/livetv/1.jpg | Bin 62382 -> 0 bytes .../UserViews/livetv/2.jpg | Bin 20550 -> 0 bytes .../UserViews/livetv/3.jpg | Bin 27983 -> 0 bytes .../UserViews/livetv/4.jpg | Bin 75468 -> 0 bytes .../UserViews/livetv/5.jpg | Bin 50933 -> 0 bytes .../UserViews/livetv/6.jpg | Bin 15931 -> 0 bytes .../UserViews/livetv/7.jpg | Bin 19916 -> 0 bytes .../UserViews/livetv/8.jpg | Bin 67721 -> 0 bytes 23 files changed, 262 insertions(+), 81 deletions(-) create mode 100644 MediaBrowser.Providers/Folders/DefaultImageProvider.cs delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/1.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/2.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/3.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/4.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/5.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/6.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/7.jpg delete mode 100644 MediaBrowser.Server.Implementations/UserViews/livetv/8.jpg (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index 905ead86c..d2a4aa60c 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -54,6 +54,11 @@ namespace MediaBrowser.Api.Music public string Id { get; set; } } + [Route("/Items/{Id}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given item")] + public class GetInstantMixFromItem : BaseGetSimilarItemsFromItem + { + } + [Authenticated] public class InstantMixService : BaseApiService { @@ -71,6 +76,17 @@ namespace MediaBrowser.Api.Music _libraryManager = libraryManager; } + public object Get(GetInstantMixFromItem request) + { + var item = _libraryManager.GetItemById(request.Id); + + var user = _userManager.GetUserById(request.UserId); + + var items = _musicManager.GetInstantMixFromItem(item, user); + + return GetResult(items, user, request); + } + public object Get(GetInstantMixFromArtistId request) { var item = _libraryManager.GetItemById(request.Id); diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 1a152790a..61fd7a55a 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -1,5 +1,4 @@ -using System.Linq; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; @@ -317,6 +316,7 @@ namespace MediaBrowser.Api.Playback.Hls { if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) { + Logger.Debug("Cannot stream copy video due to missing keyframe info"); return false; } @@ -326,8 +326,9 @@ namespace MediaBrowser.Api.Playback.Hls var length = frame - previousSegment; // Don't allow really long segments because this could result in long download times - if (length > 10000) + if (length > 12000) { + Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); return false; } previousSegment = frame; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index a333fc6e9..594b5ca93 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -419,6 +419,10 @@ namespace MediaBrowser.Controller.Entities return _sortName ?? (_sortName = CreateSortName()); } + set + { + _sortName = value; + } } public string GetInternalMetadataPath() diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 53667c6e1..0af4972f7 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -97,7 +97,8 @@ namespace MediaBrowser.Controller.Entities public int? MaxParentalRating { get; set; } public bool? IsCurrentSchema { get; set; } - + public bool? HasDeadParentId { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d30b105a5..d21a9dc3b 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -244,7 +244,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { foreach (var stream in mediaInfo.MediaStreams) { - if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase)) + if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase) && !stream.IsInterlaced) { try { @@ -282,7 +282,9 @@ namespace MediaBrowser.MediaEncoding.Encoder private async Task<List<int>> GetKeyFrames(string inputPath, int videoStreamIndex, CancellationToken cancellationToken) { - const string args = "-i {0} -select_streams v:{1} -show_packets -print_format compact -show_entries packet=flags -show_entries packet=pts_time"; + inputPath = inputPath.Split(new[] { ':' }, 2).Last().Trim('"'); + + const string args = "-show_packets -print_format compact -select_streams v:{1} -show_entries packet=flags -show_entries packet=pts_time \"{0}\""; var process = new Process { @@ -330,7 +332,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { StopProcess(processWrapper, 100, true); } - + //_logger.Debug("Found keyframes {0}", string.Join(",", lines.ToArray())); return lines; } } @@ -347,7 +349,12 @@ namespace MediaBrowser.MediaEncoding.Encoder var line = await reader.ReadLineAsync().ConfigureAwait(false); - var values = (line ?? string.Empty).Split('|') + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + var values = line.Split('|') .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(i => i.Split('=')) .Where(i => i.Length == 2) diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index c2524378e..6107c0fbe 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -320,32 +320,11 @@ namespace MediaBrowser.Model.ApiClient Task<ItemsResult> GetUserViews(string userId, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> - /// Gets the instant mix from song async. + /// Gets the instant mix from item asynchronous. /// </summary> /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetInstantMixFromSongAsync(SimilarItemsQuery query); - - /// <summary> - /// Gets the instant mix from album async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetInstantMixFromAlbumAsync(SimilarItemsQuery query); - - /// <summary> - /// Gets the instant mix from artist async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetInstantMixFromArtistAsync(SimilarItemsQuery query); - - /// <summary> - /// Gets the instant mix from music genre async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetInstantMixFromMusicGenreAsync(SimilarItemsQuery query); + /// <returns>Task<ItemsResult>.</returns> + Task<ItemsResult> GetInstantMixFromItemAsync(SimilarItemsQuery query); /// <summary> /// Gets the similar movies async. diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs new file mode 100644 index 000000000..1fbe20d7f --- /dev/null +++ b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs @@ -0,0 +1,147 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Genres; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.Folders +{ + public class DefaultImageProvider : IRemoteImageProvider, IHasItemChangeMonitor + { + private readonly IHttpClient _httpClient; + + public DefaultImageProvider(IHttpClient httpClient) + { + _httpClient = httpClient; + } + + public IEnumerable<ImageType> GetSupportedImages(IHasImages item) + { + return new List<ImageType> + { + ImageType.Primary, + ImageType.Thumb + }; + } + + public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken) + { + var view = item as UserView; + + if (view != null) + { + return GetImages(view.ViewType, cancellationToken); + } + + var folder = (ICollectionFolder)item; + return GetImages(folder.CollectionType, cancellationToken); + } + + private Task<IEnumerable<RemoteImageInfo>> GetImages(string viewType, CancellationToken cancellationToken) + { + var url = GetImageUrl(viewType); + + var list = new List<RemoteImageInfo>(); + + if (!string.IsNullOrWhiteSpace(url)) + { + list.AddRange(new List<RemoteImageInfo>{ + new RemoteImageInfo + { + ProviderName = Name, + Url = url, + Type = ImageType.Primary + }, + + new RemoteImageInfo + { + ProviderName = Name, + Url = url, + Type = ImageType.Thumb + } + }); + } + + return Task.FromResult<IEnumerable<RemoteImageInfo>>(list); + } + + private string GetImageUrl(string viewType) + { + const string urlPrefix = "https://raw.githubusercontent.com/MediaBrowser/Emby.Resources/master/images/folders/"; + + if (string.Equals(viewType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "books.png"; + } + if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "games.png"; + } + if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "music.png"; + } + if (string.Equals(viewType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "photos.png"; + } + if (string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "tv.png"; + } + if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "channels.png"; + } + if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + { + return urlPrefix + "livetv.png"; + } + if (string.Equals(viewType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) + { + //return urlPrefix + "movies.png"; + } + + return null; + //return urlPrefix + "generic.png"; + } + + public string Name + { + get { return "Default Image Provider"; } + } + + public bool Supports(IHasImages item) + { + var view = item as UserView; + + if (view != null) + { + return !view.UserId.HasValue; + } + + return item is ICollectionFolder; + } + + public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) + { + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url, + ResourcePool = GenreImageProvider.ImageDownloadResourcePool + }); + } + + public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) + { + return GetSupportedImages(item).Any(i => !item.HasImage(i)); + } + } +} diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 444567afa..1d323e567 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -83,6 +83,7 @@ <Compile Include="BoxSets\MovieDbBoxSetProvider.cs" /> <Compile Include="Channels\ChannelMetadataService.cs" /> <Compile Include="Chapters\ChapterManager.cs" /> + <Compile Include="Folders\DefaultImageProvider.cs" /> <Compile Include="Folders\FolderMetadataService.cs" /> <Compile Include="Channels\AudioChannelItemMetadataService.cs" /> <Compile Include="Folders\UserViewMetadataService.cs" /> diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 973519a77..8a659fb65 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Connect _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); } - private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.mediabrowser.tv/service/ip" }; + private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.emby.media/service/ip" }; private async void TimerCallback(object state) { diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 4569503c0..7cd96c5f3 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -371,7 +371,7 @@ namespace MediaBrowser.Server.Implementations.Connect private string GetConnectUrl(string handler) { - return "https://connect.mediabrowser.tv/service/" + handler; + return "https://connect.emby.media/service/" + handler; } public async Task<UserLinkResult> LinkUser(string userId, string connectUsername) diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index b83256342..683e6c5cc 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -52,6 +52,18 @@ namespace MediaBrowser.Server.Implementations.Library return GetInstantMixFromGenres(genres, user); } + public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user) + { + var genres = item + .GetRecursiveChildren(user, i => i is Audio) + .Cast<Audio>() + .SelectMany(i => i.Genres) + .Concat(item.Genres) + .DistinctNames(); + + return GetInstantMixFromGenres(genres, user); + } + public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user) { var genres = item @@ -113,6 +125,12 @@ namespace MediaBrowser.Server.Implementations.Library { return GetInstantMixFromSong(song, user); } + + var folder = item as Folder; + if (folder != null) + { + return GetInstantMixFromFolder(folder, user); + } return new Audio[] { }; } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index b2da2489d..f0312cef6 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -495,14 +495,6 @@ <Link>swagger-ui\swagger-ui.min.js</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> - <EmbeddedResource Include="UserViews\livetv\1.jpg" /> - <EmbeddedResource Include="UserViews\livetv\2.jpg" /> - <EmbeddedResource Include="UserViews\livetv\3.jpg" /> - <EmbeddedResource Include="UserViews\livetv\4.jpg" /> - <EmbeddedResource Include="UserViews\livetv\5.jpg" /> - <EmbeddedResource Include="UserViews\livetv\6.jpg" /> - <EmbeddedResource Include="UserViews\livetv\7.jpg" /> - <EmbeddedResource Include="UserViews\livetv\8.jpg" /> <EmbeddedResource Include="Localization\iso6392.txt" /> <EmbeddedResource Include="Localization\Ratings\be.txt" /> </ItemGroup> diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 7a993b7db..d913063c8 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -46,9 +46,16 @@ namespace MediaBrowser.Server.Implementations.Persistence public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(progress.Report); + innerProgress.RegisterAction(p => progress.Report(.95 * p)); await UpdateToLatestSchema(cancellationToken, innerProgress).ConfigureAwait(false); + + innerProgress = new ActionableProgress<double>(); + innerProgress.RegisterAction(p => progress.Report(95 + (.05 * p))); + + //await CleanDeadItems(cancellationToken, innerProgress).ConfigureAwait(false); + + progress.Report(100); } private async Task UpdateToLatestSchema(CancellationToken cancellationToken, IProgress<double> progress) @@ -92,6 +99,43 @@ namespace MediaBrowser.Server.Implementations.Persistence progress.Report(100); } + private async Task CleanDeadItems(CancellationToken cancellationToken, IProgress<double> progress) + { + var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery + { + HasDeadParentId = true + }); + + var numComplete = 0; + var numItems = itemIds.Count; + + _logger.Debug("Cleaning {0} items with dead parent links", numItems); + + foreach (var itemId in itemIds) + { + cancellationToken.ThrowIfCancellationRequested(); + + var item = _libraryManager.GetItemById(itemId); + + if (item != null) + { + _logger.Debug("Cleaning item {0} type: {1} path: {2}", item.Name, item.GetType().Name, item.Path ?? string.Empty); + + await _libraryManager.DeleteItem(item, new DeleteOptions + { + DeleteFileLocation = false + }); + } + + numComplete++; + double percent = numComplete; + percent /= numItems; + progress.Report(percent * 100); + } + + progress.Report(100); + } + public IEnumerable<ITaskTrigger> GetDefaultTriggers() { return new ITaskTrigger[] diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 04f09602f..00ebf7ea6 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1096,6 +1096,14 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (query.HasDeadParentId.HasValue) + { + if (query.HasDeadParentId.Value) + { + whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)"); + } + } + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index b11a7d167..c2ddf3c43 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -11,8 +11,6 @@ using MediaBrowser.Server.Implementations.Photos; using MoreLinq; using System; using System.Collections.Generic; -using System.Globalization; -using System.IO; using System.Linq; using System.Threading.Tasks; @@ -154,7 +152,6 @@ namespace MediaBrowser.Server.Implementations.UserViews CollectionType.BoxSets, CollectionType.Playlists, CollectionType.Channels, - CollectionType.LiveTv, CollectionType.Books, CollectionType.Photos, CollectionType.HomeVideos, @@ -170,7 +167,7 @@ namespace MediaBrowser.Server.Implementations.UserViews var view = (UserView)item; if (imageType == ImageType.Primary && IsUsingCollectionStrip(view)) { - if (itemsWithImages.Count == 0 && !string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + if (itemsWithImages.Count == 0) { return false; } @@ -180,39 +177,5 @@ namespace MediaBrowser.Server.Implementations.UserViews return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); } - - protected override IEnumerable<String> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items) - { - var userView = primaryItem as UserView; - - if (userView != null && string.Equals(userView.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) - { - var list = new List<string>(); - for (int i = 1; i <= 8; i++) - { - list.Add(ExtractLiveTvResource(i.ToString(CultureInfo.InvariantCulture), ApplicationPaths)); - } - return list; - } - - return base.GetStripCollageImagePaths(primaryItem, items); - } - - private string ExtractLiveTvResource(string name, IApplicationPaths paths) - { - var namespacePath = GetType().Namespace + ".livetv." + name + ".jpg"; - var tempPath = Path.Combine(paths.TempDirectory, Guid.NewGuid().ToString("N") + ".jpg"); - Directory.CreateDirectory(Path.GetDirectoryName(tempPath)); - - using (var stream = GetType().Assembly.GetManifestResourceStream(namespacePath)) - { - using (var fileStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.Read)) - { - stream.CopyTo(fileStream); - } - } - - return tempPath; - } } } diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/1.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/1.jpg deleted file mode 100644 index 2594b68a4..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/1.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/2.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/2.jpg deleted file mode 100644 index e5c87b96b..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/2.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/3.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/3.jpg deleted file mode 100644 index c19f7e612..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/3.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/4.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/4.jpg deleted file mode 100644 index 93ee18044..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/4.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/5.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/5.jpg deleted file mode 100644 index 4c2cd580d..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/5.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/6.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/6.jpg deleted file mode 100644 index 6f496b6ac..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/6.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/7.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/7.jpg deleted file mode 100644 index e7dba2760..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/7.jpg and /dev/null differ diff --git a/MediaBrowser.Server.Implementations/UserViews/livetv/8.jpg b/MediaBrowser.Server.Implementations/UserViews/livetv/8.jpg deleted file mode 100644 index c69ba908c..000000000 Binary files a/MediaBrowser.Server.Implementations/UserViews/livetv/8.jpg and /dev/null differ -- cgit v1.2.3 From 31e36a56e7de0cadeab5f619de9ed5b0986bd2bc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 28 Aug 2015 11:02:22 -0400 Subject: update live tv menu --- MediaBrowser.Providers/Folders/DefaultImageProvider.cs | 4 ++++ MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs | 1 - MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs index 1fbe20d7f..6c719713b 100644 --- a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs +++ b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs @@ -107,6 +107,10 @@ namespace MediaBrowser.Providers.Folders { //return urlPrefix + "movies.png"; } + if (string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)) + { + return urlPrefix + "playlists.png"; + } return null; //return urlPrefix + "generic.png"; diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index c2ddf3c43..844238228 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -150,7 +150,6 @@ namespace MediaBrowser.Server.Implementations.UserViews CollectionType.Games, CollectionType.Music, CollectionType.BoxSets, - CollectionType.Playlists, CollectionType.Channels, CollectionType.Books, CollectionType.Photos, diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 06ade9e84..01e74d066 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -423,7 +423,6 @@ namespace MediaBrowser.WebDashboard.Api var files = new[] { - "thirdparty/fontawesome/css/font-awesome.min.css" + versionString, "css/all.css" + versionString }; -- cgit v1.2.3 From 0d3aa4f7efac957058086ff12256aad38e867d74 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 28 Aug 2015 13:59:09 -0400 Subject: update metadata setting --- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs index 8cb76393e..2f219c299 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks { var list = new ITaskTrigger[] { - new IntervalTrigger{ Interval = TimeSpan.FromHours(8)} + new IntervalTrigger{ Interval = TimeSpan.FromHours(12)} }.ToList(); -- cgit v1.2.3 From 274d8176b31a97bb9c8432e4f3a4ba9401a4b1e6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Fri, 28 Aug 2015 20:50:39 -0400 Subject: update hls --- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 2 +- .../Folders/DefaultImageProvider.cs | 2 +- .../LiveTv/EmbyTV/EntryPoint.cs | 33 ++-------------------- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +-- 7 files changed, 10 insertions(+), 39 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 61fd7a55a..5d377366a 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -326,7 +326,7 @@ namespace MediaBrowser.Api.Playback.Hls var length = frame - previousSegment; // Don't allow really long segments because this could result in long download times - if (length > 12000) + if (length > 10000) { Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); return false; diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs index 6c719713b..506e983c6 100644 --- a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs +++ b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Providers.Folders if (view != null) { - return !view.UserId.HasValue; + return true; } return item is ICollectionFolder; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs index a297c866a..713cb9cd3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs @@ -1,41 +1,12 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Security; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.LiveTv; +using MediaBrowser.Controller.Plugins; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { public class EntryPoint : IServerEntryPoint { - private readonly IConfigurationManager _config; - private readonly ISecurityManager _manager; - - public EntryPoint(IConfigurationManager config, ISecurityManager manager) - { - _config = config; - _manager = manager; - } - - public async void Run() + public void Run() { EmbyTV.Current.Start(); - - if (GetConfiguration().ListingProviders.Count > 0 || GetConfiguration().TunerHosts.Count > 0) - { - try - { - await _manager.GetRegistrationStatus("livetvguide").ConfigureAwait(false); - } - catch - { - - } - } - } - - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration<LiveTvOptions>("livetv"); } public void Dispose() diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index a0702fb68..f92e05492 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.632</version> + <version>3.0.633</version> <title>MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 56e6f5c69..04d4deb7c 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.632 + 3.0.633 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 654d33b5c..2a75ac3a8 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.632 + 3.0.633 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index b72d50d69..da8309410 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.632 + 3.0.633 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 0394d403976b8cd7d87d7c19abd57bdc2d9651cf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 29 Aug 2015 20:40:52 -0400 Subject: update select server --- .../Persistence/CleanDatabaseScheduledTask.cs | 13 ++++++++++++- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 7 ++----- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 --- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index d913063c8..9f87483ba 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -81,7 +81,18 @@ namespace MediaBrowser.Server.Implementations.Persistence if (item != null) { - await _itemRepo.SaveItem(item, cancellationToken).ConfigureAwait(false); + try + { + await _itemRepo.SaveItem(item, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception ex) + { + _logger.ErrorException("Error saving item", ex); + } } numComplete++; diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 01e74d066..dac56d24d 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -651,13 +651,11 @@ namespace MediaBrowser.WebDashboard.Api private async Task GetAllCss(bool enableMinification) { var memoryStream = new MemoryStream(); - var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine); - - await AppendResource(memoryStream, "thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.theme.min.css", newLineBytes).ConfigureAwait(false); - await AppendResource(memoryStream, "thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.structure.min.css", newLineBytes).ConfigureAwait(false); var files = new[] { + "thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.theme.css", + "thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.structure.css", "css/site.css", "css/chromecast.css", "css/nowplayingbar.css", @@ -668,7 +666,6 @@ namespace MediaBrowser.WebDashboard.Api "css/card.css", "css/notifications.css", "css/search.css", - "css/pluginupdates.css", "css/remotecontrol.css", "css/userimage.css", "css/nowplaying.css", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 07792b82d..11b96a869 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -847,9 +847,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 024e451bb12b985000c4955027c7953afe13b9ee Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 30 Aug 2015 13:51:17 -0400 Subject: update translations --- MediaBrowser.Server.Implementations/Localization/Core/kk.json | 2 +- MediaBrowser.Server.Implementations/Localization/Core/ru.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Localization/Core/kk.json b/MediaBrowser.Server.Implementations/Localization/Core/kk.json index f57b9ee12..7e17dea6b 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/kk.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/kk.json @@ -121,7 +121,7 @@ "UserStoppedPlayingItemWithValues": "{0} - {1} \u043e\u0439\u043d\u0430\u0442\u0443\u044b \u0442\u043e\u049b\u0442\u0430\u043b\u0434\u044b", "SubtitleDownloadFailureForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 {0} \u04af\u0448\u0456\u043d \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u044b\u043d\u0443\u044b \u0441\u04d9\u0442\u0441\u0456\u0437", "HeaderUnidentified": "\u0410\u043d\u044b\u049b\u0442\u0430\u043b\u043c\u0430\u0493\u0430\u043d", - "HeaderImagePrimary": "\u0411\u0430\u0441\u0442\u0430\u043f\u049b\u044b", + "HeaderImagePrimary": "\u041d\u0435\u0433\u0456\u0437\u0433\u0456", "HeaderImageBackdrop": "\u0410\u0440\u0442\u049b\u044b \u0441\u0443\u0440\u0435\u0442", "HeaderImageLogo": "\u041b\u043e\u0433\u043e\u0442\u0438\u043f", "HeaderUserPrimaryImage": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0441\u0443\u0440\u0435\u0442\u0456", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ru.json b/MediaBrowser.Server.Implementations/Localization/Core/ru.json index 6a8bae45a..c705ddef4 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ru.json @@ -121,7 +121,7 @@ "UserStoppedPlayingItemWithValues": "{0} - \u0432\u043e\u0441\u043f\u0440-\u0438\u0435 \u00ab{1}\u00bb \u043e\u0441\u0442-\u043d\u043e", "SubtitleDownloadFailureForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u043a {0} \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c", "HeaderUnidentified": "\u041d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043e", - "HeaderImagePrimary": "\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439", + "HeaderImagePrimary": "\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439", "HeaderImageBackdrop": "\u0417\u0430\u0434\u043d\u0438\u043a", "HeaderImageLogo": "\u041b\u043e\u0433\u043e\u0442\u0438\u043f", "HeaderUserPrimaryImage": "\u0420\u0438\u0441\u0443\u043d\u043e\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", -- cgit v1.2.3 From 8e8ce40de20c2d85e09a33c8345b7dbac0a6419d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 31 Aug 2015 00:57:12 -0400 Subject: display current program in tv channel osd --- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 9 +++++++ MediaBrowser.Model/Dto/BaseItemDto.cs | 6 ++++- .../Dto/DtoService.cs | 16 ++++++------- .../LiveTv/LiveTvManager.cs | 28 ++++++++++++++++++++++ 4 files changed, 50 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 2b121eeeb..1458c1bc2 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -372,5 +372,14 @@ namespace MediaBrowser.Controller.LiveTv /// The feature. /// Task<MBRegistrationRecord>. Task GetRegistrationInfo(string channelId, string programId, string feature); + + /// + /// Adds the channel information. + /// + /// The dto. + /// The channel. + /// The options. + /// The user. + void AddChannelInfo(BaseItemDto dto, LiveTvChannel channel, DtoOptions options, User user); } } diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index ac8fa3370..a1c075563 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1195,6 +1195,10 @@ namespace MediaBrowser.Model.Dto /// /// The timer identifier. public string TimerId { get; set; } - + /// + /// Gets or sets the current program. + /// + /// The current program. + public BaseItemDto CurrentProgram { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index aa6ab1d65..edfef38fd 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -98,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Dto var byName = item as IItemByName; - if (byName != null && !(item is LiveTvChannel)) + if (byName != null) { if (options.Fields.Contains(ItemFields.ItemCounts)) { @@ -140,7 +140,7 @@ namespace MediaBrowser.Server.Implementations.Dto var byName = item as IItemByName; - if (byName != null && !(item is LiveTvChannel)) + if (byName != null) { if (options.Fields.Contains(ItemFields.ItemCounts)) { @@ -351,6 +351,12 @@ namespace MediaBrowser.Server.Implementations.Dto AttachBasicFields(dto, item, owner, options); + var tvChannel = item as LiveTvChannel; + if (tvChannel != null) + { + _livetvManager().AddChannelInfo(dto, tvChannel, options, user); + } + var collectionFolder = item as ICollectionFolder; if (collectionFolder != null) { @@ -1520,12 +1526,6 @@ namespace MediaBrowser.Server.Implementations.Dto SetPhotoProperties(dto, photo); } - var tvChannel = item as LiveTvChannel; - if (tvChannel != null) - { - dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(tvChannel, true).ToList(); - } - dto.ChannelId = item.ChannelId; var channelItem = item as IChannelItem; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 9cd4a2334..ff7700124 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1040,6 +1040,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv { cancellationToken.ThrowIfCancellationRequested(); + _logger.Debug("Refreshing guide from {0}", service.Name); + try { var innerProgress = new ActionableProgress(); @@ -1721,6 +1723,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv return dto; } + public void AddChannelInfo(BaseItemDto dto, LiveTvChannel channel, DtoOptions options, User user) + { + dto.MediaSources = channel.GetMediaSources(true).ToList(); + + var now = DateTime.UtcNow; + + var programs = _libraryManager.GetItems(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + ChannelIds = new[] { channel.Id.ToString("N") }, + MaxStartDate = now, + MinEndDate = now, + Limit = 1 + + }).Items.Cast(); + + var currentProgram = programs + .OrderBy(i => i.StartDate) + .FirstOrDefault(); + + if (currentProgram != null) + { + dto.CurrentProgram = _dtoService.GetBaseItemDto(currentProgram, options, user); + } + } + private async Task> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null) { var service = program != null && !string.IsNullOrWhiteSpace(program.ServiceName) ? -- cgit v1.2.3 From e5122b189fbad8109f379f3f071fcf357417aa62 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 31 Aug 2015 19:47:47 -0400 Subject: trim jqm --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 6 +++++- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 8b717e5d4..4e0d6e8d4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -482,6 +482,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { var timer = e.Argument; + _logger.Info("Recording timer fired."); + try { var cancellationTokenSource = new CancellationTokenSource(); @@ -502,7 +504,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (DateTime.UtcNow < timer.EndDate) { const int retryIntervalSeconds = 60; - _logger.Debug("Retrying recording in {0} seconds.", retryIntervalSeconds); + _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); } @@ -594,6 +596,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recording.DateLastUpdated = DateTime.UtcNow; _recordingProvider.Update(recording); + _logger.Info("Beginning recording."); + try { httpRequestOptions.BufferContent = false; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 11b96a869..86d3cb787 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -324,6 +324,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -2652,6 +2655,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 30c8937e36734ee9070830b974f34cb494b378fa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Sep 2015 02:22:46 -0400 Subject: removed pagebeforeshowready --- .../HttpServer/RangeRequestWriter.cs | 56 ---------------------- .../MediaBrowser.WebDashboard.csproj | 6 +++ 2 files changed, 6 insertions(+), 56 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index a5c69317b..9106fa059 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -235,62 +235,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer } } - /// - /// Writes to async. - /// - /// The response stream. - /// Task. - private async Task WriteToAsync(Stream responseStream) - { - try - { - // Headers only - if (IsHeadRequest) - { - return; - } - - using (var source = SourceStream) - { - // If the requested range is "0-", we can optimize by just doing a stream copy - if (RangeEnd >= TotalContentLength - 1) - { - await source.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false); - } - else - { - await CopyToAsyncInternal(source, responseStream, Convert.ToInt32(RangeLength), CancellationToken.None).ConfigureAwait(false); - } - } - } - finally - { - if (OnComplete != null) - { - OnComplete(); - } - } - } - - private async Task CopyToAsyncInternal(Stream source, Stream destination, int copyLength, CancellationToken cancellationToken) - { - var array = new byte[BufferSize]; - int count; - while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) - { - var bytesToCopy = Math.Min(count, copyLength); - - await destination.WriteAsync(array, 0, bytesToCopy, cancellationToken).ConfigureAwait(false); - - copyLength -= bytesToCopy; - - if (copyLength <= 0) - { - break; - } - } - } - public string ContentType { get; set; } public IRequest RequestContext { get; set; } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index bbdc702af..6fdcb393c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -324,6 +324,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -2664,6 +2667,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From d8c8e57a0ba2b3fe6981c577164f6cf0ecef3722 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Sep 2015 10:01:59 -0400 Subject: update tabs --- .../Folders/DefaultImageProvider.cs | 23 ++++++++++++++++++---- .../UserViews/DynamicImageProvider.cs | 10 +--------- 2 files changed, 20 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs index 506e983c6..13e486ae9 100644 --- a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs +++ b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs @@ -77,11 +77,11 @@ namespace MediaBrowser.Providers.Folders if (string.Equals(viewType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) { - //return urlPrefix + "books.png"; + return urlPrefix + "books.png"; } if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase)) { - //return urlPrefix + "games.png"; + return urlPrefix + "games.png"; } if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase)) { @@ -97,7 +97,7 @@ namespace MediaBrowser.Providers.Folders } if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase)) { - //return urlPrefix + "channels.png"; + return urlPrefix + "generic.png"; } if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) { @@ -111,9 +111,24 @@ namespace MediaBrowser.Providers.Folders { return urlPrefix + "playlists.png"; } + if (string.Equals(viewType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase)) + { + return urlPrefix + "homevideos.png"; + } + if (string.Equals(viewType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) + { + return urlPrefix + "musicvideos.png"; + } + if (string.Equals(viewType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)) + { + return urlPrefix + "generic.png"; + } + if (string.IsNullOrWhiteSpace(viewType)) + { + return urlPrefix + "generic.png"; + } return null; - //return urlPrefix + "generic.png"; } public string Name diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 844238228..8321ab952 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -147,15 +147,7 @@ namespace MediaBrowser.Server.Implementations.UserViews { CollectionType.Movies, CollectionType.TvShows, - CollectionType.Games, - CollectionType.Music, - CollectionType.BoxSets, - CollectionType.Channels, - CollectionType.Books, - CollectionType.Photos, - CollectionType.HomeVideos, - CollectionType.MusicVideos, - string.Empty + CollectionType.Music }; return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); -- cgit v1.2.3 From 3d8287bc6e3ee5b2b7377a2ddc73ef364f84fef2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Sep 2015 15:18:25 -0400 Subject: fix metadata manager layout --- .../LiveTv/Listings/SchedulesDirect.cs | 22 ++++++++++++++++++++-- .../LiveTv/LiveTvManager.cs | 6 ++++++ .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 ++ MediaBrowser.WebDashboard/Api/DashboardService.cs | 2 ++ .../MediaBrowser.WebDashboard.csproj | 6 ++++++ 5 files changed, 36 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index cb5a37401..3d02ac02e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -64,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { List programsInfo = new List(); - var token = await GetToken(info, cancellationToken); + var token = await GetToken(info, cancellationToken).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(token)) { @@ -482,7 +482,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } private readonly ConcurrentDictionary _tokens = new ConcurrentDictionary(); - + private DateTime _lastErrorResponse; private async Task GetToken(ListingsProviderInfo info, CancellationToken cancellationToken) { var username = info.Username; @@ -499,6 +499,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return null; } + // Avoid hammering SD + if ((DateTime.UtcNow - _lastErrorResponse).TotalMinutes < 1) + { + return null; + } + NameValuePair savedToken = null; if (!_tokens.TryGetValue(username, out savedToken)) { @@ -527,6 +533,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings savedToken.Value = DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture); return result; } + catch (HttpException ex) + { + if (ex.StatusCode.HasValue) + { + if ((int)ex.StatusCode.Value == 400) + { + _tokens.Clear(); + _lastErrorResponse = DateTime.UtcNow; + } + } + throw; + } finally { _tokenSemaphore.Release(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index ff7700124..9305f7be7 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -334,6 +334,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv var service = GetService(item); var sources = await service.GetChannelStreamMediaSources(item.ExternalId, cancellationToken).ConfigureAwait(false); + + if (sources.Count == 0) + { + throw new NotImplementedException(); + } + var list = sources.ToList(); foreach (var source in list) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index cab21bc3a..bccb0db0a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -377,6 +377,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun protected override async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { + Logger.Debug("GetChannelStream: channel id: {0}. stream id: {1}", channelId, streamId ?? string.Empty); + if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) { return null; diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 30dfe9088..69c4417cb 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -331,6 +331,8 @@ namespace MediaBrowser.WebDashboard.Api CopyDirectory(Path.Combine(creator.DashboardUIPath, "bower_components", "swipebox", "src", "css"), Path.Combine(path, "bower_components", "swipebox", "src", "css")); CopyDirectory(Path.Combine(creator.DashboardUIPath, "bower_components", "swipebox", "src", "js"), Path.Combine(path, "bower_components", "swipebox", "src", "js")); CopyDirectory(Path.Combine(creator.DashboardUIPath, "bower_components", "swipebox", "src", "img"), Path.Combine(path, "bower_components", "swipebox", "src", "img")); + + CopyFile(Path.Combine(creator.DashboardUIPath, "bower_components", "hammerjs", "hammer.min.js"), Path.Combine(path, "bower_components", "hammerjs", "hammer.min.js")); } MinifyCssDirectory(Path.Combine(path, "css")); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 6fdcb393c..8abd591e5 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -90,6 +90,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From a4e73120a7b896eb9f90985e0feb8bbaa7ae1d4c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Sep 2015 18:04:54 -0400 Subject: update channel streams --- MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index fe616c63e..9d43cafb8 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -586,7 +586,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles process.StandardError.BaseStream.CopyToAsync(logFileStream); - var ranToCompletion = process.WaitForExit(60000); + var ranToCompletion = process.WaitForExit(120000); if (!ranToCompletion) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 9305f7be7..d73b144b8 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -364,6 +364,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv { await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + if (string.Equals(id, mediaSourceId, StringComparison.OrdinalIgnoreCase)) + { + mediaSourceId = null; + } + try { MediaSourceInfo info; -- cgit v1.2.3 From b2931e98ee2e04ebbd97cc025c13b795ef72c5cd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Sep 2015 22:56:19 -0400 Subject: update detail page layout --- .../LiveTv/Listings/SchedulesDirect.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 3d02ac02e..d53c08150 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -80,7 +80,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { Url = ApiUrl + "/schedules", UserAgent = UserAgent, - CancellationToken = cancellationToken + CancellationToken = cancellationToken, + // The data can be large so give it some extra time + TimeoutMs = 60000 }; httpOptions.RequestHeaders["token"] = token; -- cgit v1.2.3 From 067479f2d1dcf40127ada01fbd452040a14ae877 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Sep 2015 11:33:20 -0400 Subject: update ffmpeg info --- MediaBrowser.Api/Library/LibraryService.cs | 45 ++++++++++++++++++++++ .../Session/SessionWebSocketListener.cs | 27 ++++++++----- .../FFMpeg/FFMpegDownloadInfo.cs | 4 +- 3 files changed, 64 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index ed3f2c633..96b307064 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -231,6 +231,17 @@ namespace MediaBrowser.Api.Library public string TvdbId { get; set; } } + [Route("/Library/Movies/Added", "POST", Summary = "Reports that new movies have been added by an external source")] + [Route("/Library/Movies/Updated", "POST", Summary = "Reports that new movies have been added by an external source")] + [Authenticated] + public class PostUpdatedMovies : IReturnVoid + { + [ApiMember(Name = "TmdbId", Description = "Tmdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string TmdbId { get; set; } + [ApiMember(Name = "ImdbId", Description = "Imdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string ImdbId { get; set; } + } + [Route("/Items/{Id}/Download", "GET", Summary = "Downloads item media")] [Authenticated(Roles = "download")] public class GetDownload @@ -444,6 +455,40 @@ namespace MediaBrowser.Api.Library } } + public void Post(PostUpdatedMovies request) + { + var movies = _libraryManager.GetItems(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(Movie).Name } + + }).Items; + + if (!string.IsNullOrWhiteSpace(request.ImdbId)) + { + movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).ToArray(); + } + else if (!string.IsNullOrWhiteSpace(request.TmdbId)) + { + movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)).ToArray(); + } + else + { + movies = new BaseItem[] { }; + } + + if (movies.Length > 0) + { + foreach (var item in movies) + { + _libraryMonitor.ReportFileSystemChanged(item.Path); + } + } + else + { + Task.Run(() => _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None)); + } + } + public object Get(GetDownload request) { var item = _libraryManager.GetItemById(request.Id); diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index b473444ac..602bc4876 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -85,16 +85,23 @@ namespace MediaBrowser.Server.Implementations.Session async void _httpServer_WebSocketConnecting(object sender, WebSocketConnectingEventArgs e) { - var token = e.QueryString["api_key"]; - if (!string.IsNullOrWhiteSpace(token)) - { - var session = await GetSession(e.QueryString, e.Endpoint).ConfigureAwait(false); - - if (session == null) - { - //e.AllowConnection = false; - } - } + //var token = e.QueryString["api_key"]; + //if (!string.IsNullOrWhiteSpace(token)) + //{ + // try + // { + // var session = await GetSession(e.QueryString, e.Endpoint).ConfigureAwait(false); + + // if (session == null) + // { + // e.AllowConnection = false; + // } + // } + // catch (Exception ex) + // { + // _logger.ErrorException("Error getting session info", ex); + // } + //} } private Task GetSession(NameValueCollection queryString, string remoteEndpoint) diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs index 2d4ed94f7..2910479ef 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs @@ -84,13 +84,13 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg return new[] { "http://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20150717-git-8250943-win64-static.7z", - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150717-git-8250943-win64-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150901-git-b54e03c-win64-static.7z" }; case Architecture.X86: return new[] { "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20150717-git-8250943-win32-static.7z", - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150717-git-8250943-win32-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150901-git-b54e03c-win32-static.7z" }; } break; -- cgit v1.2.3