commit
73688e3fcc
|
@ -34,7 +34,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\ImageMagickSharp.1.0.0.14\lib\net45\ImageMagickSharp.dll</HintPath>
|
||||
<HintPath>..\packages\ImageMagickSharp.1.0.0.15\lib\net45\ImageMagickSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -65,9 +65,6 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ImageMagick\UnplayedCountIndicator.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ImageMagick\fonts\MontserratLight.otf" />
|
||||
<EmbeddedResource Include="ImageMagick\fonts\robotoregular.ttf" />
|
||||
|
@ -87,6 +84,9 @@
|
|||
<Name>MediaBrowser.Model</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ImageMagickSharp" version="1.0.0.14" targetFramework="net45" />
|
||||
<package id="ImageMagickSharp" version="1.0.0.15" targetFramework="net45" />
|
||||
</packages>
|
|
@ -156,6 +156,7 @@
|
|||
<Compile Include="UserLibrary\PlaystateService.cs" />
|
||||
<Compile Include="UserLibrary\StudiosService.cs" />
|
||||
<Compile Include="UserLibrary\UserLibraryService.cs" />
|
||||
<Compile Include="UserLibrary\UserViewsService.cs" />
|
||||
<Compile Include="UserLibrary\YearsService.cs" />
|
||||
<Compile Include="UserService.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -38,20 +38,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Users/{UserId}/Views", "GET")]
|
||||
public class GetUserViews : IReturn<QueryResult<BaseItemDto>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user id.
|
||||
/// </summary>
|
||||
/// <value>The user id.</value>
|
||||
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[ApiMember(Name = "IncludeExternalContent", Description = "Whether or not to include external views such as channels or live tv", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "POST")]
|
||||
public bool? IncludeExternalContent { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class GetItem
|
||||
/// </summary>
|
||||
|
@ -345,37 +331,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
return ToOptimizedResult(dtos.ToList());
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetUserViews request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var query = new UserViewQuery
|
||||
{
|
||||
UserId = request.UserId
|
||||
|
||||
};
|
||||
|
||||
if (request.IncludeExternalContent.HasValue)
|
||||
{
|
||||
query.IncludeExternalContent = request.IncludeExternalContent.Value;
|
||||
}
|
||||
|
||||
var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var dtos = folders.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
|
||||
.ToArray();
|
||||
|
||||
var result = new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = dtos,
|
||||
TotalRecordCount = dtos.Length
|
||||
};
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
private List<BaseItemDto> GetAsync(GetSpecialFeatures request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
|
121
MediaBrowser.Api/UserLibrary/UserViewsService.cs
Normal file
121
MediaBrowser.Api/UserLibrary/UserViewsService.cs
Normal file
|
@ -0,0 +1,121 @@
|
|||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Library;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using ServiceStack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Api.UserLibrary
|
||||
{
|
||||
[Route("/Users/{UserId}/Views", "GET")]
|
||||
public class GetUserViews : IReturn<QueryResult<BaseItemDto>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user id.
|
||||
/// </summary>
|
||||
/// <value>The user id.</value>
|
||||
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[ApiMember(Name = "IncludeExternalContent", Description = "Whether or not to include external views such as channels or live tv", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "POST")]
|
||||
public bool? IncludeExternalContent { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Users/{UserId}/SpecialViewOptions", "GET")]
|
||||
public class GetSpecialViewOptions : IReturn<List<SpecialViewOption>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user id.
|
||||
/// </summary>
|
||||
/// <value>The user id.</value>
|
||||
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string UserId { get; set; }
|
||||
}
|
||||
|
||||
public class UserViewsService : BaseApiService
|
||||
{
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserViewManager _userViewManager;
|
||||
private readonly IDtoService _dtoService;
|
||||
|
||||
public UserViewsService(IUserManager userManager, IUserViewManager userViewManager, IDtoService dtoService)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_userViewManager = userViewManager;
|
||||
_dtoService = dtoService;
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetUserViews request)
|
||||
{
|
||||
var query = new UserViewQuery
|
||||
{
|
||||
UserId = request.UserId
|
||||
};
|
||||
|
||||
if (request.IncludeExternalContent.HasValue)
|
||||
{
|
||||
query.IncludeExternalContent = request.IncludeExternalContent.Value;
|
||||
}
|
||||
|
||||
var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var dtos = folders.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user))
|
||||
.ToArray();
|
||||
|
||||
var result = new QueryResult<BaseItemDto>
|
||||
{
|
||||
Items = dtos,
|
||||
TotalRecordCount = dtos.Length
|
||||
};
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetSpecialViewOptions request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var views = user.RootFolder
|
||||
.GetChildren(user, true)
|
||||
.OfType<CollectionFolder>()
|
||||
.Where(i => IsEligibleForSpecialView(i))
|
||||
.ToList();
|
||||
|
||||
var list = views
|
||||
.Select(i => new SpecialViewOption
|
||||
{
|
||||
Name = i.Name,
|
||||
Id = i.Id.ToString("N")
|
||||
|
||||
})
|
||||
.OrderBy(i => i.Name)
|
||||
.ToList();
|
||||
|
||||
return ToOptimizedResult(list);
|
||||
}
|
||||
|
||||
private bool IsEligibleForSpecialView(CollectionFolder view)
|
||||
{
|
||||
var types = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Games, CollectionType.Music };
|
||||
|
||||
return types.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
class SpecialViewOption
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
|
@ -1894,12 +1894,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
return video.RefreshMetadata(newOptions, cancellationToken);
|
||||
}
|
||||
|
||||
public string GetEtag()
|
||||
public string GetEtag(User user)
|
||||
{
|
||||
return string.Join("|", GetEtagValues().ToArray()).GetMD5().ToString("N");
|
||||
return string.Join("|", GetEtagValues(user).ToArray()).GetMD5().ToString("N");
|
||||
}
|
||||
|
||||
protected virtual List<string> GetEtagValues()
|
||||
protected virtual List<string> GetEtagValues(User user)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
@ -9,6 +10,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
string CollectionType { get; }
|
||||
string Path { get; }
|
||||
string Name { get; }
|
||||
Guid Id { get; }
|
||||
IEnumerable<string> PhysicalLocations { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,7 +247,16 @@ namespace MediaBrowser.Controller.Entities
|
|||
return GetFavoriteSongs(queryParent, user, query);
|
||||
|
||||
default:
|
||||
return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), queryParent, query);
|
||||
{
|
||||
if (queryParent is UserView)
|
||||
{
|
||||
return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), queryParent, query);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetResult(queryParent.GetChildren(user, true), queryParent, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,40 +2,78 @@
|
|||
using MoreLinq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public static class NameExtensions
|
||||
{
|
||||
public static bool AreEqual(string name1, string name2)
|
||||
public static bool AreEqual(string x, string y)
|
||||
{
|
||||
name1 = NormalizeForComparison(name1);
|
||||
name2 = NormalizeForComparison(name2);
|
||||
if (string.IsNullOrWhiteSpace(x) && string.IsNullOrWhiteSpace(y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return string.Equals(name1, name2, StringComparison.OrdinalIgnoreCase);
|
||||
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) == 0;
|
||||
}
|
||||
|
||||
public static bool EqualsAny(IEnumerable<string> names, string name)
|
||||
public static bool EqualsAny(IEnumerable<string> names, string x)
|
||||
{
|
||||
name = NormalizeForComparison(name);
|
||||
x = NormalizeForComparison(x);
|
||||
|
||||
return names.Any(i => string.Equals(NormalizeForComparison(i), name, StringComparison.OrdinalIgnoreCase));
|
||||
return names.Any(y => string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) == 0);
|
||||
}
|
||||
|
||||
private static string NormalizeForComparison(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
if (name == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return name;
|
||||
//return name.RemoveDiacritics();
|
||||
}
|
||||
|
||||
private static string RemoveDiacritics(string name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//return name;
|
||||
return name.RemoveDiacritics();
|
||||
}
|
||||
|
||||
public static IEnumerable<string> DistinctNames(this IEnumerable<string> names)
|
||||
{
|
||||
return names.DistinctBy(NormalizeForComparison, StringComparer.OrdinalIgnoreCase);
|
||||
return names.DistinctBy(RemoveDiacritics, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
class TextComparer : IComparer<string>, IEqualityComparer<string>
|
||||
{
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(x) && string.IsNullOrWhiteSpace(y))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace);
|
||||
}
|
||||
|
||||
public bool Equals(string x, string y)
|
||||
{
|
||||
return Compare(x, y) == 0;
|
||||
}
|
||||
|
||||
public int GetHashCode(string obj)
|
||||
{
|
||||
return (obj ?? string.Empty).GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>IEnumerable{Guid}.</returns>
|
||||
IEnumerable<Guid> GetItemsOfType(Type type);
|
||||
IEnumerable<Guid> GetItemIdsOfType(Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the children.
|
||||
|
@ -133,6 +133,13 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveMediaStreams(Guid id, IEnumerable<MediaStream> streams, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the items of.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>IEnumerable<BaseItem>.</returns>
|
||||
IEnumerable<BaseItem> GetItemsOfType(Type type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -489,32 +489,37 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var processWrapper = new ProcessWrapper(process, this);
|
||||
|
||||
StartProcess(processWrapper);
|
||||
bool ranToCompletion;
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
|
||||
try
|
||||
{
|
||||
StartProcess(processWrapper);
|
||||
|
||||
#pragma warning disable 4014
|
||||
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
|
||||
process.StandardOutput.BaseStream.CopyToAsync(memoryStream);
|
||||
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
|
||||
process.StandardOutput.BaseStream.CopyToAsync(memoryStream);
|
||||
#pragma warning restore 4014
|
||||
|
||||
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
|
||||
process.BeginErrorReadLine();
|
||||
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
var ranToCompletion = process.WaitForExit(10000);
|
||||
ranToCompletion = process.WaitForExit(10000);
|
||||
|
||||
if (!ranToCompletion)
|
||||
if (!ranToCompletion)
|
||||
{
|
||||
StopProcess(processWrapper, 1000, false);
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
StopProcess(processWrapper, 1000, false);
|
||||
resourcePool.Release();
|
||||
}
|
||||
|
||||
resourcePool.Release();
|
||||
|
||||
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
|
||||
|
||||
process.Dispose();
|
||||
|
||||
if (exitCode == -1 || memoryStream.Length == 0)
|
||||
{
|
||||
memoryStream.Dispose();
|
||||
|
@ -594,7 +599,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
|
||||
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
bool ranToCompletion;
|
||||
bool ranToCompletion = false;
|
||||
|
||||
var processWrapper = new ProcessWrapper(process, this);
|
||||
|
||||
|
@ -609,19 +614,23 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
bool isResponsive = true;
|
||||
int lastCount = 0;
|
||||
|
||||
while (isResponsive && !process.WaitForExit(30000))
|
||||
while (isResponsive)
|
||||
{
|
||||
if (process.WaitForExit(30000))
|
||||
{
|
||||
ranToCompletion = true;
|
||||
break;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
int jpegCount = Directory.GetFiles(targetDirectory)
|
||||
var jpegCount = Directory.GetFiles(targetDirectory)
|
||||
.Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
isResponsive = (jpegCount > lastCount);
|
||||
lastCount = jpegCount;
|
||||
}
|
||||
|
||||
ranToCompletion = process.HasExited;
|
||||
|
||||
if (!ranToCompletion)
|
||||
{
|
||||
StopProcess(processWrapper, 1000, false);
|
||||
|
@ -634,8 +643,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
|
||||
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
|
||||
|
||||
process.Dispose();
|
||||
|
||||
if (exitCode == -1)
|
||||
{
|
||||
var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument);
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// </summary>
|
||||
/// <value><c>true</c> if [enable user specific user views]; otherwise, <c>false</c>.</value>
|
||||
public bool EnableUserSpecificUserViews { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value pointing to the file system where the ssl certiifcate is located..
|
||||
/// </summary>
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
public bool EnableCinemaMode { get; set; }
|
||||
|
||||
public string[] LatestItemsExcludes { get; set; }
|
||||
public string[] PlainFolderViews { get; set; }
|
||||
|
||||
public bool HidePlayedInLatest { get; set; }
|
||||
|
||||
|
@ -62,6 +63,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
DisplayChannelsWithinViews = new string[] { };
|
||||
|
||||
ExcludeFoldersFromGrouping = new string[] { };
|
||||
PlainFolderViews = new string[] { };
|
||||
DisplayCollectionsView = true;
|
||||
|
||||
IncludeTrailersInSuggestions = true;
|
||||
|
|
|
@ -1,153 +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.FolderImages
|
||||
{
|
||||
public class DefaultImageProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder
|
||||
{
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public DefaultImageProvider(IHttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public IEnumerable<ImageType> GetSupportedImages(IHasImages item)
|
||||
{
|
||||
return new List<ImageType>
|
||||
{
|
||||
ImageType.Primary,
|
||||
ImageType.Thumb
|
||||
};
|
||||
}
|
||||
|
||||
public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken)
|
||||
{
|
||||
var view = item as UserView;
|
||||
|
||||
if (view != null)
|
||||
{
|
||||
return GetImages(view.ViewType, view.ParentId != Guid.Empty, cancellationToken);
|
||||
}
|
||||
|
||||
var folder = (ICollectionFolder)item;
|
||||
return GetImages(folder.CollectionType, false, cancellationToken);
|
||||
}
|
||||
|
||||
private Task<IEnumerable<RemoteImageInfo>> GetImages(string viewType, bool isSubView, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = GetImageUrl(viewType, isSubView);
|
||||
var list = new List<RemoteImageInfo>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
list.AddRange(new List<RemoteImageInfo>
|
||||
{
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = url,
|
||||
Type = ImageType.Primary
|
||||
},
|
||||
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = url,
|
||||
Type = ImageType.Thumb
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Task.FromResult<IEnumerable<RemoteImageInfo>>(list);
|
||||
}
|
||||
|
||||
private string GetImageUrl(string viewType, bool isSubView)
|
||||
{
|
||||
const string urlPrefix = "https://raw.githubusercontent.com/MediaBrowser/MediaBrowser.Resources/master/images/folders/";
|
||||
|
||||
if (string.Equals(viewType, CollectionType.Books, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (string.Equals(viewType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isSubView)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return urlPrefix + "generic.png";
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Default Image Provider"; }
|
||||
}
|
||||
|
||||
public bool Supports(IHasImages item)
|
||||
{
|
||||
return item is ICollectionFolder || item is UserView;
|
||||
}
|
||||
|
||||
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpClient.GetResponse(new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = url,
|
||||
ResourcePool = GenreImageProvider.ImageDownloadResourcePool
|
||||
});
|
||||
}
|
||||
|
||||
public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService)
|
||||
{
|
||||
return GetSupportedImages(item).Any(i => !item.HasImage(i));
|
||||
}
|
||||
|
||||
public int Order
|
||||
{
|
||||
get
|
||||
{
|
||||
// Run after the dynamic image provider
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -83,7 +83,6 @@
|
|||
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
|
||||
<Compile Include="Channels\ChannelMetadataService.cs" />
|
||||
<Compile Include="Chapters\ChapterManager.cs" />
|
||||
<Compile Include="FolderImages\DefaultImageProvider.cs" />
|
||||
<Compile Include="Folders\FolderMetadataService.cs" />
|
||||
<Compile Include="Channels\AudioChannelItemMetadataService.cs" />
|
||||
<Compile Include="Folders\UserViewMetadataService.cs" />
|
||||
|
|
|
@ -6,6 +6,7 @@ using MediaBrowser.Controller.Providers;
|
|||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -20,13 +21,15 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
private readonly IMediaEncoder _mediaEncoder;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, ILibraryManager libraryManager)
|
||||
public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, ILibraryManager libraryManager, ILogger logger)
|
||||
{
|
||||
_isoManager = isoManager;
|
||||
_mediaEncoder = mediaEncoder;
|
||||
_config = config;
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -74,6 +77,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
// Can't extract if we didn't find a video stream in the file
|
||||
if (!video.DefaultVideoStreamIndex.HasValue)
|
||||
{
|
||||
_logger.Debug("Skipping image extraction due to missing DefaultVideoStreamIndex for {0}.", video.Path ?? string.Empty);
|
||||
return Task.FromResult(new DynamicImageResponse { HasImage = false });
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,10 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
: item.CanDownload(user);
|
||||
}
|
||||
|
||||
|
||||
if (fields.Contains(ItemFields.Etag))
|
||||
{
|
||||
dto.Etag = item.GetEtag(user);
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
|
|
@ -1678,11 +1678,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(viewType))
|
||||
{
|
||||
throw new ArgumentNullException("viewType");
|
||||
}
|
||||
|
||||
var id = GetNewItemId("37_namedview_" + name + user.Id.ToString("N") + (parentId ?? string.Empty), typeof(UserView));
|
||||
|
||||
var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
|
||||
|
@ -1716,6 +1711,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
isNew = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
item.ViewType = viewType;
|
||||
await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var refresh = isNew || (DateTime.UtcNow - item.DateLastSaved).TotalHours >= 12;
|
||||
|
||||
if (refresh)
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
.ToList();
|
||||
|
||||
var excludeFolderIds = user.Configuration.ExcludeFoldersFromGrouping.Select(i => new Guid(i)).ToList();
|
||||
var plainFolderIds = user.Configuration.PlainFolderViews.Select(i => new Guid(i)).ToList();
|
||||
|
||||
var standaloneFolders = folders
|
||||
.Where(i => UserView.IsExcludedFromGrouping(i) || excludeFolderIds.Contains(i.Id))
|
||||
|
@ -72,13 +73,17 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
var collectionFolder = folder as ICollectionFolder;
|
||||
var folderViewType = collectionFolder == null ? null : collectionFolder.CollectionType;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(folderViewType))
|
||||
if (plainFolderIds.Contains(folder.Id))
|
||||
{
|
||||
list.Add(folder);
|
||||
list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, false, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(folderViewType))
|
||||
{
|
||||
list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, true, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,44 +92,57 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
list.AddRange(standaloneFolders);
|
||||
}
|
||||
|
||||
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) ||
|
||||
foldersWithViewTypes.Any(i => string.IsNullOrWhiteSpace(i.CollectionType)))
|
||||
var parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType))
|
||||
.ToList();
|
||||
|
||||
if (parents.Count > 0)
|
||||
{
|
||||
list.Add(await GetUserView(CollectionType.TvShows, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(parents, CollectionType.TvShows, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase)) ||
|
||||
foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)))
|
||||
parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase) || string.Equals(i.CollectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType))
|
||||
.ToList();
|
||||
|
||||
if (parents.Count > 0)
|
||||
{
|
||||
list.Add(await GetUserView(CollectionType.Music, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(parents, CollectionType.Music, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) ||
|
||||
foldersWithViewTypes.Any(i => string.IsNullOrWhiteSpace(i.CollectionType)))
|
||||
parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(i.CollectionType))
|
||||
.ToList();
|
||||
|
||||
if (parents.Count > 0)
|
||||
{
|
||||
list.Add(await GetUserView(CollectionType.Movies, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(parents, CollectionType.Movies, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase)))
|
||||
parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
if (parents.Count > 0)
|
||||
{
|
||||
list.Add(await GetUserView(CollectionType.Games, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(parents, CollectionType.Games, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)))
|
||||
parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
if (parents.Count > 0)
|
||||
{
|
||||
//list.Add(_collectionManager.GetCollectionsFolder(user.Id.ToString("N")));
|
||||
list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(parents, CollectionType.BoxSets, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)))
|
||||
parents = foldersWithViewTypes.Where(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
if (parents.Count > 0)
|
||||
{
|
||||
//list.Add(_playlists.GetPlaylistsFolder(user.Id.ToString("N")));
|
||||
list.Add(await GetUserView(CollectionType.Playlists, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(parents, CollectionType.Playlists, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (user.Configuration.DisplayFoldersView)
|
||||
{
|
||||
list.Add(await GetUserView(CollectionType.Folders, "zz_" + CollectionType.Folders, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(new List<ICollectionFolder>(), CollectionType.Folders, "zz_" + CollectionType.Folders, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (query.IncludeExternalContent)
|
||||
|
@ -151,7 +169,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId))
|
||||
{
|
||||
//list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(CollectionType.LiveTv, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(new List<ICollectionFolder>(), CollectionType.LiveTv, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,16 +200,42 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
return GetUserSubView(name, parentId, type, user, sortName, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<UserView> GetUserView(string type, string sortName, User user, CancellationToken cancellationToken)
|
||||
public async Task<UserView> GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, CancellationToken cancellationToken)
|
||||
{
|
||||
var name = _localizationManager.GetLocalizedString("ViewType" + type);
|
||||
if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var name = parents[0].Name;
|
||||
var parentId = parents[0].Id;
|
||||
|
||||
return _libraryManager.GetNamedView(user, name, type, sortName, cancellationToken);
|
||||
var enableRichView = !user.Configuration.PlainFolderViews.Contains(parentId.ToString("N"), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (_config.Configuration.EnableUserSpecificUserViews)
|
||||
{
|
||||
viewType = enableRichView ? viewType : null;
|
||||
var view = await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (view.ParentId != parentId)
|
||||
{
|
||||
view.ParentId = parentId;
|
||||
await view.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
viewType = enableRichView ? viewType : CollectionType.Folders;
|
||||
return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = _localizationManager.GetLocalizedString("ViewType" + viewType);
|
||||
|
||||
return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<UserView> GetUserView(Guid parentId, string name, string type, string sortName, User user, CancellationToken cancellationToken)
|
||||
public Task<UserView> GetUserView(Guid parentId, string name, string viewType, bool enableRichView, string sortName, User user, CancellationToken cancellationToken)
|
||||
{
|
||||
return _libraryManager.GetNamedView(user, name, parentId.ToString("N"), type, sortName, cancellationToken);
|
||||
return _libraryManager.GetNamedView(user, name, parentId.ToString("N"), viewType, sortName, cancellationToken);
|
||||
}
|
||||
|
||||
public List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request)
|
||||
|
@ -317,7 +361,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
.RootFolder
|
||||
.GetRecursiveChildren(filter);
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<BaseItem> GetItemsConfiguredForLatest(User user, Func<BaseItem, bool> filter)
|
||||
{
|
||||
// Avoid implicitly captured closure
|
||||
|
|
|
@ -54,11 +54,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
new ConcurrentDictionary<string, LiveStreamData>();
|
||||
|
||||
private List<Guid> _channelIdList = new List<Guid>();
|
||||
private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>();
|
||||
private Dictionary<Guid, LiveTvProgram> _programs;
|
||||
private readonly ConcurrentDictionary<Guid, bool> _refreshedPrograms = new ConcurrentDictionary<Guid, bool>();
|
||||
|
||||
private readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager)
|
||||
{
|
||||
_config = config;
|
||||
|
@ -109,6 +107,37 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||
}
|
||||
|
||||
private readonly object _programsDataLock = new object();
|
||||
private Dictionary<Guid, LiveTvProgram> GetProgramsDictionary()
|
||||
{
|
||||
if (_programs == null)
|
||||
{
|
||||
lock (_programsDataLock)
|
||||
{
|
||||
if (_programs == null)
|
||||
{
|
||||
var dict = new Dictionary<Guid, LiveTvProgram>();
|
||||
|
||||
foreach (var item in _itemRepo.GetItemsOfType(typeof (LiveTvProgram))
|
||||
.Cast<LiveTvProgram>()
|
||||
.ToList())
|
||||
{
|
||||
dict[item.Id] = item;
|
||||
}
|
||||
|
||||
_programs = dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _programs;
|
||||
}
|
||||
|
||||
private IEnumerable<LiveTvProgram> GetPrograms()
|
||||
{
|
||||
return GetProgramsDictionary().Values;
|
||||
}
|
||||
|
||||
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
@ -260,7 +289,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
LiveTvProgram obj = null;
|
||||
|
||||
_programs.TryGetValue(guid, out obj);
|
||||
GetProgramsDictionary().TryGetValue(guid, out obj);
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
|
@ -597,7 +626,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
item.ProductionYear = info.ProductionYear;
|
||||
item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate;
|
||||
|
||||
|
||||
await item.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return item;
|
||||
|
@ -691,7 +720,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
IEnumerable<LiveTvProgram> programs = _programs.Values;
|
||||
IEnumerable<LiveTvProgram> programs = GetPrograms();
|
||||
|
||||
if (query.MinEndDate.HasValue)
|
||||
{
|
||||
|
@ -806,7 +835,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
IEnumerable<LiveTvProgram> programs = _programs.Values;
|
||||
IEnumerable<LiveTvProgram> programs = GetPrograms();
|
||||
|
||||
var user = _userManager.GetUserById(query.UserId);
|
||||
|
||||
|
@ -995,24 +1024,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
innerProgress.RegisterAction(p => progress.Report(p * .9));
|
||||
await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
var innerProgress = new ActionableProgress<double>();
|
||||
innerProgress.RegisterAction(p => progress.Report(p * .9));
|
||||
await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false);
|
||||
innerProgress = new ActionableProgress<double>();
|
||||
innerProgress.RegisterAction(p => progress.Report(90 + (p * .1)));
|
||||
await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
innerProgress = new ActionableProgress<double>();
|
||||
innerProgress.RegisterAction(p => progress.Report(90 + (p * .1)));
|
||||
await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
RefreshIfNeeded(_programs.Values.Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList());
|
||||
}
|
||||
finally
|
||||
{
|
||||
_refreshSemaphore.Release();
|
||||
}
|
||||
RefreshIfNeeded(GetPrograms().Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList());
|
||||
}
|
||||
|
||||
private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
|
@ -1136,7 +1156,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
progress.Report(80 * percent + 10);
|
||||
}
|
||||
|
||||
_programs = programs.ToDictionary(i => i.Id);
|
||||
lock (_programsDataLock)
|
||||
{
|
||||
_programs = programs.ToDictionary(i => i.Id);
|
||||
}
|
||||
|
||||
_refreshedPrograms.Clear();
|
||||
progress.Report(90);
|
||||
|
||||
|
@ -1147,28 +1171,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
progress.Report(100);
|
||||
}
|
||||
|
||||
public async Task CleanDatabase(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
await DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_refreshSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private Task CleanDatabaseInternal(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
return DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken);
|
||||
return DeleteOldPrograms(GetProgramsDictionary().Keys.ToList(), progress, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task DeleteOldPrograms(List<Guid> currentIdList, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = _itemRepo.GetItemsOfType(typeof(LiveTvProgram)).ToList();
|
||||
var list = _itemRepo.GetItemIdsOfType(typeof(LiveTvProgram)).ToList();
|
||||
|
||||
var numComplete = 0;
|
||||
|
||||
|
@ -1549,7 +1559,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var program = _programs.Values
|
||||
var program = GetPrograms()
|
||||
.Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(i => i.StartDate)
|
||||
.SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue))
|
||||
|
@ -1742,7 +1752,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
{
|
||||
var dtoOptions = new DtoOptions();
|
||||
dtoOptions.Fields.Remove(ItemFields.SyncInfo);
|
||||
|
||||
|
||||
var recordingResult = await GetRecordings(new RecordingQuery
|
||||
{
|
||||
UserId = query.UserId
|
||||
|
@ -1855,13 +1865,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public GuideInfo GetGuideInfo()
|
||||
{
|
||||
var programs = _programs.ToList();
|
||||
var programs = GetPrograms().OrderBy(i => i.StartDate).ToList();
|
||||
|
||||
var startDate = _programs.Count == 0 ? DateTime.MinValue :
|
||||
programs.Select(i => i.Value.StartDate).Min();
|
||||
var startDate = programs.Count == 0 ?
|
||||
DateTime.MinValue :
|
||||
programs[0].StartDate;
|
||||
|
||||
var endDate = programs.Count == 0 ? DateTime.MinValue :
|
||||
programs.Select(i => i.Value.StartDate).Max();
|
||||
var endDate = programs.Count == 0 ?
|
||||
DateTime.MinValue :
|
||||
programs[programs.Count - 1].StartDate;
|
||||
|
||||
return new GuideInfo
|
||||
{
|
||||
|
|
|
@ -1430,5 +1430,8 @@
|
|||
"ButtonMyPreferencesWelcomeNo": "No thanks, I'll do it later.",
|
||||
"MyPreferencesWelcomeMessage1": "We've presented your library in a way we think you'll enjoy. The appearance and grouping of content can be changed anytime by adjusting your preferences. Your preferences will apply to all Emby apps.",
|
||||
"MyPreferencesWelcomeMessage2": "Would you like to set your preferences now?",
|
||||
"ToAccessPreferencesHelp": "To access your preferences later, click your user icon in the top right header and select My Preferences."
|
||||
"ToAccessPreferencesHelp": "To access your preferences later, click your user icon in the top right header and select My Preferences.",
|
||||
"HeaderViewStyles": "View Styles",
|
||||
"LabelSelectViewStyles": "Enable rich presentations for:",
|
||||
"LabelSelectViewStylesHelp": "If enabled, views will be built with metadata to offer categories such as Suggestions, Latest, Genres, and more. If disabled, they'll be displayed with simple folders."
|
||||
}
|
||||
|
|
|
@ -522,7 +522,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Guid> GetItemsOfType(Type type)
|
||||
public IEnumerable<BaseItem> GetItemsOfType(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
|
@ -530,7 +530,37 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
}
|
||||
|
||||
CheckDisposed();
|
||||
|
||||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select type,data from TypedBaseItems where type = @type";
|
||||
|
||||
cmd.Parameters.Add(cmd, "@type", DbType.String).Value = type.FullName;
|
||||
|
||||
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var item = GetItem(reader);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Guid> GetItemIdsOfType(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException("type");
|
||||
}
|
||||
|
||||
CheckDisposed();
|
||||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select guid from TypedBaseItems where type = @type";
|
||||
|
|
|
@ -205,7 +205,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
|||
{
|
||||
Condition = ProfileConditionType.LessThanEqual,
|
||||
Property = ProfileConditionValue.AudioChannels,
|
||||
Value = "5",
|
||||
Value = "6",
|
||||
IsRequired = false
|
||||
},
|
||||
new ProfileCondition
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\ImageMagickSharp.1.0.0.14\lib\net45\ImageMagickSharp.dll</HintPath>
|
||||
<HintPath>..\packages\ImageMagickSharp.1.0.0.15\lib\net45\ImageMagickSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MediaBrowser.IsoMounter">
|
||||
<HintPath>..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll</HintPath>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ImageMagickSharp" version="1.0.0.14" targetFramework="net45" />
|
||||
<package id="ImageMagickSharp" version="1.0.0.15" targetFramework="net45" />
|
||||
<package id="MediaBrowser.IsoMounting" version="3.0.69" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.Core" version="1.0.94.0" targetFramework="net45" />
|
||||
</packages>
|
|
@ -1,4 +1,4 @@
|
|||
using System.Reflection;
|
||||
|
||||
//[assembly: AssemblyVersion("3.0.*")]
|
||||
[assembly: AssemblyVersion("3.0.5582.1")]
|
||||
[assembly: AssemblyVersion("3.0.5582.2")]
|
||||
|
|
Loading…
Reference in New Issue
Block a user