Merge branch 'dev'
This commit is contained in:
commit
4f791d6ee1
|
@ -80,7 +80,7 @@ namespace MediaBrowser.Api
|
|||
.OrderBy(i => i)
|
||||
.ToArray();
|
||||
|
||||
result.Tags = items.OfType<IHasTags>()
|
||||
result.Tags = items
|
||||
.SelectMany(i => i.Tags)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.OrderBy(i => i)
|
||||
|
|
|
@ -10,6 +10,7 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Api
|
||||
{
|
||||
|
@ -187,18 +188,40 @@ namespace MediaBrowser.Api
|
|||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetSimilarGames request)
|
||||
{
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
|
||||
_itemRepo,
|
||||
_libraryManager,
|
||||
_userDataRepository,
|
||||
_dtoService,
|
||||
Logger,
|
||||
request, new[] { typeof(Game) },
|
||||
SimilarItemsHelper.GetSimiliarityScore);
|
||||
var result = GetSimilarItemsResult(request);
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(result);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem 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);
|
||||
|
||||
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
Limit = request.Limit,
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
typeof(Game).Name
|
||||
},
|
||||
SimilarTo = item
|
||||
|
||||
}).ToList();
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var result = new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(),
|
||||
|
||||
TotalRecordCount = itemsResult.Count
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,11 +280,7 @@ namespace MediaBrowser.Api
|
|||
episode.AbsoluteEpisodeNumber = request.AbsoluteEpisodeNumber;
|
||||
}
|
||||
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags != null)
|
||||
{
|
||||
hasTags.Tags = request.Tags;
|
||||
}
|
||||
item.Tags = request.Tags;
|
||||
|
||||
var hasTaglines = item as IHasTaglines;
|
||||
if (hasTaglines != null)
|
||||
|
@ -298,11 +294,7 @@ namespace MediaBrowser.Api
|
|||
hasShortOverview.ShortOverview = request.ShortOverview;
|
||||
}
|
||||
|
||||
var hasKeywords = item as IHasKeywords;
|
||||
if (hasKeywords != null)
|
||||
{
|
||||
hasKeywords.Keywords = request.Keywords;
|
||||
}
|
||||
item.Keywords = request.Keywords;
|
||||
|
||||
if (request.Studios != null)
|
||||
{
|
||||
|
@ -427,11 +419,6 @@ namespace MediaBrowser.Api
|
|||
series.Status = request.SeriesStatus;
|
||||
series.AirDays = request.AirDays;
|
||||
series.AirTime = request.AirTime;
|
||||
|
||||
if (request.DisplaySpecialsWithSeasons.HasValue)
|
||||
{
|
||||
series.DisplaySpecialsWithSeasons = request.DisplaySpecialsWithSeasons.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -439,6 +439,12 @@ namespace MediaBrowser.Api.LiveTv
|
|||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ListingProviders/Default", "GET")]
|
||||
[Authenticated(AllowBeforeStartupWizard = true)]
|
||||
public class GetDefaultListingProvider : ListingsProviderInfo, IReturn<ListingsProviderInfo>
|
||||
{
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ListingProviders", "POST", Summary = "Adds a listing provider")]
|
||||
[Authenticated(AllowBeforeStartupWizard = true)]
|
||||
public class AddListingProvider : ListingsProviderInfo, IReturn<ListingsProviderInfo>
|
||||
|
@ -478,6 +484,40 @@ namespace MediaBrowser.Api.LiveTv
|
|||
{
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ChannelMappingOptions")]
|
||||
[Authenticated(AllowBeforeStartupWizard = true)]
|
||||
public class GetChannelMappingOptions
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string ProviderId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/LiveTv/ChannelMappings")]
|
||||
[Authenticated(AllowBeforeStartupWizard = true)]
|
||||
public class SetChannelMapping
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string ProviderId { get; set; }
|
||||
public string TunerChannelNumber { get; set; }
|
||||
public string ProviderChannelNumber { get; set; }
|
||||
}
|
||||
|
||||
public class ChannelMappingOptions
|
||||
{
|
||||
public List<TunerChannelMapping> TunerChannels { get; set; }
|
||||
public List<NameIdPair> ProviderChannels { get; set; }
|
||||
public List<NameValuePair> Mappings { get; set; }
|
||||
public string ProviderName { get; set; }
|
||||
}
|
||||
|
||||
public class TunerChannelMapping
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string ProviderChannelNumber { get; set; }
|
||||
public string ProviderChannelName { get; set; }
|
||||
}
|
||||
|
||||
[Route("/LiveTv/Registration", "GET")]
|
||||
[Authenticated]
|
||||
public class GetLiveTvRegistrationInfo : IReturn<MBRegistrationRecord>
|
||||
|
@ -525,6 +565,11 @@ namespace MediaBrowser.Api.LiveTv
|
|||
_dtoService = dtoService;
|
||||
}
|
||||
|
||||
public object Get(GetDefaultListingProvider request)
|
||||
{
|
||||
return ToOptimizedResult(new ListingsProviderInfo());
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetSatChannnelScanResult request)
|
||||
{
|
||||
var result = await _liveTvManager.GetSatChannelScanResult(request, CancellationToken.None).ConfigureAwait(false);
|
||||
|
@ -539,6 +584,102 @@ namespace MediaBrowser.Api.LiveTv
|
|||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public async Task<object> Post(SetChannelMapping request)
|
||||
{
|
||||
var config = GetConfiguration();
|
||||
|
||||
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(request.ProviderId, i.Id, StringComparison.OrdinalIgnoreCase));
|
||||
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, request.TunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
|
||||
if (!string.Equals(request.TunerChannelNumber, request.ProviderChannelNumber, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var list = listingsProviderInfo.ChannelMappings.ToList();
|
||||
list.Add(new NameValuePair
|
||||
{
|
||||
Name = request.TunerChannelNumber,
|
||||
Value = request.ProviderChannelNumber
|
||||
});
|
||||
listingsProviderInfo.ChannelMappings = list.ToArray();
|
||||
}
|
||||
|
||||
UpdateConfiguration(config);
|
||||
|
||||
var tunerChannels = await _liveTvManager.GetChannelsForListingsProvider(request.ProviderId, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var mappings = listingsProviderInfo.ChannelMappings.ToList();
|
||||
|
||||
var tunerChannelMappings =
|
||||
tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList();
|
||||
|
||||
return tunerChannelMappings.First(i => string.Equals(i.Number, request.TunerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetChannelMappingOptions request)
|
||||
{
|
||||
var config = GetConfiguration();
|
||||
|
||||
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(request.ProviderId, i.Id, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var listingsProviderName = _liveTvManager.ListingProviders.First(i => string.Equals(i.Type, listingsProviderInfo.Type, StringComparison.OrdinalIgnoreCase)).Name;
|
||||
|
||||
var tunerChannels = await _liveTvManager.GetChannelsForListingsProvider(request.ProviderId, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var mappings = listingsProviderInfo.ChannelMappings.ToList();
|
||||
|
||||
var result = new ChannelMappingOptions
|
||||
{
|
||||
TunerChannels = tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(),
|
||||
|
||||
ProviderChannels = providerChannels.Select(i => new NameIdPair
|
||||
{
|
||||
Name = i.Name,
|
||||
Id = i.Number
|
||||
|
||||
}).ToList(),
|
||||
|
||||
Mappings = mappings,
|
||||
|
||||
ProviderName = listingsProviderName
|
||||
};
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
private TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List<NameValuePair> mappings, List<ChannelInfo> providerChannels)
|
||||
{
|
||||
var result = new TunerChannelMapping
|
||||
{
|
||||
Name = channel.Number + " " + channel.Name,
|
||||
Number = channel.Number
|
||||
};
|
||||
|
||||
var mapping = mappings.FirstOrDefault(i => string.Equals(i.Name, channel.Number, StringComparison.OrdinalIgnoreCase));
|
||||
var providerChannelNumber = channel.Number;
|
||||
|
||||
if (mapping != null)
|
||||
{
|
||||
providerChannelNumber = mapping.Value;
|
||||
}
|
||||
|
||||
var providerChannel = providerChannels.FirstOrDefault(i => string.Equals(i.Number, providerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (providerChannel != null)
|
||||
{
|
||||
result.ProviderChannelNumber = providerChannel.Number;
|
||||
result.ProviderChannelName = providerChannel.Name;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public object Get(GetSatIniMappings request)
|
||||
{
|
||||
return ToOptimizedResult(_liveTvManager.GetSatIniMappings());
|
||||
|
@ -550,9 +691,7 @@ namespace MediaBrowser.Api.LiveTv
|
|||
|
||||
var response = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = "https://json.schedulesdirect.org/20141201/available/countries",
|
||||
CacheLength = TimeSpan.FromDays(1),
|
||||
CacheMode = CacheMode.Unconditional
|
||||
Url = "https://json.schedulesdirect.org/20141201/available/countries"
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
|
@ -609,6 +748,11 @@ namespace MediaBrowser.Api.LiveTv
|
|||
return _config.GetConfiguration<LiveTvOptions>("livetv");
|
||||
}
|
||||
|
||||
private void UpdateConfiguration(LiveTvOptions options)
|
||||
{
|
||||
_config.SaveConfiguration("livetv", options);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetLineups request)
|
||||
{
|
||||
var info = await _liveTvManager.GetLineups(request.Type, request.Id, request.Country, request.Location).ConfigureAwait(false);
|
||||
|
|
|
@ -14,6 +14,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
|
||||
namespace MediaBrowser.Api.Movies
|
||||
{
|
||||
|
@ -110,18 +111,16 @@ namespace MediaBrowser.Api.Movies
|
|||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>System.Object.</returns>
|
||||
public async Task<object> Get(GetSimilarMovies request)
|
||||
public object Get(GetSimilarMovies request)
|
||||
{
|
||||
var result = await GetSimilarItemsResult(
|
||||
request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false);
|
||||
var result = GetSimilarItemsResult(request);
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(result);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetSimilarTrailers request)
|
||||
public object Get(GetSimilarTrailers request)
|
||||
{
|
||||
var result = await GetSimilarItemsResult(
|
||||
request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false);
|
||||
var result = GetSimilarItemsResult(request);
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(result);
|
||||
}
|
||||
|
@ -130,52 +129,16 @@ namespace MediaBrowser.Api.Movies
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Movie).Name }
|
||||
};
|
||||
|
||||
if (user.Configuration.IncludeTrailersInSuggestions)
|
||||
{
|
||||
var includeList = query.IncludeItemTypes.ToList();
|
||||
includeList.Add(typeof(Trailer).Name);
|
||||
query.IncludeItemTypes = includeList.ToArray();
|
||||
}
|
||||
|
||||
var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId };
|
||||
var movies = _libraryManager.GetItemList(query, parentIds)
|
||||
.OrderBy(i => (int)i.SourceType);
|
||||
|
||||
var listEligibleForCategories = new List<BaseItem>();
|
||||
var listEligibleForSuggestion = new List<BaseItem>();
|
||||
|
||||
var list = movies.ToList();
|
||||
|
||||
listEligibleForCategories.AddRange(list);
|
||||
listEligibleForSuggestion.AddRange(list);
|
||||
|
||||
listEligibleForCategories = listEligibleForCategories
|
||||
// Exclude trailers from the suggestion categories
|
||||
.Where(i => i is Movie)
|
||||
.DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
|
||||
.DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
listEligibleForSuggestion = listEligibleForSuggestion
|
||||
.DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
|
||||
.DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
dtoOptions.Fields = request.GetItemFields().ToList();
|
||||
|
||||
var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions);
|
||||
var result = GetRecommendationCategories(user, request.ParentId, request.CategoryLimit, request.ItemLimit, dtoOptions);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
private async Task<ItemsResult> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
|
||||
private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
|
||||
{
|
||||
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
|
||||
|
||||
|
@ -183,95 +146,68 @@ namespace MediaBrowser.Api.Movies
|
|||
(!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
|
||||
_libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
|
||||
|
||||
var query = new InternalItemsQuery(user)
|
||||
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Movie).Name }
|
||||
};
|
||||
|
||||
if (user == null || user.Configuration.IncludeTrailersInSuggestions)
|
||||
Limit = request.Limit,
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
var includeList = query.IncludeItemTypes.ToList();
|
||||
includeList.Add(typeof(Trailer).Name);
|
||||
query.IncludeItemTypes = includeList.ToArray();
|
||||
}
|
||||
|
||||
var list = _libraryManager.GetItemList(query)
|
||||
.OrderBy(i => (int)i.SourceType)
|
||||
.DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
|
||||
.ToList();
|
||||
|
||||
if (item is Video)
|
||||
{
|
||||
var imdbId = item.GetProviderId(MetadataProviders.Imdb);
|
||||
|
||||
// Use imdb id to try to filter duplicates of the same item
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
list = list
|
||||
.Where(i => !string.Equals(imdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList();
|
||||
|
||||
IEnumerable<BaseItem> returnItems = items;
|
||||
|
||||
if (request.Limit.HasValue)
|
||||
{
|
||||
returnItems = returnItems.Take(request.Limit.Value);
|
||||
}
|
||||
typeof(Movie).Name,
|
||||
typeof(Trailer).Name,
|
||||
typeof(LiveTvProgram).Name
|
||||
},
|
||||
IsMovie = true,
|
||||
SimilarTo = item
|
||||
}).ToList();
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var result = new ItemsResult
|
||||
var result = new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(),
|
||||
Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(),
|
||||
|
||||
TotalRecordCount = items.Count
|
||||
TotalRecordCount = itemsResult.Count
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private IEnumerable<RecommendationDto> GetRecommendationCategories(User user, List<BaseItem> allMoviesForCategories, List<BaseItem> allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions)
|
||||
private IEnumerable<RecommendationDto> GetRecommendationCategories(User user, string parentId, int categoryLimit, int itemLimit, DtoOptions dtoOptions)
|
||||
{
|
||||
var categories = new List<RecommendationDto>();
|
||||
|
||||
var recentlyPlayedMovies = allMoviesForCategories
|
||||
.Select(i =>
|
||||
var parentIds = string.IsNullOrWhiteSpace(parentId) ? new string[] { } : new[] { parentId };
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
var userdata = _userDataRepository.GetUserData(user, i);
|
||||
return new Tuple<BaseItem, bool, DateTime>(i, userdata.Played, userdata.LastPlayedDate ?? DateTime.MinValue);
|
||||
})
|
||||
.Where(i => i.Item2)
|
||||
.OrderByDescending(i => i.Item3)
|
||||
.Select(i => i.Item1)
|
||||
.ToList();
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
typeof(Movie).Name,
|
||||
//typeof(Trailer).Name,
|
||||
//typeof(LiveTvProgram).Name
|
||||
},
|
||||
// IsMovie = true
|
||||
SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random },
|
||||
SortOrder = SortOrder.Descending,
|
||||
Limit = 7
|
||||
};
|
||||
|
||||
var excludeFromLiked = recentlyPlayedMovies.Take(10);
|
||||
var likedMovies = allMovies
|
||||
.Select(i =>
|
||||
{
|
||||
var score = 0;
|
||||
var userData = _userDataRepository.GetUserData(user, i);
|
||||
var recentlyPlayedMovies = _libraryManager.GetItemList(query, parentIds).ToList();
|
||||
|
||||
if (userData.IsFavorite)
|
||||
var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
score = 2;
|
||||
}
|
||||
else
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
score = userData.Likes.HasValue ? userData.Likes.Value ? 1 : -1 : 0;
|
||||
}
|
||||
typeof(Movie).Name,
|
||||
typeof(Trailer).Name,
|
||||
typeof(LiveTvProgram).Name
|
||||
},
|
||||
IsMovie = true,
|
||||
SortBy = new[] { ItemSortBy.Random },
|
||||
SortOrder = SortOrder.Descending,
|
||||
Limit = 10,
|
||||
IsFavoriteOrLiked = true,
|
||||
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray()
|
||||
|
||||
return new Tuple<BaseItem, int>(i, score);
|
||||
})
|
||||
.OrderByDescending(i => i.Item2)
|
||||
.ThenBy(i => Guid.NewGuid())
|
||||
.Where(i => i.Item2 > 0)
|
||||
.Select(i => i.Item1)
|
||||
.Where(i => !excludeFromLiked.Contains(i));
|
||||
}, parentIds).ToList();
|
||||
|
||||
var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList();
|
||||
// Get recently played directors
|
||||
|
@ -284,11 +220,11 @@ namespace MediaBrowser.Api.Movies
|
|||
.OrderBy(i => Guid.NewGuid())
|
||||
.ToList();
|
||||
|
||||
var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
|
||||
var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator();
|
||||
var similarToRecentlyPlayed = GetSimilarTo(user, recentlyPlayedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
|
||||
var similarToLiked = GetSimilarTo(user, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator();
|
||||
|
||||
var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
|
||||
var hasActorFromRecentlyPlayed = GetWithActor(user, allMovies, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator();
|
||||
var hasDirectorFromRecentlyPlayed = GetWithDirector(user, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
|
||||
var hasActorFromRecentlyPlayed = GetWithActor(user, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator();
|
||||
|
||||
var categoryTypes = new List<IEnumerator<RecommendationDto>>
|
||||
{
|
||||
|
@ -331,42 +267,25 @@ namespace MediaBrowser.Api.Movies
|
|||
return categories.OrderBy(i => i.RecommendationType).ThenBy(i => Guid.NewGuid());
|
||||
}
|
||||
|
||||
private IEnumerable<RecommendationDto> GetWithDirector(User user, List<BaseItem> allMovies, IEnumerable<string> directors, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
|
||||
{
|
||||
var userId = user.Id;
|
||||
|
||||
foreach (var director in directors)
|
||||
{
|
||||
var items = allMovies
|
||||
.Where(i => _libraryManager.GetPeople(i).Any(p => string.Equals(p.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) && string.Equals(p.Name, director, StringComparison.OrdinalIgnoreCase)))
|
||||
.Take(itemLimit)
|
||||
.ToList();
|
||||
|
||||
if (items.Count > 0)
|
||||
{
|
||||
yield return new RecommendationDto
|
||||
{
|
||||
BaselineItemName = director,
|
||||
CategoryId = director.GetMD5().ToString("N"),
|
||||
RecommendationType = type,
|
||||
Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<RecommendationDto> GetWithActor(User user, List<BaseItem> allMovies, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
|
||||
private IEnumerable<RecommendationDto> GetWithDirector(User user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
|
||||
{
|
||||
foreach (var name in names)
|
||||
{
|
||||
var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery(user)
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
Person = name
|
||||
Person = name,
|
||||
// Account for duplicates by imdb id, since the database doesn't support this yet
|
||||
Limit = itemLimit + 2,
|
||||
PersonTypes = new[] { PersonType.Director },
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
typeof(Movie).Name,
|
||||
typeof(Trailer).Name,
|
||||
typeof(LiveTvProgram).Name
|
||||
},
|
||||
IsMovie = true
|
||||
|
||||
});
|
||||
|
||||
var items = allMovies
|
||||
.Where(i => itemsWithActor.Contains(i.Id))
|
||||
}).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
|
||||
.Take(itemLimit)
|
||||
.ToList();
|
||||
|
||||
|
@ -383,14 +302,57 @@ namespace MediaBrowser.Api.Movies
|
|||
}
|
||||
}
|
||||
|
||||
private IEnumerable<RecommendationDto> GetSimilarTo(User user, List<BaseItem> allMovies, IEnumerable<BaseItem> baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
|
||||
private IEnumerable<RecommendationDto> GetWithActor(User user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
|
||||
{
|
||||
foreach (var name in names)
|
||||
{
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
Person = name,
|
||||
// Account for duplicates by imdb id, since the database doesn't support this yet
|
||||
Limit = itemLimit + 2,
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
typeof(Movie).Name,
|
||||
typeof(Trailer).Name,
|
||||
typeof(LiveTvProgram).Name
|
||||
},
|
||||
IsMovie = true
|
||||
|
||||
}).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
|
||||
.Take(itemLimit)
|
||||
.ToList();
|
||||
|
||||
if (items.Count > 0)
|
||||
{
|
||||
yield return new RecommendationDto
|
||||
{
|
||||
BaselineItemName = name,
|
||||
CategoryId = name.GetMD5().ToString("N"),
|
||||
RecommendationType = type,
|
||||
Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<RecommendationDto> GetSimilarTo(User user, List<BaseItem> baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
|
||||
{
|
||||
foreach (var item in baselineItems)
|
||||
{
|
||||
var similar = SimilarItemsHelper
|
||||
.GetSimilaritems(item, _libraryManager, allMovies, SimilarItemsHelper.GetSimiliarityScore)
|
||||
.Take(itemLimit)
|
||||
.ToList();
|
||||
var similar = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
Limit = itemLimit,
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
typeof(Movie).Name,
|
||||
typeof(Trailer).Name,
|
||||
typeof(LiveTvProgram).Name
|
||||
},
|
||||
IsMovie = true,
|
||||
SimilarTo = item
|
||||
|
||||
}).ToList();
|
||||
|
||||
if (similar.Count > 0)
|
||||
{
|
||||
|
|
|
@ -846,7 +846,7 @@ namespace MediaBrowser.Api.Playback
|
|||
if (MediaEncoder.SupportsDecoder("h264_qsv"))
|
||||
{
|
||||
// Seeing stalls and failures with decoding. Not worth it compared to encoding.
|
||||
//return "-c:v h264_qsv ";
|
||||
return "-c:v h264_qsv ";
|
||||
}
|
||||
break;
|
||||
case "mpeg2video":
|
||||
|
@ -980,11 +980,6 @@ namespace MediaBrowser.Api.Playback
|
|||
var transcodingId = Guid.NewGuid().ToString("N");
|
||||
var commandLineArgs = GetCommandLineArguments(outputPath, state, true);
|
||||
|
||||
if (ApiEntryPoint.Instance.GetEncodingOptions().EnableDebugLogging)
|
||||
{
|
||||
commandLineArgs = "-loglevel debug " + commandLineArgs;
|
||||
}
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
|
@ -1212,7 +1207,7 @@ namespace MediaBrowser.Api.Playback
|
|||
}
|
||||
}
|
||||
|
||||
private int? GetVideoBitrateParamValue(VideoStreamRequest request, MediaStream videoStream)
|
||||
private int? GetVideoBitrateParamValue(VideoStreamRequest request, MediaStream videoStream, string outputVideoCodec)
|
||||
{
|
||||
var bitrate = request.VideoBitRate;
|
||||
|
||||
|
@ -1237,6 +1232,18 @@ namespace MediaBrowser.Api.Playback
|
|||
}
|
||||
}
|
||||
|
||||
if (bitrate.HasValue)
|
||||
{
|
||||
var inputVideoCodec = videoStream == null ? null : videoStream.Codec;
|
||||
bitrate = ResolutionNormalizer.ScaleBitrate(bitrate.Value, inputVideoCodec, outputVideoCodec);
|
||||
|
||||
// If a max bitrate was requested, don't let the scaled bitrate exceed it
|
||||
if (request.VideoBitRate.HasValue)
|
||||
{
|
||||
bitrate = Math.Min(bitrate.Value, request.VideoBitRate.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
|
@ -1518,6 +1525,13 @@ namespace MediaBrowser.Api.Playback
|
|||
}
|
||||
}
|
||||
else if (i == 25)
|
||||
{
|
||||
if (videoRequest != null)
|
||||
{
|
||||
videoRequest.ForceLiveStream = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
else if (i == 26)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val) && videoRequest != null)
|
||||
{
|
||||
|
@ -1528,7 +1542,7 @@ namespace MediaBrowser.Api.Playback
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (i == 26)
|
||||
else if (i == 27)
|
||||
{
|
||||
request.TranscodingMaxAudioChannels = int.Parse(val, UsCulture);
|
||||
}
|
||||
|
@ -1690,7 +1704,7 @@ namespace MediaBrowser.Api.Playback
|
|||
if (videoRequest != null)
|
||||
{
|
||||
state.OutputVideoCodec = state.VideoRequest.VideoCodec;
|
||||
state.OutputVideoBitrate = GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream);
|
||||
state.OutputVideoBitrate = GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream, state.OutputVideoCodec);
|
||||
|
||||
if (state.OutputVideoBitrate.HasValue)
|
||||
{
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace MediaBrowser.Api.Playback
|
|||
public long? InputFileSize { get; set; }
|
||||
|
||||
public string OutputAudioSync = "1";
|
||||
public string OutputVideoSync = "vfr";
|
||||
public string OutputVideoSync = "-1";
|
||||
|
||||
public List<string> SupportedAudioCodecs { get; set; }
|
||||
|
||||
|
|
|
@ -213,7 +213,6 @@ namespace MediaBrowser.Api.Reports
|
|||
NameStartsWith = request.NameStartsWith,
|
||||
NameStartsWithOrGreater = request.NameStartsWithOrGreater,
|
||||
HasImdbId = request.HasImdbId,
|
||||
IsYearMismatched = request.IsYearMismatched,
|
||||
IsPlaceHolder = request.IsPlaceHolder,
|
||||
IsLocked = request.IsLocked,
|
||||
IsInBoxSet = request.IsInBoxSet,
|
||||
|
|
|
@ -116,24 +116,12 @@ namespace MediaBrowser.Api
|
|||
|
||||
private static IEnumerable<string> GetTags(BaseItem item)
|
||||
{
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags != null)
|
||||
{
|
||||
return hasTags.Tags;
|
||||
}
|
||||
|
||||
return new List<string>();
|
||||
return item.Tags;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetKeywords(BaseItem item)
|
||||
{
|
||||
var hasTags = item as IHasKeywords;
|
||||
if (hasTags != null)
|
||||
{
|
||||
return hasTags.Keywords;
|
||||
}
|
||||
|
||||
return new List<string>();
|
||||
return item.Keywords;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -111,10 +111,10 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
config.EnableLocalizedGuids = true;
|
||||
config.EnableCustomPathSubFolders = true;
|
||||
config.EnableDateLastRefresh = true;
|
||||
config.EnableStandaloneMusicKeys = true;
|
||||
config.EnableCaseSensitiveItemIds = true;
|
||||
config.SchemaVersion = 79;
|
||||
config.EnableFolderView = true;
|
||||
config.SchemaVersion = 92;
|
||||
}
|
||||
|
||||
public void Post(UpdateStartupConfiguration request)
|
||||
|
|
|
@ -98,6 +98,10 @@ namespace MediaBrowser.Api.Subtitles
|
|||
|
||||
[ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public long? EndPositionTicks { get; set; }
|
||||
|
||||
[ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool CopyTimestamps { get; set; }
|
||||
public bool AddVttTimeMap { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")]
|
||||
|
@ -175,7 +179,7 @@ namespace MediaBrowser.Api.Subtitles
|
|||
|
||||
var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);
|
||||
|
||||
var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
|
||||
var url = string.Format("stream.vtt?CopyTimestamps=true&AddVttTimeMap=true&StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
|
||||
positionTicks.ToString(CultureInfo.InvariantCulture),
|
||||
endPositionTicks.ToString(CultureInfo.InvariantCulture),
|
||||
accessToken);
|
||||
|
@ -190,7 +194,7 @@ namespace MediaBrowser.Api.Subtitles
|
|||
return ResultFactory.GetResult(builder.ToString(), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
public object Get(GetSubtitle request)
|
||||
public async Task<object> Get(GetSubtitle request)
|
||||
{
|
||||
if (string.Equals(request.Format, "js", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
@ -209,20 +213,32 @@ namespace MediaBrowser.Api.Subtitles
|
|||
return ToStaticFileResult(subtitleStream.Path);
|
||||
}
|
||||
|
||||
var stream = GetSubtitles(request).Result;
|
||||
using (var stream = await GetSubtitles(request).ConfigureAwait(false))
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var text = reader.ReadToEnd();
|
||||
|
||||
return ResultFactory.GetResult(stream, MimeTypes.GetMimeType("file." + request.Format));
|
||||
if (string.Equals(request.Format, "vtt", StringComparison.OrdinalIgnoreCase) && request.AddVttTimeMap)
|
||||
{
|
||||
text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000");
|
||||
}
|
||||
|
||||
private async Task<Stream> GetSubtitles(GetSubtitle request)
|
||||
return ResultFactory.GetResult(text, MimeTypes.GetMimeType("file." + request.Format));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Task<Stream> GetSubtitles(GetSubtitle request)
|
||||
{
|
||||
return await _subtitleEncoder.GetSubtitles(request.Id,
|
||||
return _subtitleEncoder.GetSubtitles(request.Id,
|
||||
request.MediaSourceId,
|
||||
request.Index,
|
||||
request.Format,
|
||||
request.StartPositionTicks,
|
||||
request.EndPositionTicks,
|
||||
CancellationToken.None).ConfigureAwait(false);
|
||||
request.CopyTimestamps,
|
||||
CancellationToken.None);
|
||||
}
|
||||
|
||||
public object Get(SearchRemoteSubtitles request)
|
||||
|
|
|
@ -12,6 +12,7 @@ using ServiceStack;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Api
|
||||
{
|
||||
|
@ -273,20 +274,42 @@ namespace MediaBrowser.Api
|
|||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetSimilarShows request)
|
||||
{
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
|
||||
_itemRepo,
|
||||
_libraryManager,
|
||||
_userDataManager,
|
||||
_dtoService,
|
||||
Logger,
|
||||
request, new[] { typeof(Series) },
|
||||
SimilarItemsHelper.GetSimiliarityScore);
|
||||
var result = GetSimilarItemsResult(request);
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(result);
|
||||
}
|
||||
|
||||
private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem 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);
|
||||
|
||||
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
Limit = request.Limit,
|
||||
IncludeItemTypes = new[]
|
||||
{
|
||||
typeof(Series).Name
|
||||
},
|
||||
SimilarTo = item
|
||||
|
||||
}).ToList();
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var result = new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(),
|
||||
|
||||
TotalRecordCount = itemsResult.Count
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public object Get(GetUpcomingEpisodes request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
|
|
@ -333,12 +333,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
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)))
|
||||
if (!tags.Any(v => i.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -100,9 +100,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
[ApiMember(Name = "HasTvdbId", Description = "Optional filter by items that have a tvdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? HasTvdbId { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsYearMismatched", Description = "Optional filter by items that are potentially misidentified.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsYearMismatched { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsInBoxSet { get; set; }
|
||||
|
||||
|
|
|
@ -187,7 +187,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
NameStartsWith = request.NameStartsWith,
|
||||
NameStartsWithOrGreater = request.NameStartsWithOrGreater,
|
||||
HasImdbId = request.HasImdbId,
|
||||
IsYearMismatched = request.IsYearMismatched,
|
||||
IsPlaceHolder = request.IsPlaceHolder,
|
||||
IsLocked = request.IsLocked,
|
||||
IsInBoxSet = request.IsInBoxSet,
|
||||
|
|
|
@ -385,7 +385,7 @@ namespace MediaBrowser.Api
|
|||
throw new ResourceNotFoundException("User not found");
|
||||
}
|
||||
|
||||
await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
|
||||
await _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), null).ConfigureAwait(false);
|
||||
|
||||
await _userManager.DeleteUser(user).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -465,6 +465,10 @@ namespace MediaBrowser.Api
|
|||
}
|
||||
|
||||
await _userManager.ChangePassword(user, request.NewPassword).ConfigureAwait(false);
|
||||
|
||||
var currentToken = AuthorizationContext.GetAuthorizationInfo(Request).Token;
|
||||
|
||||
await _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), currentToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -602,7 +606,8 @@ namespace MediaBrowser.Api
|
|||
throw new ArgumentException("There must be at least one enabled user in the system.");
|
||||
}
|
||||
|
||||
await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false);
|
||||
var currentToken = AuthorizationContext.GetAuthorizationInfo(Request).Token;
|
||||
await _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), currentToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await _userManager.UpdateUserPolicy(request.Id, request).ConfigureAwait(false);
|
||||
|
|
|
@ -552,7 +552,7 @@ namespace MediaBrowser.Common.Implementations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Error creating {0}", ex, type.Name);
|
||||
Logger.ErrorException("Error creating {0}", ex, type.Name);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ namespace MediaBrowser.Common.Implementations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Error creating {0}", ex, type.Name);
|
||||
Logger.ErrorException("Error creating {0}", ex, type.Name);
|
||||
// Don't blow up in release mode
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
};
|
||||
}
|
||||
|
||||
private WebRequest GetRequest(HttpRequestOptions options, string method, bool enableHttpCompression)
|
||||
private WebRequest GetRequest(HttpRequestOptions options, string method)
|
||||
{
|
||||
var request = CreateWebRequest(options.Url);
|
||||
var httpWebRequest = request as HttpWebRequest;
|
||||
|
@ -154,7 +154,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
|
||||
AddRequestHeaders(httpWebRequest, options);
|
||||
|
||||
httpWebRequest.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None;
|
||||
httpWebRequest.AutomaticDecompression = options.EnableHttpCompression ?
|
||||
(options.DecompressionMethod ?? DecompressionMethods.Deflate) :
|
||||
DecompressionMethods.None;
|
||||
}
|
||||
|
||||
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
|
||||
|
@ -366,7 +368,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
};
|
||||
}
|
||||
|
||||
var httpWebRequest = GetRequest(options, httpMethod, options.EnableHttpCompression);
|
||||
var httpWebRequest = GetRequest(options, httpMethod);
|
||||
|
||||
if (options.RequestContentBytes != null ||
|
||||
!string.IsNullOrEmpty(options.RequestContent) ||
|
||||
|
@ -556,7 +558,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var httpWebRequest = GetRequest(options, "GET", options.EnableHttpCompression);
|
||||
var httpWebRequest = GetRequest(options, "GET");
|
||||
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimpleInjector, Version=3.1.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SimpleInjector.3.1.4\lib\net45\SimpleInjector.dll</HintPath>
|
||||
<Reference Include="SimpleInjector, Version=3.1.5.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SimpleInjector.3.1.5\lib\net45\SimpleInjector.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||
<package id="NLog" version="4.3.4" targetFramework="net45" />
|
||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
<package id="SimpleInjector" version="3.1.4" targetFramework="net45" />
|
||||
<package id="SimpleInjector" version="3.1.5" targetFramework="net45" />
|
||||
</packages>
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Common.Net
|
||||
|
@ -16,6 +17,8 @@ namespace MediaBrowser.Common.Net
|
|||
/// <value>The URL.</value>
|
||||
public string Url { get; set; }
|
||||
|
||||
public DecompressionMethods? DecompressionMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the accept header.
|
||||
/// </summary>
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace MediaBrowser.Controller.Channels
|
|||
|
||||
public bool IsInfiniteStream { get; set; }
|
||||
|
||||
public string HomePageUrl { get; set; }
|
||||
|
||||
public ChannelItemInfo()
|
||||
{
|
||||
MediaSources = new List<ChannelMediaInfo>();
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Chapters
|
|||
/// <param name="chapters">The chapters.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveChapters(string itemId, IEnumerable<ChapterInfo> chapters, CancellationToken cancellationToken);
|
||||
Task SaveChapters(string itemId, List<ChapterInfo> chapters, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Searches the specified video.
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
IHasArtist,
|
||||
IHasMusicGenres,
|
||||
IHasLookupInfo<SongInfo>,
|
||||
IHasTags,
|
||||
IHasMediaSources,
|
||||
IThemeMedia,
|
||||
IArchivable
|
||||
|
|
|
@ -179,17 +179,13 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
{
|
||||
var items = GetRecursiveChildren().ToList();
|
||||
|
||||
var songs = items.OfType<Audio>().ToList();
|
||||
|
||||
var others = items.Except(songs).ToList();
|
||||
|
||||
var totalItems = songs.Count + others.Count;
|
||||
var totalItems = items.Count;
|
||||
var numComplete = 0;
|
||||
|
||||
var childUpdateType = ItemUpdateType.None;
|
||||
|
||||
// Refresh songs
|
||||
foreach (var item in songs)
|
||||
foreach (var item in items)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
@ -199,7 +195,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= totalItems;
|
||||
progress.Report(percent * 100);
|
||||
progress.Report(percent * 95);
|
||||
}
|
||||
|
||||
var parentRefreshOptions = refreshOptions;
|
||||
|
@ -212,19 +208,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
// Refresh current item
|
||||
await RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Refresh all non-songs
|
||||
foreach (var item in others)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var updateType = await item.RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= totalItems;
|
||||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,13 +62,6 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
query.ArtistNames = new[] { Name };
|
||||
}
|
||||
|
||||
// Need this for now since the artist filter isn't yet supported by the db
|
||||
if (ConfigurationManager.Configuration.SchemaVersion < 79)
|
||||
{
|
||||
var filter = GetItemFilter();
|
||||
return LibraryManager.GetItemList(query).Where(filter);
|
||||
}
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ using System.Threading.Tasks;
|
|||
using CommonIO;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
@ -36,6 +37,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
protected BaseItem()
|
||||
{
|
||||
Keywords = new List<string>();
|
||||
Tags = new List<string>();
|
||||
Genres = new List<string>();
|
||||
Studios = new List<string>();
|
||||
|
@ -69,10 +71,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public List<ItemImageInfo> ImageInfos { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsVirtualItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the album.
|
||||
/// </summary>
|
||||
/// <value>The album.</value>
|
||||
[IgnoreDataMember]
|
||||
public string Album { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -810,6 +816,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
[IgnoreDataMember]
|
||||
public List<string> Tags { get; set; }
|
||||
|
||||
public List<string> Keywords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the home page URL.
|
||||
/// </summary>
|
||||
|
@ -1031,9 +1039,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
: options;
|
||||
|
||||
var result = await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return result;
|
||||
return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
@ -1393,17 +1399,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
private bool IsVisibleViaTags(User user)
|
||||
{
|
||||
var hasTags = this as IHasTags;
|
||||
|
||||
if (hasTags != null)
|
||||
{
|
||||
var policy = user.Policy;
|
||||
if (policy.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase)))
|
||||
if (policy.BlockedTags.Any(i => Tags.Contains(i, StringComparer.OrdinalIgnoreCase)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2214,5 +2215,10 @@ namespace MediaBrowser.Controller.Entities
|
|||
DeleteFileLocation = false
|
||||
});
|
||||
}
|
||||
|
||||
public virtual List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
return new List<ExternalUrl>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ using MediaBrowser.Model.Entities;
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class Book : BaseItem, IHasTags, IHasLookupInfo<BookInfo>, IHasSeries
|
||||
public class Book : BaseItem, IHasLookupInfo<BookInfo>, IHasSeries
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override string MediaType
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <summary>
|
||||
/// Class Folder
|
||||
/// </summary>
|
||||
public class Folder : BaseItem, IHasThemeMedia, IHasTags
|
||||
public class Folder : BaseItem, IHasThemeMedia
|
||||
{
|
||||
public static IUserManager UserManager { get; set; }
|
||||
public static IUserViewManager UserViewManager { get; set; }
|
||||
|
@ -164,49 +164,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
item.DateModified = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
AddChildInternal(item.Id);
|
||||
|
||||
await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected void AddChildrenInternal(List<Guid> children)
|
||||
{
|
||||
lock (_childrenSyncLock)
|
||||
{
|
||||
var newChildren = ChildIds.ToList();
|
||||
newChildren.AddRange(children);
|
||||
_children = newChildren.ToList();
|
||||
}
|
||||
}
|
||||
protected void AddChildInternal(Guid child)
|
||||
{
|
||||
lock (_childrenSyncLock)
|
||||
{
|
||||
var childIds = ChildIds.ToList();
|
||||
if (!childIds.Contains(child))
|
||||
{
|
||||
childIds.Add(child);
|
||||
_children = childIds.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveChildrenInternal(List<Guid> children)
|
||||
{
|
||||
lock (_childrenSyncLock)
|
||||
{
|
||||
_children = ChildIds.Except(children).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the child.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
public void RemoveChild(BaseItem item)
|
||||
{
|
||||
RemoveChildrenInternal(new[] { item.Id }.ToList());
|
||||
|
||||
item.SetParent(null);
|
||||
}
|
||||
|
||||
|
@ -241,33 +207,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The children
|
||||
/// </summary>
|
||||
private IReadOnlyList<Guid> _children;
|
||||
/// <summary>
|
||||
/// The _children sync lock
|
||||
/// </summary>
|
||||
private readonly object _childrenSyncLock = new object();
|
||||
/// <summary>
|
||||
/// Gets or sets the actual children.
|
||||
/// </summary>
|
||||
/// <value>The actual children.</value>
|
||||
protected virtual IEnumerable<Guid> ChildIds
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_childrenSyncLock)
|
||||
{
|
||||
if (_children == null)
|
||||
{
|
||||
_children = LoadChildren().ToList();
|
||||
}
|
||||
return _children.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actual children.
|
||||
/// </summary>
|
||||
|
@ -277,7 +216,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
get
|
||||
{
|
||||
return ChildIds.Select(LibraryManager.GetItemById).Where(i => i != null);
|
||||
return LoadChildren().Select(LibraryManager.GetItemById).Where(i => i != null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,17 +400,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
foreach (var item in itemsRemoved)
|
||||
{
|
||||
if (item.LocationType == LocationType.Virtual ||
|
||||
item.LocationType == LocationType.Remote)
|
||||
var itemLocationType = item.LocationType;
|
||||
if (itemLocationType == LocationType.Virtual ||
|
||||
itemLocationType == LocationType.Remote)
|
||||
{
|
||||
// Don't remove these because there's no way to accurately validate them.
|
||||
validChildren.Add(item);
|
||||
}
|
||||
|
||||
else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path))
|
||||
{
|
||||
await UpdateIsOffline(item, true).ConfigureAwait(false);
|
||||
validChildren.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -481,8 +418,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (actualRemovals.Count > 0)
|
||||
{
|
||||
RemoveChildrenInternal(actualRemovals.Select(i => i.Id).ToList());
|
||||
|
||||
foreach (var item in actualRemovals)
|
||||
{
|
||||
Logger.Debug("Removed item: " + item.Path);
|
||||
|
@ -495,8 +430,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
await LibraryManager.CreateItems(newItems, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
AddChildrenInternal(newItems.Select(i => i.Id).ToList());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -733,6 +666,27 @@ namespace MediaBrowser.Controller.Entities
|
|||
});
|
||||
}
|
||||
|
||||
public virtual int GetChildCount(User user)
|
||||
{
|
||||
if (LinkedChildren.Count > 0)
|
||||
{
|
||||
if (!(this is ICollectionFolder))
|
||||
{
|
||||
return GetChildren(user, true).Count();
|
||||
}
|
||||
}
|
||||
|
||||
var result = GetItems(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = false,
|
||||
Limit = 0,
|
||||
ParentId = Id
|
||||
|
||||
}).Result;
|
||||
|
||||
return result.TotalRecordCount;
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> QueryRecursive(InternalItemsQuery query)
|
||||
{
|
||||
var user = query.User;
|
||||
|
@ -768,58 +722,13 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
if (!(this is ICollectionFolder))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to LinkedChildren");
|
||||
Logger.Debug("Query requires post-filtering due to LinkedChildren. Type: " + GetType().Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var supportsUserDataQueries = ConfigurationManager.Configuration.SchemaVersion >= 76;
|
||||
|
||||
if (query.SortBy != null && query.SortBy.Length > 0)
|
||||
{
|
||||
if (!supportsUserDataQueries)
|
||||
{
|
||||
if (query.SortBy.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.PlayCount");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.IsPlayed");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.IsUnplayed");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ConfigurationManager.Configuration.SchemaVersion < 79)
|
||||
{
|
||||
if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.Artist, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Artist");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (query.SortBy.Contains(ItemSortBy.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder");
|
||||
|
@ -840,11 +749,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Metascore");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.OfficialRating, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.OfficialRating");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.Players, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Players");
|
||||
|
@ -860,11 +764,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
Logger.Debug("Query requires post-filtering due to ItemSortBy.SeriesSortName");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.Studio, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Studio");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.VideoBitRate, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.VideoBitRate");
|
||||
|
@ -884,39 +783,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!supportsUserDataQueries)
|
||||
{
|
||||
if (query.IsLiked.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsLiked");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.IsFavoriteOrLiked.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsFavoriteOrLiked");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.IsFavorite.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsFavorite");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.IsResumable.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsResumable");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.IsPlayed.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsPlayed");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (query.IsInBoxSet.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsInBoxSet");
|
||||
|
@ -930,30 +796,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (query.HasImdbId.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to HasImdbId");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.HasTmdbId.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to HasTmdbId");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.HasTvdbId.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to HasTvdbId");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.IsYearMismatched.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsYearMismatched");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.HasOfficialRating.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to HasOfficialRating");
|
||||
|
@ -1003,12 +845,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (query.ImageTypes.Length > 0)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ImageTypes");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Apply studio filter
|
||||
if (query.StudioIds.Length > 0)
|
||||
{
|
||||
|
@ -1042,12 +878,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (query.OfficialRatings.Length > 0)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to OfficialRatings");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.IsMissing.HasValue)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to IsMissing");
|
||||
|
@ -1066,7 +896,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (UserViewBuilder.CollapseBoxSetItems(query, this, query.User))
|
||||
if (UserViewBuilder.CollapseBoxSetItems(query, this, query.User, ConfigurationManager))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to CollapseBoxSetItems");
|
||||
return true;
|
||||
|
@ -1102,15 +932,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (ConfigurationManager.Configuration.SchemaVersion < 79)
|
||||
{
|
||||
if (query.ArtistNames.Length > 0)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ArtistNames");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1004,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
protected QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, InternalItemsQuery query)
|
||||
{
|
||||
return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager);
|
||||
return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
|
@ -1613,60 +1434,36 @@ namespace MediaBrowser.Controller.Entities
|
|||
return;
|
||||
}
|
||||
|
||||
var recursiveItemCount = 0;
|
||||
var unplayed = 0;
|
||||
|
||||
double totalPercentPlayed = 0;
|
||||
|
||||
var itemsResult = GetItems(new InternalItemsQuery(user)
|
||||
var unplayedQueryResult = GetItems(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = true,
|
||||
IsFolder = false,
|
||||
ExcludeLocationTypes = new[] { LocationType.Virtual },
|
||||
EnableTotalRecordCount = false
|
||||
IsVirtualItem = false,
|
||||
EnableTotalRecordCount = true,
|
||||
Limit = 0,
|
||||
IsPlayed = false
|
||||
|
||||
}).Result;
|
||||
|
||||
var children = itemsResult.Items;
|
||||
|
||||
// Loop through each recursive child
|
||||
foreach (var child in children)
|
||||
var allItemsQueryResult = GetItems(new InternalItemsQuery(user)
|
||||
{
|
||||
recursiveItemCount++;
|
||||
Recursive = true,
|
||||
IsFolder = false,
|
||||
IsVirtualItem = false,
|
||||
EnableTotalRecordCount = true,
|
||||
Limit = 0
|
||||
|
||||
var isUnplayed = true;
|
||||
}).Result;
|
||||
|
||||
var itemUserData = UserDataManager.GetUserData(user, child);
|
||||
|
||||
// Incrememt totalPercentPlayed
|
||||
if (itemUserData != null)
|
||||
{
|
||||
if (itemUserData.Played)
|
||||
{
|
||||
totalPercentPlayed += 100;
|
||||
|
||||
isUnplayed = false;
|
||||
}
|
||||
else if (itemUserData.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
|
||||
{
|
||||
double itemPercent = itemUserData.PlaybackPositionTicks;
|
||||
itemPercent /= child.RunTimeTicks.Value;
|
||||
totalPercentPlayed += itemPercent;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUnplayed)
|
||||
{
|
||||
unplayed++;
|
||||
}
|
||||
}
|
||||
|
||||
dto.UnplayedItemCount = unplayed;
|
||||
double recursiveItemCount = allItemsQueryResult.TotalRecordCount;
|
||||
double unplayedCount = unplayedQueryResult.TotalRecordCount;
|
||||
|
||||
if (recursiveItemCount > 0)
|
||||
{
|
||||
dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
|
||||
var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
|
||||
dto.PlayedPercentage = 100 - unplayedPercentage;
|
||||
dto.Played = dto.PlayedPercentage.Value >= 100;
|
||||
dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Linq;
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
|
||||
public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
|
||||
{
|
||||
public List<Guid> ThemeSongIds { get; set; }
|
||||
public List<Guid> ThemeVideoIds { get; set; }
|
||||
|
|
|
@ -19,6 +19,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public User User { get; set; }
|
||||
|
||||
public BaseItem SimilarTo { get; set; }
|
||||
|
||||
public bool? IsFolder { get; set; }
|
||||
public bool? IsFavorite { get; set; }
|
||||
public bool? IsFavoriteOrLiked { get; set; }
|
||||
|
@ -33,6 +35,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string[] ExcludeTags { get; set; }
|
||||
public string[] ExcludeInheritedTags { get; set; }
|
||||
public string[] Genres { get; set; }
|
||||
public string[] Keywords { get; set; }
|
||||
|
||||
public bool? IsMissing { get; set; }
|
||||
public bool? IsUnaired { get; set; }
|
||||
|
@ -52,6 +55,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string Person { get; set; }
|
||||
public string[] PersonIds { get; set; }
|
||||
public string[] ItemIds { get; set; }
|
||||
public string[] ExcludeItemIds { get; set; }
|
||||
public string AdjacentTo { get; set; }
|
||||
public string[] PersonTypes { get; set; }
|
||||
|
||||
|
@ -60,7 +64,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
public bool? IsInBoxSet { get; set; }
|
||||
public bool? IsLocked { get; set; }
|
||||
public bool? IsPlaceHolder { get; set; }
|
||||
public bool? IsYearMismatched { get; set; }
|
||||
|
||||
public bool? HasImdbId { get; set; }
|
||||
public bool? HasOverview { get; set; }
|
||||
|
@ -107,6 +110,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
internal List<Guid> ItemIdsFromPersonFilters { get; set; }
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
public int? ParentIndexNumberNotEquals { get; set; }
|
||||
public int? IndexNumber { get; set; }
|
||||
public int? MinParentalRating { get; set; }
|
||||
public int? MaxParentalRating { get; set; }
|
||||
|
@ -114,6 +118,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public bool? IsCurrentSchema { get; set; }
|
||||
public bool? HasDeadParentId { get; set; }
|
||||
public bool? IsOffline { get; set; }
|
||||
public bool? IsVirtualItem { get; set; }
|
||||
|
||||
public Guid? ParentId { get; set; }
|
||||
public string[] AncestorIds { get; set; }
|
||||
|
@ -137,6 +142,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
public bool GroupByPresentationUniqueKey { get; set; }
|
||||
public bool EnableTotalRecordCount { get; set; }
|
||||
public bool ForceDirect { get; set; }
|
||||
public Dictionary<string, string> ExcludeProviderIds { get; set; }
|
||||
public string GroupByAncestorOfType { get; set; }
|
||||
|
||||
public InternalItemsQuery()
|
||||
{
|
||||
|
@ -145,12 +152,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
AlbumNames = new string[] { };
|
||||
ArtistNames = new string[] { };
|
||||
ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
BlockUnratedItems = new UnratedItem[] { };
|
||||
Tags = new string[] { };
|
||||
OfficialRatings = new string[] { };
|
||||
SortBy = new string[] { };
|
||||
MediaTypes = new string[] { };
|
||||
Keywords = new string[] { };
|
||||
IncludeItemTypes = new string[] { };
|
||||
ExcludeItemTypes = new string[] { };
|
||||
Genres = new string[] { };
|
||||
|
@ -164,6 +173,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
PersonIds = new string[] { };
|
||||
ChannelIds = new string[] { };
|
||||
ItemIds = new string[] { };
|
||||
ExcludeItemIds = new string[] { };
|
||||
AncestorIds = new string[] { };
|
||||
TopParentIds = new string[] { };
|
||||
ExcludeTags = new string[] { };
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasKeywords
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the keywords.
|
||||
/// </summary>
|
||||
/// <value>The keywords.</value>
|
||||
List<string> Keywords { get; set; }
|
||||
}
|
||||
|
||||
public static class KeywordExtensions
|
||||
{
|
||||
public static void AddKeyword(this IHasKeywords item, string name)
|
||||
public static void AddKeyword(this BaseItem item, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
|
@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
/// <summary>
|
||||
/// Class BoxSet
|
||||
/// </summary>
|
||||
public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IHasShares
|
||||
public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IHasShares
|
||||
{
|
||||
public List<Share> Shares { get; set; }
|
||||
|
||||
|
@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
RemoteTrailerIds = new List<Guid>();
|
||||
|
||||
DisplayOrder = ItemSortBy.PremiereDate;
|
||||
Keywords = new List<string>();
|
||||
Shares = new List<Share>();
|
||||
}
|
||||
|
||||
|
@ -47,12 +46,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
/// <value>The remote trailers.</value>
|
||||
public List<MediaUrl> RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tags.
|
||||
/// </summary>
|
||||
/// <value>The tags.</value>
|
||||
public List<string> Keywords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display order.
|
||||
/// </summary>
|
||||
|
|
|
@ -8,13 +8,14 @@ using System.Runtime.Serialization;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Movies
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Movie
|
||||
/// </summary>
|
||||
public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle
|
||||
public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle
|
||||
{
|
||||
public List<Guid> SpecialFeatureIds { get; set; }
|
||||
|
||||
|
@ -31,7 +32,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
ThemeSongIds = new List<Guid>();
|
||||
ThemeVideoIds = new List<Guid>();
|
||||
Taglines = new List<string>();
|
||||
Keywords = new List<string>();
|
||||
ProductionLocations = new List<string>();
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
|
||||
public List<Guid> LocalTrailerIds { get; set; }
|
||||
public List<Guid> RemoteTrailerIds { get; set; }
|
||||
public List<string> Keywords { get; set; }
|
||||
|
||||
public List<MediaUrl> RemoteTrailers { get; set; }
|
||||
|
||||
|
@ -163,5 +162,22 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
public override List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Runtime.Serialization;
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class Photo : BaseItem, IHasTags, IHasTaglines
|
||||
public class Photo : BaseItem, IHasTaglines
|
||||
{
|
||||
public List<string> Taglines { get; set; }
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <summary>
|
||||
/// Class Studio
|
||||
/// </summary>
|
||||
public class Studio : BaseItem, IItemByName, IHasTags
|
||||
public class Studio : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
|
|
|
@ -11,8 +11,20 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
/// <summary>
|
||||
/// Class Episode
|
||||
/// </summary>
|
||||
public class Episode : Video, IHasLookupInfo<EpisodeInfo>, IHasSeries
|
||||
public class Episode : Video, IHasTrailers, IHasLookupInfo<EpisodeInfo>, IHasSeries
|
||||
{
|
||||
|
||||
public Episode()
|
||||
{
|
||||
RemoteTrailers = new List<MediaUrl>();
|
||||
LocalTrailerIds = new List<Guid>();
|
||||
RemoteTrailerIds = new List<Guid>();
|
||||
}
|
||||
|
||||
public List<Guid> LocalTrailerIds { get; set; }
|
||||
public List<Guid> RemoteTrailerIds { get; set; }
|
||||
public List<MediaUrl> RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the season in which it aired.
|
||||
/// </summary>
|
||||
|
@ -96,7 +108,13 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
var series = Series;
|
||||
if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
|
||||
{
|
||||
list.InsertRange(0, series.GetUserDataKeys().Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
|
||||
var seriesUserDataKeys = series.GetUserDataKeys();
|
||||
var take = seriesUserDataKeys.Count;
|
||||
if (seriesUserDataKeys.Count > 1)
|
||||
{
|
||||
take--;
|
||||
}
|
||||
list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
|
@ -75,6 +75,11 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return list;
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
return GetChildren(user, true).Count();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Episode's Series Instance
|
||||
/// </summary>
|
||||
|
@ -128,39 +133,16 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var result = base.RequiresRefresh();
|
||||
|
||||
if (!result)
|
||||
{
|
||||
if (!IsVirtualItem.HasValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool? IsVirtualItem { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsMissingSeason
|
||||
{
|
||||
get { return (IsVirtualItem ?? DetectIsVirtualItem()) && !IsUnaired; }
|
||||
get { return (IsVirtualItem) && !IsUnaired; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsVirtualUnaired
|
||||
{
|
||||
get { return (IsVirtualItem ?? DetectIsVirtualItem()) && IsUnaired; }
|
||||
}
|
||||
|
||||
private bool DetectIsVirtualItem()
|
||||
{
|
||||
return LocationType == LocationType.Virtual && GetEpisodes().All(i => i.LocationType == LocationType.Virtual);
|
||||
get { return (IsVirtualItem) && IsUnaired; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
@ -196,52 +178,17 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
return GetEpisodes(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
return GetEpisodes(Series, user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
public IEnumerable<Episode> GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
{
|
||||
var series = Series;
|
||||
|
||||
if (IndexNumber.HasValue && series != null)
|
||||
{
|
||||
return series.GetEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
||||
return GetEpisodes(series, user, includeMissingEpisodes, includeVirtualUnairedEpisodes, null);
|
||||
}
|
||||
|
||||
var episodes = GetRecursiveChildren(user)
|
||||
.OfType<Episode>();
|
||||
|
||||
if (series != null && series.ContainsEpisodesWithoutSeasonFolders)
|
||||
public IEnumerable<Episode> GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> allSeriesEpisodes)
|
||||
{
|
||||
var seasonNumber = IndexNumber;
|
||||
var list = episodes.ToList();
|
||||
|
||||
if (seasonNumber.HasValue)
|
||||
{
|
||||
list.AddRange(series.GetRecursiveChildren(user).OfType<Episode>()
|
||||
.Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.AddRange(series.GetRecursiveChildren(user).OfType<Episode>()
|
||||
.Where(i => !i.ParentIndexNumber.HasValue));
|
||||
}
|
||||
|
||||
episodes = list.DistinctBy(i => i.Id);
|
||||
}
|
||||
|
||||
if (!includeMissingEpisodes)
|
||||
{
|
||||
episodes = episodes.Where(i => !i.IsMissingEpisode);
|
||||
}
|
||||
if (!includeVirtualUnairedEpisodes)
|
||||
{
|
||||
episodes = episodes.Where(i => !i.IsVirtualUnaired);
|
||||
}
|
||||
|
||||
return LibraryManager
|
||||
.Sort(episodes, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending)
|
||||
.Cast<Episode>();
|
||||
return series.GetEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes, allSeriesEpisodes);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes()
|
||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
|||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MoreLinq;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
|
@ -30,7 +31,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
RemoteTrailers = new List<MediaUrl>();
|
||||
LocalTrailerIds = new List<Guid>();
|
||||
RemoteTrailerIds = new List<Guid>();
|
||||
DisplaySpecialsWithSeasons = true;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
@ -57,8 +57,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
}
|
||||
}
|
||||
|
||||
public bool DisplaySpecialsWithSeasons { get; set; }
|
||||
|
||||
public List<Guid> LocalTrailerIds { get; set; }
|
||||
public List<Guid> RemoteTrailerIds { get; set; }
|
||||
|
||||
|
@ -94,10 +92,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
get
|
||||
{
|
||||
return GetRecursiveChildren(i => i is Episode)
|
||||
.Select(i => i.DateCreated)
|
||||
.OrderByDescending(i => i)
|
||||
.FirstOrDefault();
|
||||
return DateLastMediaAdded ?? DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,14 +101,30 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
get
|
||||
{
|
||||
if (EnablePooling())
|
||||
var userdatakeys = GetUserDataKeys();
|
||||
|
||||
if (userdatakeys.Count > 1)
|
||||
{
|
||||
return GetUserDataKeys().First();
|
||||
return userdatakeys[0];
|
||||
}
|
||||
return base.PresentationUniqueKey;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Season).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName },
|
||||
IsVirtualItem = false,
|
||||
Limit = 0
|
||||
});
|
||||
|
||||
return result.TotalRecordCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
|
@ -182,27 +193,32 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
if (query.User == null)
|
||||
{
|
||||
return base.GetItemsInternal(query);
|
||||
}
|
||||
|
||||
var user = query.User;
|
||||
|
||||
if (query.Recursive)
|
||||
{
|
||||
query.AncestorWithPresentationUniqueKey = PresentationUniqueKey;
|
||||
if (query.SortBy.Length == 0)
|
||||
{
|
||||
query.SortBy = new[] { ItemSortBy.SortName };
|
||||
}
|
||||
if (query.IncludeItemTypes.Length == 0)
|
||||
{
|
||||
query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
|
||||
}
|
||||
query.IsVirtualItem = false;
|
||||
return Task.FromResult(LibraryManager.GetItemsResult(query));
|
||||
}
|
||||
|
||||
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
|
||||
|
||||
IEnumerable<BaseItem> items;
|
||||
|
||||
if (query.User == null)
|
||||
{
|
||||
items = query.Recursive
|
||||
? GetRecursiveChildren(filter)
|
||||
: Children.Where(filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
items = query.Recursive
|
||||
? GetSeasons(user).Cast<BaseItem>().Concat(GetEpisodes(user)).Where(filter)
|
||||
: GetSeasons(user).Where(filter);
|
||||
}
|
||||
|
||||
var items = GetSeasons(user).Where(filter);
|
||||
var result = PostFilterAndSort(items, query);
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
|
@ -210,33 +226,13 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
IEnumerable<Season> seasons;
|
||||
|
||||
if (EnablePooling())
|
||||
{
|
||||
var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
|
||||
{
|
||||
PresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Series).Name }
|
||||
});
|
||||
|
||||
if (seriesIds.Count > 1)
|
||||
{
|
||||
seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
|
||||
AncestorWithPresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Season).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
|
||||
}).Cast<Season>();
|
||||
}
|
||||
else
|
||||
{
|
||||
seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>();
|
||||
}
|
||||
|
||||
if (!includeMissingSeasons)
|
||||
{
|
||||
|
@ -259,8 +255,18 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, bool includeMissing, bool includeVirtualUnaired)
|
||||
{
|
||||
var allEpisodes = GetSeasons(user, true, true)
|
||||
.SelectMany(i => i.GetEpisodes(user, includeMissing, includeVirtualUnaired))
|
||||
var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
|
||||
}).ToList();
|
||||
|
||||
var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
|
||||
|
||||
var allEpisodes = allItems.OfType<Season>()
|
||||
.SelectMany(i => i.GetEpisodes(this, user, includeMissing, includeVirtualUnaired, allSeriesEpisodes))
|
||||
.Reverse()
|
||||
.ToList();
|
||||
|
||||
|
@ -283,9 +289,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
var totalItems = seasons.Count + otherItems.Count;
|
||||
var numComplete = 0;
|
||||
|
||||
refreshOptions = new MetadataRefreshOptions(refreshOptions);
|
||||
refreshOptions.IsPostRecursiveRefresh = true;
|
||||
|
||||
// Refresh current item
|
||||
await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -315,7 +318,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
&& refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
|
||||
&& !refreshOptions.ReplaceAllMetadata
|
||||
&& episode.IsMissingEpisode
|
||||
&& episode.LocationType == Model.Entities.LocationType.Virtual
|
||||
&& episode.LocationType == LocationType.Virtual
|
||||
&& episode.PremiereDate.HasValue
|
||||
&& (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30)
|
||||
{
|
||||
|
@ -333,6 +336,8 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
refreshOptions = new MetadataRefreshOptions(refreshOptions);
|
||||
refreshOptions.IsPostRecursiveRefresh = true;
|
||||
await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
progress.Report(100);
|
||||
|
@ -345,50 +350,32 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return GetEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
}
|
||||
|
||||
private bool EnablePooling()
|
||||
private IEnumerable<Episode> GetAllEpisodes(User user)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
return LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
IEnumerable<Episode> episodes;
|
||||
|
||||
if (EnablePooling())
|
||||
{
|
||||
var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
|
||||
{
|
||||
PresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Series).Name }
|
||||
});
|
||||
|
||||
if (seriesIds.Count > 1)
|
||||
{
|
||||
episodes = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
|
||||
AncestorWithPresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
|
||||
}).Cast<Episode>();
|
||||
}
|
||||
else
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
{
|
||||
episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name }
|
||||
}).Cast<Episode>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name }
|
||||
}).Cast<Episode>();
|
||||
IEnumerable<Episode> episodes = GetAllEpisodes(user);
|
||||
|
||||
return GetEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes);
|
||||
}
|
||||
|
||||
episodes = FilterEpisodesBySeason(episodes, parentSeason, DisplaySpecialsWithSeasons);
|
||||
public IEnumerable<Episode> GetEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> allSeriesEpisodes)
|
||||
{
|
||||
if (allSeriesEpisodes == null)
|
||||
{
|
||||
return GetEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
||||
}
|
||||
|
||||
var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons);
|
||||
|
||||
if (!includeMissingEpisodes)
|
||||
{
|
||||
|
@ -436,38 +423,31 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, Season parentSeason, bool includeSpecials)
|
||||
{
|
||||
var seasonNumber = parentSeason.IndexNumber;
|
||||
if (!includeSpecials || (seasonNumber.HasValue && seasonNumber.Value == 0))
|
||||
{
|
||||
var seasonPresentationKey = parentSeason.PresentationUniqueKey;
|
||||
|
||||
return episodes.Where(i =>
|
||||
{
|
||||
if ((i.ParentIndexNumber ?? -1) == seasonNumber)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var season = i.Season;
|
||||
return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var seasonPresentationKey = parentSeason.PresentationUniqueKey;
|
||||
var supportSpecialsInSeason = includeSpecials && seasonNumber.HasValue && seasonNumber.Value != 0;
|
||||
|
||||
return episodes.Where(episode =>
|
||||
{
|
||||
var currentSeasonNumber = episode.AiredSeasonNumber;
|
||||
|
||||
var currentSeasonNumber = supportSpecialsInSeason ? episode.AiredSeasonNumber : episode.ParentIndexNumber;
|
||||
if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!currentSeasonNumber.HasValue && !seasonNumber.HasValue && parentSeason.LocationType == LocationType.Virtual)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = episode.Season;
|
||||
return season != null && string.Equals(season.PresentationUniqueKey, seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
|
@ -508,5 +488,22 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
public override List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/shows/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasTags
|
||||
/// </summary>
|
||||
public interface IHasTags
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the tags.
|
||||
/// </summary>
|
||||
/// <value>The tags.</value>
|
||||
List<string> Tags { get; set; }
|
||||
}
|
||||
|
||||
public static class TagExtensions
|
||||
{
|
||||
public static void AddTag(this IHasTags item, string name)
|
||||
public static void AddTag(this BaseItem item, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
|
@ -5,13 +5,14 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Trailer
|
||||
/// </summary>
|
||||
public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo>
|
||||
public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo>
|
||||
{
|
||||
public List<string> ProductionLocations { get; set; }
|
||||
|
||||
|
@ -30,8 +31,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public List<MediaUrl> RemoteTrailers { get; set; }
|
||||
|
||||
public List<string> Keywords { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsLocalTrailer
|
||||
{
|
||||
|
@ -110,5 +109,22 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
public override List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,11 @@ namespace MediaBrowser.Controller.Entities
|
|||
return PostFilterAndSort(result.Where(filter), query);
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
return GetChildren(user, true).Count();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
protected override bool SupportsShortcutChildren
|
||||
{
|
||||
|
|
|
@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Entities
|
|||
return list;
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
return GetChildren(user, true).Count();
|
||||
}
|
||||
|
||||
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
var parent = this as Folder;
|
||||
|
@ -58,7 +63,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
|
||||
}
|
||||
|
||||
return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, CollectionManager, PlaylistManager)
|
||||
return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager, PlaylistManager)
|
||||
.GetUserItems(parent, this, ViewType, query);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
@ -30,10 +32,10 @@ namespace MediaBrowser.Controller.Entities
|
|||
private readonly ILogger _logger;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly ITVSeriesManager _tvSeriesManager;
|
||||
private readonly ICollectionManager _collectionManager;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IPlaylistManager _playlistManager;
|
||||
|
||||
public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, ICollectionManager collectionManager, IPlaylistManager playlistManager)
|
||||
public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, IServerConfigurationManager config, IPlaylistManager playlistManager)
|
||||
{
|
||||
_userViewManager = userViewManager;
|
||||
_liveTvManager = liveTvManager;
|
||||
|
@ -42,7 +44,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
_logger = logger;
|
||||
_userDataManager = userDataManager;
|
||||
_tvSeriesManager = tvSeriesManager;
|
||||
_collectionManager = collectionManager;
|
||||
_config = config;
|
||||
_playlistManager = playlistManager;
|
||||
}
|
||||
|
||||
|
@ -159,7 +161,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
return await GetTvGenres(queryParent, user, query).ConfigureAwait(false);
|
||||
|
||||
case SpecialFolder.TvGenre:
|
||||
return await GetTvGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
|
||||
return GetTvGenreItems(queryParent, displayParent, user, query);
|
||||
|
||||
case SpecialFolder.TvResume:
|
||||
return GetTvResume(queryParent, user, query);
|
||||
|
@ -332,13 +334,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
var items = parent.QueryRecursive(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = true,
|
||||
ParentId = parent.Id,
|
||||
IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
|
||||
IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
|
||||
EnableTotalRecordCount = false
|
||||
|
||||
}).Cast<IHasAlbumArtist>();
|
||||
}).Items.Cast<IHasAlbumArtist>();
|
||||
|
||||
var artists = _libraryManager.GetAlbumArtists(items);
|
||||
|
||||
|
@ -347,13 +350,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
var items = parent.QueryRecursive(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = true,
|
||||
ParentId = parent.Id,
|
||||
IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name }
|
||||
IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name },
|
||||
EnableTotalRecordCount = false
|
||||
|
||||
}).Cast<IHasArtist>();
|
||||
}).Items.Cast<IHasArtist>();
|
||||
|
||||
var artists = _libraryManager.GetArtists(items);
|
||||
|
||||
|
@ -362,13 +366,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
|
||||
{
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
var items = parent.QueryRecursive(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = true,
|
||||
ParentId = parent.Id,
|
||||
IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
|
||||
IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
|
||||
EnableTotalRecordCount = false
|
||||
|
||||
}).Cast<IHasAlbumArtist>();
|
||||
}).Items.Cast<IHasAlbumArtist>();
|
||||
|
||||
var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
|
||||
|
||||
|
@ -660,6 +665,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
query.SetUser(user);
|
||||
query.Limit = GetSpecialItemsLimit();
|
||||
query.IncludeItemTypes = new[] { typeof(Episode).Name };
|
||||
query.ExcludeLocationTypes = new[] { LocationType.Virtual };
|
||||
|
||||
return _libraryManager.GetItemsResult(query);
|
||||
}
|
||||
|
@ -737,7 +743,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
return GetResult(genres, parent, query);
|
||||
}
|
||||
|
||||
private async Task<QueryResult<BaseItem>> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
|
||||
private QueryResult<BaseItem> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
|
||||
{
|
||||
query.Recursive = true;
|
||||
query.ParentId = queryParent.Id;
|
||||
|
@ -766,7 +772,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager));
|
||||
|
||||
return PostFilterAndSort(items, queryParent, null, query, _libraryManager);
|
||||
return PostFilterAndSort(items, queryParent, null, query, _libraryManager, _config);
|
||||
}
|
||||
|
||||
public static bool FilterItem(BaseItem item, InternalItemsQuery query)
|
||||
|
@ -779,14 +785,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
int? totalRecordLimit,
|
||||
InternalItemsQuery query)
|
||||
{
|
||||
return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager);
|
||||
return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _config);
|
||||
}
|
||||
|
||||
public static QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
|
||||
BaseItem queryParent,
|
||||
int? totalRecordLimit,
|
||||
InternalItemsQuery query,
|
||||
ILibraryManager libraryManager)
|
||||
ILibraryManager libraryManager,
|
||||
IServerConfigurationManager configurationManager)
|
||||
{
|
||||
var user = query.User;
|
||||
|
||||
|
@ -795,7 +802,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
query.IsVirtualUnaired,
|
||||
query.IsUnaired);
|
||||
|
||||
items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user);
|
||||
items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user, configurationManager);
|
||||
|
||||
// This must be the last filter
|
||||
if (!string.IsNullOrEmpty(query.AdjacentTo))
|
||||
|
@ -809,14 +816,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
public static IEnumerable<BaseItem> CollapseBoxSetItemsIfNeeded(IEnumerable<BaseItem> items,
|
||||
InternalItemsQuery query,
|
||||
BaseItem queryParent,
|
||||
User user)
|
||||
User user,
|
||||
IServerConfigurationManager configurationManager)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
throw new ArgumentNullException("items");
|
||||
}
|
||||
|
||||
if (CollapseBoxSetItems(query, queryParent, user))
|
||||
if (CollapseBoxSetItems(query, queryParent, user, configurationManager))
|
||||
{
|
||||
items = BaseItem.CollectionManager.CollapseItemsWithinBoxSets(items, user);
|
||||
}
|
||||
|
@ -849,7 +857,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public static bool CollapseBoxSetItems(InternalItemsQuery query,
|
||||
BaseItem queryParent,
|
||||
User user)
|
||||
User user,
|
||||
IServerConfigurationManager configurationManager)
|
||||
{
|
||||
// Could end up stuck in a loop like this
|
||||
if (queryParent is BoxSet)
|
||||
|
@ -861,7 +870,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (!param.HasValue)
|
||||
{
|
||||
if (user != null && !user.Configuration.GroupMoviesIntoBoxSets)
|
||||
if (user != null && !configurationManager.Configuration.EnableGroupingIntoCollections)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -992,11 +1001,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
|
||||
if (request.IsYearMismatched.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Person))
|
||||
{
|
||||
return false;
|
||||
|
@ -1415,16 +1419,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
if (query.IsYearMismatched.HasValue)
|
||||
{
|
||||
var filterValue = query.IsYearMismatched.Value;
|
||||
|
||||
if (IsYearMismatched(item, libraryManager) != filterValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (query.HasOfficialRating.HasValue)
|
||||
{
|
||||
var filterValue = query.HasOfficialRating.Value;
|
||||
|
@ -1658,12 +1652,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
var tags = query.Tags;
|
||||
if (tags.Length > 0)
|
||||
{
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
|
||||
if (!tags.Any(v => item.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1976,34 +1965,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None);
|
||||
}
|
||||
|
||||
public static bool IsYearMismatched(BaseItem item, ILibraryManager libraryManager)
|
||||
{
|
||||
if (item.ProductionYear.HasValue)
|
||||
{
|
||||
var path = item.Path;
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var info = libraryManager.ParseName(Path.GetFileName(path));
|
||||
var yearInName = info.Year;
|
||||
|
||||
// Go up a level if we didn't get a year
|
||||
if (!yearInName.HasValue)
|
||||
{
|
||||
info = libraryManager.ParseName(Path.GetFileName(Path.GetDirectoryName(path)));
|
||||
yearInName = info.Year;
|
||||
}
|
||||
|
||||
if (yearInName.HasValue)
|
||||
{
|
||||
return yearInName.Value != item.ProductionYear.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<BaseItem> FilterForAdjacency(IEnumerable<BaseItem> items, string adjacentToId)
|
||||
{
|
||||
var list = items.ToList();
|
||||
|
|
|
@ -21,7 +21,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
public class Video : BaseItem,
|
||||
IHasAspectRatio,
|
||||
IHasTags,
|
||||
ISupportsPlaceHolders,
|
||||
IHasMediaSources,
|
||||
IHasShortOverview,
|
||||
|
|
|
@ -150,13 +150,6 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <returns>BaseItem.</returns>
|
||||
BaseItem GetItemById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the memory item by identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem GetMemoryItemById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intros.
|
||||
/// </summary>
|
||||
|
|
|
@ -15,5 +15,6 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken);
|
||||
Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings);
|
||||
Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location);
|
||||
Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Events;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
|
@ -385,5 +386,15 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
List<NameValuePair> GetSatIniMappings();
|
||||
|
||||
Task<List<ChannelInfo>> GetSatChannelScanResult(TunerHostInfo info, CancellationToken cancellationToken);
|
||||
|
||||
Task<List<ChannelInfo>> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken);
|
||||
Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
|
||||
|
||||
List<IListingsProvider> ListingProviders { get;}
|
||||
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled;
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated;
|
||||
event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,4 +226,23 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <returns>Task.</returns>
|
||||
Task ResetTuner(string id, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public interface ISupportsNewTimerIds
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the timer asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<string> CreateTimer(TimerInfo info, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the series timer asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<string> CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
|
@ -235,5 +236,25 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
if (IsMovie)
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
MediaBrowser.Controller/LiveTv/TimerEventInfo.cs
Normal file
14
MediaBrowser.Controller/LiveTv/TimerEventInfo.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
public class TimerEventInfo
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string ProgramId { get; set; }
|
||||
}
|
||||
}
|
|
@ -142,7 +142,7 @@
|
|||
<Compile Include="Entities\IHasDisplayOrder.cs" />
|
||||
<Compile Include="Entities\IHasId.cs" />
|
||||
<Compile Include="Entities\IHasImages.cs" />
|
||||
<Compile Include="Entities\IHasKeywords.cs" />
|
||||
<Compile Include="Entities\KeywordExtensions.cs" />
|
||||
<Compile Include="Entities\IHasMediaSources.cs" />
|
||||
<Compile Include="Entities\IHasMetascore.cs" />
|
||||
<Compile Include="Entities\IHasOriginalTitle.cs" />
|
||||
|
@ -154,7 +154,6 @@
|
|||
<Compile Include="Entities\IHasSpecialFeatures.cs" />
|
||||
<Compile Include="Entities\IHasStartDate.cs" />
|
||||
<Compile Include="Entities\IHasTaglines.cs" />
|
||||
<Compile Include="Entities\IHasTags.cs" />
|
||||
<Compile Include="Entities\IHasThemeMedia.cs" />
|
||||
<Compile Include="Entities\IHasTrailers.cs" />
|
||||
<Compile Include="Entities\IHasUserData.cs" />
|
||||
|
@ -177,6 +176,7 @@
|
|||
<Compile Include="Entities\PhotoAlbum.cs" />
|
||||
<Compile Include="Entities\Share.cs" />
|
||||
<Compile Include="Entities\SourceType.cs" />
|
||||
<Compile Include="Entities\TagExtensions.cs" />
|
||||
<Compile Include="Entities\UserView.cs" />
|
||||
<Compile Include="Entities\UserViewBuilder.cs" />
|
||||
<Compile Include="FileOrganization\IFileOrganizationService.cs" />
|
||||
|
@ -218,6 +218,7 @@
|
|||
<Compile Include="LiveTv\ProgramInfo.cs" />
|
||||
<Compile Include="LiveTv\RecordingInfo.cs" />
|
||||
<Compile Include="LiveTv\SeriesTimerInfo.cs" />
|
||||
<Compile Include="LiveTv\TimerEventInfo.cs" />
|
||||
<Compile Include="LiveTv\TimerInfo.cs" />
|
||||
<Compile Include="Localization\ILocalizationManager.cs" />
|
||||
<Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" />
|
||||
|
@ -290,14 +291,11 @@
|
|||
<Compile Include="Providers\IImageFileSaver.cs" />
|
||||
<Compile Include="Providers\IImageProvider.cs" />
|
||||
<Compile Include="Providers\IImageSaver.cs" />
|
||||
<Compile Include="Providers\IItemIdentityConverter.cs" />
|
||||
<Compile Include="Providers\IItemIdentityProvider.cs" />
|
||||
<Compile Include="Providers\ILocalImageFileProvider.cs" />
|
||||
<Compile Include="Providers\ILocalMetadataProvider.cs" />
|
||||
<Compile Include="Providers\ImageRefreshMode.cs" />
|
||||
<Compile Include="Providers\ImageRefreshOptions.cs" />
|
||||
<Compile Include="Providers\IPreRefreshProvider.cs" />
|
||||
<Compile Include="Providers\IProviderRepository.cs" />
|
||||
<Compile Include="Providers\IRemoteImageProvider.cs" />
|
||||
<Compile Include="Providers\ILocalImageProvider.cs" />
|
||||
<Compile Include="Providers\IMetadataProvider.cs" />
|
||||
|
@ -330,11 +328,8 @@
|
|||
<Compile Include="Sorting\SortHelper.cs" />
|
||||
<Compile Include="Subtitles\ISubtitleManager.cs" />
|
||||
<Compile Include="Subtitles\ISubtitleProvider.cs" />
|
||||
<Compile Include="Providers\ItemIdentifier.cs" />
|
||||
<Compile Include="Providers\ItemIdentities.cs" />
|
||||
<Compile Include="Providers\ItemLookupInfo.cs" />
|
||||
<Compile Include="Providers\MetadataRefreshOptions.cs" />
|
||||
<Compile Include="Providers\MetadataStatus.cs" />
|
||||
<Compile Include="Providers\ISeriesOrderManager.cs" />
|
||||
<Compile Include="Session\ISessionManager.cs" />
|
||||
<Compile Include="Entities\AggregateFolder.cs" />
|
||||
|
|
|
@ -10,13 +10,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
/// <summary>
|
||||
/// Gets the subtitles.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <param name="mediaSourceId">The media source identifier.</param>
|
||||
/// <param name="subtitleStreamIndex">Index of the subtitle stream.</param>
|
||||
/// <param name="outputFormat">The output format.</param>
|
||||
/// <param name="startTimeTicks">The start time ticks.</param>
|
||||
/// <param name="endTimeTicks">The end time ticks.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<Stream> GetSubtitles(string itemId,
|
||||
string mediaSourceId,
|
||||
|
@ -24,6 +17,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||
string outputFormat,
|
||||
long startTimeTicks,
|
||||
long? endTimeTicks,
|
||||
bool preserveOriginalTimestamps,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// <param name="chapters">The chapters.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveChapters(Guid id, IEnumerable<ChapterInfo> chapters, CancellationToken cancellationToken);
|
||||
Task SaveChapters(Guid id, List<ChapterInfo> chapters, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
|
@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// <param name="streams">The streams.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken);
|
||||
Task SaveMediaStreams(Guid id, List<MediaStream> streams, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item ids.
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// <returns>Task{UserItemData}.</returns>
|
||||
UserItemData GetUserData(Guid userId, string key);
|
||||
|
||||
UserItemData GetUserData(Guid userId, List<string> keys);
|
||||
|
||||
/// <summary>
|
||||
/// Return all user data associated with the given user
|
||||
/// </summary>
|
||||
|
|
|
@ -803,11 +803,7 @@ namespace MediaBrowser.Controller.Providers
|
|||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags != null)
|
||||
{
|
||||
FetchFromTagsNode(subtree, hasTags);
|
||||
}
|
||||
FetchFromTagsNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -816,11 +812,7 @@ namespace MediaBrowser.Controller.Providers
|
|||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
var hasTags = item as IHasKeywords;
|
||||
if (hasTags != null)
|
||||
{
|
||||
FetchFromKeywordsNode(subtree, hasTags);
|
||||
}
|
||||
FetchFromKeywordsNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1070,7 +1062,7 @@ namespace MediaBrowser.Controller.Providers
|
|||
}
|
||||
}
|
||||
|
||||
private void FetchFromTagsNode(XmlReader reader, IHasTags item)
|
||||
private void FetchFromTagsNode(XmlReader reader, BaseItem item)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
|
@ -1099,7 +1091,7 @@ namespace MediaBrowser.Controller.Providers
|
|||
}
|
||||
}
|
||||
|
||||
private void FetchFromKeywordsNode(XmlReader reader, IHasKeywords item)
|
||||
private void FetchFromKeywordsNode(XmlReader reader, BaseItem item)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IItemIdentityConverter { }
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IItemIdentityProvider { }
|
||||
}
|
|
@ -97,13 +97,11 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// </summary>
|
||||
/// <param name="imageProviders">The image providers.</param>
|
||||
/// <param name="metadataServices">The metadata services.</param>
|
||||
/// <param name="identityProviders">The identity providers.</param>
|
||||
/// <param name="identityConverters">The identity converters.</param>
|
||||
/// <param name="metadataProviders">The metadata providers.</param>
|
||||
/// <param name="savers">The savers.</param>
|
||||
/// <param name="imageSavers">The image savers.</param>
|
||||
/// <param name="externalIds">The external ids.</param>
|
||||
void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IItemIdentityProvider> identityProviders, IEnumerable<IItemIdentityConverter> identityConverters, IEnumerable<IMetadataProvider> metadataProviders,
|
||||
void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders,
|
||||
IEnumerable<IMetadataSaver> savers,
|
||||
IEnumerable<IImageSaver> imageSavers,
|
||||
IEnumerable<IExternalId> externalIds);
|
||||
|
@ -135,7 +133,7 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>IEnumerable{ExternalUrl}.</returns>
|
||||
IEnumerable<ExternalUrl> GetExternalUrls(IHasProviderIds item);
|
||||
IEnumerable<ExternalUrl> GetExternalUrls(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external identifier infos.
|
||||
|
@ -190,21 +188,5 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{HttpResponseInfo}.</returns>
|
||||
Task<HttpResponseInfo> GetSearchImage(string providerName, string url, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item identity providers.
|
||||
/// </summary>
|
||||
/// <typeparam name="TLookupInfo">The type of the t lookup information.</typeparam>
|
||||
/// <returns>IEnumerable<IItemIdentityProvider<TLookupInfo, TIdentity>>.</returns>
|
||||
IEnumerable<IItemIdentityProvider<TLookupInfo>> GetItemIdentityProviders<TLookupInfo>()
|
||||
where TLookupInfo : ItemLookupInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item identity converters.
|
||||
/// </summary>
|
||||
/// <typeparam name="TLookupInfo">The type of the t lookup information.</typeparam>
|
||||
/// <returns>IEnumerable<IItemIdentityConverter<TIdentity>>.</returns>
|
||||
IEnumerable<IItemIdentityConverter<TLookupInfo>> GetItemIdentityConverters<TLookupInfo>()
|
||||
where TLookupInfo : ItemLookupInfo;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
using MediaBrowser.Controller.Persistence;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IProviderRepository : IRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the metadata status.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <returns>MetadataStatus.</returns>
|
||||
MetadataStatus GetMetadataStatus(Guid itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the metadata status.
|
||||
/// </summary>
|
||||
/// <param name="status">The status.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveMetadataStatus(MetadataStatus status, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public static class ItemIdentifier<TLookupInfo>
|
||||
where TLookupInfo : ItemLookupInfo
|
||||
{
|
||||
public static async Task FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken)
|
||||
{
|
||||
var providers = providerManager.GetItemIdentityProviders<TLookupInfo>();
|
||||
var converters = providerManager.GetItemIdentityConverters<TLookupInfo>().ToList();
|
||||
|
||||
foreach (var provider in providers)
|
||||
{
|
||||
await provider.Identify(item);
|
||||
}
|
||||
|
||||
bool changesMade = true;
|
||||
|
||||
while (changesMade)
|
||||
{
|
||||
changesMade = false;
|
||||
|
||||
foreach (var converter in converters)
|
||||
{
|
||||
if (await converter.Convert(item))
|
||||
{
|
||||
changesMade = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IItemIdentityProvider<in TLookupInfo> : IItemIdentityProvider
|
||||
where TLookupInfo : ItemLookupInfo
|
||||
{
|
||||
Task Identify(TLookupInfo info);
|
||||
}
|
||||
|
||||
public interface IItemIdentityConverter<in TLookupInfo> : IItemIdentityConverter
|
||||
where TLookupInfo : ItemLookupInfo
|
||||
{
|
||||
Task<bool> Convert(TLookupInfo info);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
|
@ -5,10 +6,6 @@ namespace MediaBrowser.Controller.Providers
|
|||
{
|
||||
public class ItemInfo
|
||||
{
|
||||
public ItemInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public ItemInfo(IHasMetadata item)
|
||||
{
|
||||
Path = item.Path;
|
||||
|
@ -21,8 +18,11 @@ namespace MediaBrowser.Controller.Providers
|
|||
VideoType = video.VideoType;
|
||||
IsPlaceHolder = video.IsPlaceHolder;
|
||||
}
|
||||
|
||||
ItemType = item.GetType();
|
||||
}
|
||||
|
||||
public Type ItemType { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string ContainingFolderPath { get; set; }
|
||||
public VideoType VideoType { get; set; }
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class MetadataStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item identifier.
|
||||
/// </summary>
|
||||
/// <value>The item identifier.</value>
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date last metadata refresh.
|
||||
/// </summary>
|
||||
/// <value>The date last metadata refresh.</value>
|
||||
public DateTime? DateLastMetadataRefresh { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date last images refresh.
|
||||
/// </summary>
|
||||
/// <value>The date last images refresh.</value>
|
||||
public DateTime? DateLastImagesRefresh { get; set; }
|
||||
|
||||
public DateTime? ItemDateModified { get; set; }
|
||||
|
||||
public bool IsDirty { get; private set; }
|
||||
|
||||
public void SetDateLastMetadataRefresh(DateTime? date)
|
||||
{
|
||||
if (date != DateLastMetadataRefresh)
|
||||
{
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
DateLastMetadataRefresh = date;
|
||||
}
|
||||
|
||||
public void SetDateLastImagesRefresh(DateTime? date)
|
||||
{
|
||||
if (date != DateLastImagesRefresh)
|
||||
{
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
DateLastImagesRefresh = date;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -315,9 +315,8 @@ namespace MediaBrowser.Controller.Session
|
|||
/// <summary>
|
||||
/// Revokes the user tokens.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RevokeUserTokens(string userId);
|
||||
Task RevokeUserTokens(string userId, string currentAccessToken);
|
||||
|
||||
/// <summary>
|
||||
/// Revokes the token.
|
||||
|
|
|
@ -1015,17 +1015,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
|
||||
{
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
var inputFormat = (Path.GetExtension(imageInfo.Path) ?? string.Empty)
|
||||
.TrimStart('.')
|
||||
|
|
|
@ -101,6 +101,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||
}
|
||||
|
||||
var uri = new Uri(location);
|
||||
_logger.Debug("Attempting to create PlayToController from location {0}", location);
|
||||
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
|
||||
|
||||
if (device.RendererCommands == null)
|
||||
|
@ -112,6 +113,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||
}
|
||||
}
|
||||
|
||||
_logger.Debug("Logging session activity from location {0}", location);
|
||||
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ namespace MediaBrowser.Dlna.Profiles
|
|||
new HttpHeaderInfo
|
||||
{
|
||||
Name = "User-Agent",
|
||||
Value = @"SEC_",
|
||||
Match = HeaderMatchType.Substring
|
||||
Value = @".*(SEC_HHP_\[TV\] [A-Z]{2}\d{2}J[A-Z]?\d{3,4})*.",
|
||||
Match = HeaderMatchType.Regex
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<Identification>
|
||||
<ModelUrl>samsung.com</ModelUrl>
|
||||
<Headers>
|
||||
<HttpHeaderInfo name="User-Agent" value="SEC_" match="Substring" />
|
||||
<HttpHeaderInfo name="User-Agent" value=".*(SEC_HHP_\[TV\] [A-Z]{2}\d{2}J[A-Z]?\d{3,4})*." match="Regex" />
|
||||
</Headers>
|
||||
</Identification>
|
||||
<Manufacturer>Emby</Manufacturer>
|
||||
|
|
|
@ -593,37 +593,29 @@ namespace MediaBrowser.LocalMetadata.Savers
|
|||
builder.Append("</Studios>");
|
||||
}
|
||||
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags != null)
|
||||
{
|
||||
if (hasTags.Tags.Count > 0)
|
||||
if (item.Tags.Count > 0)
|
||||
{
|
||||
builder.Append("<Tags>");
|
||||
|
||||
foreach (var tag in hasTags.Tags)
|
||||
foreach (var tag in item.Tags)
|
||||
{
|
||||
builder.Append("<Tag>" + SecurityElement.Escape(tag) + "</Tag>");
|
||||
}
|
||||
|
||||
builder.Append("</Tags>");
|
||||
}
|
||||
}
|
||||
|
||||
var hasKeywords = item as IHasKeywords;
|
||||
if (hasKeywords != null)
|
||||
{
|
||||
if (hasKeywords.Keywords.Count > 0)
|
||||
if (item.Keywords.Count > 0)
|
||||
{
|
||||
builder.Append("<PlotKeywords>");
|
||||
|
||||
foreach (var tag in hasKeywords.Keywords)
|
||||
foreach (var tag in item.Keywords)
|
||||
{
|
||||
builder.Append("<PlotKeyword>" + SecurityElement.Escape(tag) + "</PlotKeyword>");
|
||||
}
|
||||
|
||||
builder.Append("</PlotKeywords>");
|
||||
}
|
||||
}
|
||||
|
||||
var people = libraryManager.GetPeople(item);
|
||||
|
||||
|
|
|
@ -73,11 +73,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
|
||||
var commandLineArgs = GetCommandLineArguments(encodingJob);
|
||||
|
||||
if (GetEncodingOptions().EnableDebugLogging)
|
||||
{
|
||||
commandLineArgs = "-loglevel debug " + commandLineArgs;
|
||||
}
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
if (videoRequest != null)
|
||||
{
|
||||
state.OutputVideoCodec = state.Options.VideoCodec;
|
||||
state.OutputVideoBitrate = GetVideoBitrateParamValue(state.Options, state.VideoStream);
|
||||
state.OutputVideoBitrate = GetVideoBitrateParamValue(state.Options, state.VideoStream, state.OutputVideoCodec);
|
||||
|
||||
if (state.OutputVideoBitrate.HasValue)
|
||||
{
|
||||
|
@ -396,7 +396,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
return request.AudioChannels;
|
||||
}
|
||||
|
||||
private int? GetVideoBitrateParamValue(EncodingJobOptions request, MediaStream videoStream)
|
||||
private int? GetVideoBitrateParamValue(EncodingJobOptions request, MediaStream videoStream, string outputVideoCodec)
|
||||
{
|
||||
var bitrate = request.VideoBitRate;
|
||||
|
||||
|
@ -421,6 +421,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
}
|
||||
}
|
||||
|
||||
if (bitrate.HasValue)
|
||||
{
|
||||
var inputVideoCodec = videoStream == null ? null : videoStream.Codec;
|
||||
bitrate = ResolutionNormalizer.ScaleBitrate(bitrate.Value, inputVideoCodec, outputVideoCodec);
|
||||
|
||||
// If a max bitrate was requested, don't let the scaled bitrate exceed it
|
||||
if (request.VideoBitRate.HasValue)
|
||||
{
|
||||
bitrate = Math.Min(bitrate.Value, request.VideoBitRate.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
|
|
|
@ -408,7 +408,9 @@ namespace MediaBrowser.MediaEncoding.Probing
|
|||
Level = streamInfo.level,
|
||||
Index = streamInfo.index,
|
||||
PixelFormat = streamInfo.pix_fmt,
|
||||
NalLengthSize = streamInfo.nal_length_size
|
||||
NalLengthSize = streamInfo.nal_length_size,
|
||||
TimeBase = streamInfo.time_base,
|
||||
CodecTimeBase = streamInfo.codec_time_base
|
||||
};
|
||||
|
||||
if (string.Equals(streamInfo.is_avc, "true", StringComparison.OrdinalIgnoreCase) ||
|
||||
|
|
|
@ -58,6 +58,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
string outputFormat,
|
||||
long startTimeTicks,
|
||||
long? endTimeTicks,
|
||||
bool preserveOriginalTimestamps,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
|
@ -68,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
|
||||
var trackInfo = reader.Parse(stream, cancellationToken);
|
||||
|
||||
FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false);
|
||||
FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
|
||||
|
||||
var writer = GetWriter(outputFormat);
|
||||
|
||||
|
@ -116,6 +117,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
string outputFormat,
|
||||
long startTimeTicks,
|
||||
long? endTimeTicks,
|
||||
bool preserveOriginalTimestamps,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken)
|
||||
|
@ -130,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
|
||||
using (var stream = subtitle.Item1)
|
||||
{
|
||||
return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, cancellationToken).ConfigureAwait(false);
|
||||
return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -230,12 +230,6 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs">
|
||||
<Link>Configuration\SubtitlePlaybackMode.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TheMovieDbOptions.cs">
|
||||
<Link>Configuration\TheMovieDbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TvdbOptions.cs">
|
||||
<Link>Configuration\TvdbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\UnratedItem.cs">
|
||||
<Link>Configuration\UnratedItem.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -204,12 +204,6 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\SubtitlePlaybackMode.cs">
|
||||
<Link>Configuration\SubtitlePlaybackMode.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TheMovieDbOptions.cs">
|
||||
<Link>Configuration\TheMovieDbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\TvdbOptions.cs">
|
||||
<Link>Configuration\TvdbOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\UnratedItem.cs">
|
||||
<Link>Configuration\UnratedItem.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -57,6 +57,10 @@ namespace MediaBrowser.Model.ApiClient
|
|||
{
|
||||
existing.RemoteAddress = server.RemoteAddress;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(server.ConnectServerId))
|
||||
{
|
||||
existing.ConnectServerId = server.ConnectServerId;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(server.LocalAddress))
|
||||
{
|
||||
existing.LocalAddress = server.LocalAddress;
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace MediaBrowser.Model.ApiClient
|
|||
|
||||
public String Name { get; set; }
|
||||
public String Id { get; set; }
|
||||
public String ConnectServerId { get; set; }
|
||||
public String LocalAddress { get; set; }
|
||||
public String RemoteAddress { get; set; }
|
||||
public String ManualAddress { get; set; }
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
public int EncodingThreadCount { get; set; }
|
||||
public string TranscodingTempPath { get; set; }
|
||||
public double DownMixAudioBoost { get; set; }
|
||||
public bool EnableDebugLogging { get; set; }
|
||||
public bool EnableThrottling { get; set; }
|
||||
public int ThrottleDelaySeconds { get; set; }
|
||||
public string HardwareAccelerationType { get; set; }
|
||||
|
|
|
@ -3,11 +3,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
{
|
||||
public class FanartOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable automatic updates].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableAutomaticUpdates { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the user API key.
|
||||
/// </summary>
|
||||
|
|
|
@ -86,12 +86,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// <value><c>true</c> if [save local meta]; otherwise, <c>false</c>.</value>
|
||||
public bool SaveLocalMeta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable localized guids].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable localized guids]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableLocalizedGuids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred metadata language.
|
||||
/// </summary>
|
||||
|
@ -190,14 +184,10 @@ namespace MediaBrowser.Model.Configuration
|
|||
public bool EnableVideoArchiveFiles { get; set; }
|
||||
public int RemoteClientBitrateLimit { get; set; }
|
||||
|
||||
public bool DenyIFrameEmbedding { get; set; }
|
||||
|
||||
public AutoOnOff EnableLibraryMonitor { get; set; }
|
||||
|
||||
public int SharingExpirationDays { get; set; }
|
||||
|
||||
public bool EnableDateLastRefresh { get; set; }
|
||||
|
||||
public string[] Migrations { get; set; }
|
||||
|
||||
public int MigrationVersion { get; set; }
|
||||
|
@ -207,16 +197,24 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public bool EnableAnonymousUsageReporting { get; set; }
|
||||
public bool EnableStandaloneMusicKeys { get; set; }
|
||||
public bool EnableLocalizedGuids { get; set; }
|
||||
public bool EnableFolderView { get; set; }
|
||||
public bool EnableGroupingIntoCollections { get; set; }
|
||||
public bool DisplaySpecialsWithinSeasons { get; set; }
|
||||
public bool DisplayCollectionsView { get; set; }
|
||||
public string[] LocalNetworkAddresses { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||
/// </summary>
|
||||
public ServerConfiguration()
|
||||
{
|
||||
LocalNetworkAddresses = new string[] { };
|
||||
Migrations = new string[] { };
|
||||
|
||||
EnableLocalizedGuids = true;
|
||||
EnableCustomPathSubFolders = true;
|
||||
EnableLocalizedGuids = true;
|
||||
DisplaySpecialsWithinSeasons = true;
|
||||
|
||||
ImageSavingConvention = ImageSavingConvention.Compatible;
|
||||
PublicPort = 8096;
|
||||
|
@ -229,10 +227,8 @@ namespace MediaBrowser.Model.Configuration
|
|||
EnableAnonymousUsageReporting = true;
|
||||
|
||||
EnableAutomaticRestart = true;
|
||||
DenyIFrameEmbedding = true;
|
||||
|
||||
EnableUPnP = true;
|
||||
|
||||
SharingExpirationDays = 30;
|
||||
MinResumePct = 5;
|
||||
MaxResumePct = 90;
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public class TheMovieDbOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable automatic updates].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableAutomaticUpdates { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public class TvdbOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [enable automatic updates].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [enable automatic updates]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableAutomaticUpdates { get; set; }
|
||||
}
|
||||
}
|
|
@ -34,14 +34,11 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public SubtitlePlaybackMode SubtitleMode { get; set; }
|
||||
public bool DisplayCollectionsView { get; set; }
|
||||
public bool DisplayFoldersView { get; set; }
|
||||
|
||||
public bool EnableLocalPassword { get; set; }
|
||||
|
||||
public string[] OrderedViews { get; set; }
|
||||
|
||||
public bool IncludeTrailersInSuggestions { get; set; }
|
||||
|
||||
public string[] LatestItemsExcludes { get; set; }
|
||||
public string[] PlainFolderViews { get; set; }
|
||||
|
||||
|
@ -51,6 +48,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
public bool RememberAudioSelections { get; set; }
|
||||
public bool RememberSubtitleSelections { get; set; }
|
||||
public bool EnableNextEpisodeAutoPlay { get; set; }
|
||||
public bool DisplayFoldersView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||
|
@ -69,8 +67,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
PlainFolderViews = new string[] { };
|
||||
|
||||
IncludeTrailersInSuggestions = true;
|
||||
|
||||
GroupedFolders = new string[] { };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,5 +56,25 @@ namespace MediaBrowser.Model.Dlna
|
|||
MaxHeight = maxHeight
|
||||
};
|
||||
}
|
||||
|
||||
private static double GetVideoBitrateScaleFactor(string codec)
|
||||
{
|
||||
if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return .5;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int ScaleBitrate(int bitrate, string inputVideoCodec, string outputVideoCodec)
|
||||
{
|
||||
var inputScaleFactor = GetVideoBitrateScaleFactor(inputVideoCodec);
|
||||
var outputScaleFactor = GetVideoBitrateScaleFactor(outputVideoCodec);
|
||||
var scaleFactor = outputScaleFactor/inputScaleFactor;
|
||||
var newBitrate = scaleFactor*bitrate;
|
||||
|
||||
return Convert.ToInt32(newBitrate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -335,7 +335,8 @@ namespace MediaBrowser.Model.Dlna
|
|||
Name = stream.Language ?? "Unknown",
|
||||
Format = subtitleProfile.Format,
|
||||
Index = stream.Index,
|
||||
DeliveryMethod = subtitleProfile.Method
|
||||
DeliveryMethod = subtitleProfile.Method,
|
||||
DisplayTitle = stream.DisplayTitle
|
||||
};
|
||||
|
||||
if (info.DeliveryMethod == SubtitleDeliveryMethod.External)
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
public string Name { get; set; }
|
||||
public bool IsForced { get; set; }
|
||||
public string Format { get; set; }
|
||||
public string DisplayTitle { get; set; }
|
||||
public int Index { get; set; }
|
||||
public SubtitleDeliveryMethod DeliveryMethod { get; set; }
|
||||
public bool IsExternalUrl { get; set; }
|
||||
|
|
|
@ -9,50 +9,50 @@ namespace MediaBrowser.Model.Entities
|
|||
/// <summary>
|
||||
/// The primary
|
||||
/// </summary>
|
||||
Primary,
|
||||
Primary = 0,
|
||||
/// <summary>
|
||||
/// The art
|
||||
/// </summary>
|
||||
Art,
|
||||
Art = 1,
|
||||
/// <summary>
|
||||
/// The backdrop
|
||||
/// </summary>
|
||||
Backdrop,
|
||||
Backdrop = 2,
|
||||
/// <summary>
|
||||
/// The banner
|
||||
/// </summary>
|
||||
Banner,
|
||||
Banner = 3,
|
||||
/// <summary>
|
||||
/// The logo
|
||||
/// </summary>
|
||||
Logo,
|
||||
Logo = 4,
|
||||
/// <summary>
|
||||
/// The thumb
|
||||
/// </summary>
|
||||
Thumb,
|
||||
Thumb = 5,
|
||||
/// <summary>
|
||||
/// The disc
|
||||
/// </summary>
|
||||
Disc,
|
||||
Disc = 6,
|
||||
/// <summary>
|
||||
/// The box
|
||||
/// </summary>
|
||||
Box,
|
||||
Box = 7,
|
||||
/// <summary>
|
||||
/// The screenshot
|
||||
/// </summary>
|
||||
Screenshot,
|
||||
Screenshot = 8,
|
||||
/// <summary>
|
||||
/// The menu
|
||||
/// </summary>
|
||||
Menu,
|
||||
Menu = 9,
|
||||
/// <summary>
|
||||
/// The chapter image
|
||||
/// </summary>
|
||||
Chapter,
|
||||
Chapter = 10,
|
||||
/// <summary>
|
||||
/// The box rear
|
||||
/// </summary>
|
||||
BoxRear
|
||||
BoxRear = 11
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ namespace MediaBrowser.Model.Entities
|
|||
/// <value>The comment.</value>
|
||||
public string Comment { get; set; }
|
||||
|
||||
public string TimeBase { get; set; }
|
||||
public string CodecTimeBase { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public string DisplayTitle
|
||||
|
@ -89,7 +92,7 @@ namespace MediaBrowser.Model.Entities
|
|||
|
||||
if (!string.IsNullOrEmpty(Language))
|
||||
{
|
||||
attributes.Add(Language);
|
||||
attributes.Add(StringHelper.FirstToUpper(Language));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Model.LiveTv
|
||||
{
|
||||
|
@ -73,11 +75,33 @@ namespace MediaBrowser.Model.LiveTv
|
|||
|
||||
public string[] EnabledTuners { get; set; }
|
||||
public bool EnableAllTuners { get; set; }
|
||||
public string[] NewsCategories { get; set; }
|
||||
public string[] SportsCategories { get; set; }
|
||||
public string[] KidsCategories { get; set; }
|
||||
public string[] MovieCategories { get; set; }
|
||||
public NameValuePair[] ChannelMappings { get; set; }
|
||||
|
||||
public ListingsProviderInfo()
|
||||
{
|
||||
NewsCategories = new string[] { "news", "journalism", "documentary", "current affairs" };
|
||||
SportsCategories = new string[] { "sports", "basketball", "baseball", "football" };
|
||||
KidsCategories = new string[] { "kids", "family", "children", "childrens", "disney" };
|
||||
MovieCategories = new string[] { "movie" };
|
||||
EnabledTuners = new string[] { };
|
||||
EnableAllTuners = true;
|
||||
ChannelMappings = new NameValuePair[] {};
|
||||
}
|
||||
|
||||
public string GetMappedChannel(string channelNumber)
|
||||
{
|
||||
foreach (NameValuePair mapping in ChannelMappings)
|
||||
{
|
||||
if (StringHelper.EqualsIgnoreCase(mapping.Name, channelNumber))
|
||||
{
|
||||
return mapping.Value;
|
||||
}
|
||||
}
|
||||
return channelNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,8 +97,6 @@
|
|||
<Compile Include="Configuration\FanartOptions.cs" />
|
||||
<Compile Include="Configuration\MetadataConfiguration.cs" />
|
||||
<Compile Include="Configuration\PeopleMetadataOptions.cs" />
|
||||
<Compile Include="Configuration\TheMovieDbOptions.cs" />
|
||||
<Compile Include="Configuration\TvdbOptions.cs" />
|
||||
<Compile Include="Configuration\XbmcMetadataOptions.cs" />
|
||||
<Compile Include="Configuration\SubtitlePlaybackMode.cs" />
|
||||
<Compile Include="Connect\ConnectAuthenticationExchangeResult.cs" />
|
||||
|
|
|
@ -85,5 +85,6 @@ namespace MediaBrowser.Model.Querying
|
|||
public const string GameSystem = "GameSystem";
|
||||
public const string IsFavoriteOrLiked = "IsFavoriteOrLiked";
|
||||
public const string DateLastContentAdded = "DateLastContentAdded";
|
||||
public const string SeriesDatePlayed = "SeriesDatePlayed";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Books
|
|||
{
|
||||
public class BookMetadataService : MetadataService<Book, BookInfo>
|
||||
{
|
||||
public BookMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void MergeData(MetadataResult<Book> source, MetadataResult<Book> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
||||
{
|
||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||
|
@ -25,5 +21,9 @@ namespace MediaBrowser.Providers.Books
|
|||
target.Item.SeriesName = source.Item.SeriesName;
|
||||
}
|
||||
}
|
||||
|
||||
public BookMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,6 @@ namespace MediaBrowser.Providers.BoxSets
|
|||
{
|
||||
public class BoxSetMetadataService : MetadataService<BoxSet, BoxSetInfo>
|
||||
{
|
||||
public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task<ItemUpdateType> BeforeSave(BoxSet item, bool isFullRefresh, ItemUpdateType currentUpdateType)
|
||||
{
|
||||
var updateType = await base.BeforeSave(item, isFullRefresh, currentUpdateType).ConfigureAwait(false);
|
||||
|
@ -54,5 +50,9 @@ namespace MediaBrowser.Providers.BoxSets
|
|||
targetItem.Shares = sourceItem.Shares;
|
||||
}
|
||||
}
|
||||
|
||||
public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.Channels
|
|||
{
|
||||
public class ChannelMetadataService : MetadataService<Channel, ItemLookupInfo>
|
||||
{
|
||||
public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void MergeData(MetadataResult<Channel> source, MetadataResult<Channel> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
||||
{
|
||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||
}
|
||||
|
||||
public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ namespace MediaBrowser.Providers.Chapters
|
|||
return _itemRepo.GetChapters(new Guid(itemId));
|
||||
}
|
||||
|
||||
public Task SaveChapters(string itemId, IEnumerable<ChapterInfo> chapters, CancellationToken cancellationToken)
|
||||
public Task SaveChapters(string itemId, List<ChapterInfo> chapters, CancellationToken cancellationToken)
|
||||
{
|
||||
return _itemRepo.SaveChapters(new Guid(itemId), chapters, cancellationToken);
|
||||
}
|
||||
|
|
|
@ -16,14 +16,13 @@ namespace MediaBrowser.Providers.Folders
|
|||
{
|
||||
public class CollectionFolderMetadataService : MetadataService<CollectionFolder, ItemLookupInfo>
|
||||
{
|
||||
public CollectionFolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager)
|
||||
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void MergeData(MetadataResult<CollectionFolder> source, MetadataResult<CollectionFolder> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
||||
{
|
||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||
}
|
||||
|
||||
public CollectionFolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
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
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "games.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "music.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "photos.png";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "tv.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "channels.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "livetv.png";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "movies.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "playlists.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "homevideos.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return urlPrefix + "musicvideos.jpg";
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//return urlPrefix + "collections.jpg";
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(viewType))
|
||||
{
|
||||
//return urlPrefix + "generic.jpg";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Default Image Provider"; }
|
||||
}
|
||||
|
||||
public bool Supports(IHasImages item)
|
||||
{
|
||||
var view = item as UserView;
|
||||
|
||||
if (view != null)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(GetImageUrl(view.ViewType));
|
||||
}
|
||||
|
||||
var folder = item as ICollectionFolder;
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(GetImageUrl(folder.CollectionType));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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, IDirectoryService directoryService)
|
||||
{
|
||||
return GetSupportedImages(item).Any(i => !item.HasImage(i));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,10 +12,6 @@ namespace MediaBrowser.Providers.Folders
|
|||
{
|
||||
public class FolderMetadataService : MetadataService<Folder, ItemLookupInfo>
|
||||
{
|
||||
public FolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
public override int Order
|
||||
{
|
||||
get
|
||||
|
@ -29,5 +25,9 @@ namespace MediaBrowser.Providers.Folders
|
|||
{
|
||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||
}
|
||||
|
||||
public FolderMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace MediaBrowser.Providers.Folders
|
|||
{
|
||||
public class UserViewMetadataService : MetadataService<UserView, ItemLookupInfo>
|
||||
{
|
||||
public UserViewMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void MergeData(MetadataResult<UserView> source, MetadataResult<UserView> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
||||
{
|
||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||
}
|
||||
|
||||
public UserViewMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user