add live tv collage
|
@ -200,24 +200,15 @@ namespace MediaBrowser.Api
|
|||
//}
|
||||
item.ProviderIds = request.ProviderIds;
|
||||
|
||||
var service = new ItemRefreshService(_libraryManager)
|
||||
var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions
|
||||
{
|
||||
Logger = Logger,
|
||||
Request = Request,
|
||||
ResultFactory = ResultFactory,
|
||||
SessionContext = SessionContext,
|
||||
AuthorizationContext = AuthorizationContext
|
||||
};
|
||||
|
||||
service.Post(new RefreshItem
|
||||
{
|
||||
Id = request.Id,
|
||||
MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
|
||||
ImageRefreshMode = ImageRefreshMode.FullRefresh,
|
||||
ReplaceAllMetadata = true,
|
||||
ReplaceAllImages = request.ReplaceAllImages,
|
||||
Recursive = true
|
||||
});
|
||||
ReplaceAllImages = request.ReplaceAllImages
|
||||
|
||||
}, CancellationToken.None);
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using ServiceStack;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Api
|
||||
{
|
||||
|
@ -40,41 +34,12 @@ namespace MediaBrowser.Api
|
|||
public class ItemRefreshService : BaseApiService
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
|
||||
public ItemRefreshService(ILibraryManager libraryManager)
|
||||
public ItemRefreshService(ILibraryManager libraryManager, IProviderManager providerManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
private async Task RefreshArtist(RefreshItem request, MusicArtist item)
|
||||
{
|
||||
var cancellationToken = CancellationToken.None;
|
||||
|
||||
var albums = _libraryManager.RootFolder
|
||||
.GetRecursiveChildren()
|
||||
.OfType<MusicAlbum>()
|
||||
.Where(i => i.HasAnyArtist(item.Name))
|
||||
.ToList();
|
||||
|
||||
var musicArtists = albums
|
||||
.Select(i => i.Parent)
|
||||
.OfType<MusicArtist>()
|
||||
.ToList();
|
||||
|
||||
var options = GetRefreshOptions(request);
|
||||
|
||||
var musicArtistRefreshTasks = musicArtists.Select(i => i.ValidateChildren(new Progress<double>(), cancellationToken, options, true));
|
||||
|
||||
await Task.WhenAll(musicArtistRefreshTasks).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error refreshing library", ex);
|
||||
}
|
||||
_providerManager = providerManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -85,68 +50,9 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
var item = _libraryManager.GetItemById(request.Id);
|
||||
|
||||
var task = item is MusicArtist ? RefreshArtist(request, (MusicArtist)item) : RefreshItem(request, item);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the item.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task RefreshItem(RefreshItem request, BaseItem item)
|
||||
{
|
||||
var options = GetRefreshOptions(request);
|
||||
|
||||
try
|
||||
{
|
||||
await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
if (item.IsFolder)
|
||||
{
|
||||
// Collection folders don't validate their children so we'll have to simulate that here
|
||||
var collectionFolder = item as CollectionFolder;
|
||||
|
||||
if (collectionFolder != null)
|
||||
{
|
||||
await RefreshCollectionFolderChildren(request, collectionFolder).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var folder = (Folder)item;
|
||||
|
||||
await folder.ValidateChildren(new Progress<double>(), CancellationToken.None, options, request.Recursive).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error refreshing library", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the collection folder children.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="collectionFolder">The collection folder.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task RefreshCollectionFolderChildren(RefreshItem request, CollectionFolder collectionFolder)
|
||||
{
|
||||
var options = GetRefreshOptions(request);
|
||||
|
||||
foreach (var child in collectionFolder.Children.ToList())
|
||||
{
|
||||
await child.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
if (child.IsFolder)
|
||||
{
|
||||
var folder = (Folder)child;
|
||||
|
||||
await folder.ValidateChildren(new Progress<double>(), CancellationToken.None, options, request.Recursive).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
_providerManager.QueueRefresh(item.Id, options);
|
||||
}
|
||||
|
||||
private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request)
|
||||
|
|
|
@ -751,7 +751,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
: options;
|
||||
|
||||
var result = await ProviderManager.RefreshMetadata(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
var result = await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
await ProviderManager.RefreshMetadata(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,15 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// <param name="options">The options.</param>
|
||||
void QueueRefresh(Guid itemId, MetadataRefreshOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the full item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RefreshFullItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the metadata.
|
||||
/// </summary>
|
||||
|
@ -31,7 +40,7 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// <param name="options">The options.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<ItemUpdateType> RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken);
|
||||
Task<ItemUpdateType> RefreshSingleItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the image.
|
||||
|
|
|
@ -288,9 +288,6 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Dlna\ContentFeatureBuilder.cs">
|
||||
<Link>Dlna\ContentFeatureBuilder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Dlna\DefaultLocalPlayer.cs">
|
||||
<Link>Dlna\DefaultLocalPlayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Dlna\DeviceIdentification.cs">
|
||||
<Link>Dlna\DeviceIdentification.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
public class DefaultLocalPlayer : ILocalPlayer
|
||||
{
|
||||
public bool CanAccessFile(string path)
|
||||
{
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
||||
public bool CanAccessDirectory(string path)
|
||||
{
|
||||
return Directory.Exists(path);
|
||||
}
|
||||
|
||||
public virtual bool CanAccessUrl(string url, bool requiresCustomRequestHeaders)
|
||||
{
|
||||
if (requiresCustomRequestHeaders)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CanAccessUrl(url);
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, TestResult> _results = new Dictionary<string, TestResult>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly object _resultLock = new object();
|
||||
|
||||
private bool CanAccessUrl(string url)
|
||||
{
|
||||
var key = GetHostFromUrl(url);
|
||||
lock (_resultLock)
|
||||
{
|
||||
TestResult result;
|
||||
if (_results.TryGetValue(url, out result))
|
||||
{
|
||||
var timespan = DateTime.UtcNow - result.Date;
|
||||
if (timespan <= TimeSpan.FromMinutes(3))
|
||||
{
|
||||
return result.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var canAccess = CanAccessUrlInternal(url);
|
||||
lock (_resultLock)
|
||||
{
|
||||
_results[key] = new TestResult
|
||||
{
|
||||
Success = canAccess,
|
||||
Date = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
return canAccess;
|
||||
}
|
||||
|
||||
private bool CanAccessUrlInternal(string url)
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.Timeout = 5000;
|
||||
request.Method = "HEAD";
|
||||
try
|
||||
{
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
return response.StatusCode == HttpStatusCode.OK;
|
||||
}
|
||||
}
|
||||
catch (WebException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void ClearUrlTestResultCache()
|
||||
{
|
||||
lock (_resultLock)
|
||||
{
|
||||
_results.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetHostFromUrl(string url)
|
||||
{
|
||||
var start = url.IndexOf("://", StringComparison.OrdinalIgnoreCase) + 3;
|
||||
var len = url.IndexOf('/', start) - start;
|
||||
return url.Substring(start, len);
|
||||
}
|
||||
|
||||
private class TestResult
|
||||
{
|
||||
public bool Success;
|
||||
public DateTime Date;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -124,7 +124,6 @@
|
|||
<Compile Include="Devices\LocalFileInfo.cs" />
|
||||
<Compile Include="Devices\DeviceInfo.cs" />
|
||||
<Compile Include="Devices\DevicesOptions.cs" />
|
||||
<Compile Include="Dlna\DefaultLocalPlayer.cs" />
|
||||
<Compile Include="Dlna\EncodingContext.cs" />
|
||||
<Compile Include="Dlna\ILocalPlayer.cs" />
|
||||
<Compile Include="Dlna\NullLocalPlayer.cs" />
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace MediaBrowser.Providers.Manager
|
|||
_externalIds = externalIds.OrderBy(i => i.Name).ToArray();
|
||||
}
|
||||
|
||||
public Task<ItemUpdateType> RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
public Task<ItemUpdateType> RefreshSingleItem(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var service = _metadataServices.FirstOrDefault(i => i.CanRefresh(item));
|
||||
|
||||
|
@ -897,23 +897,100 @@ namespace MediaBrowser.Providers.Manager
|
|||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var item = libraryManager.GetItemById(refreshItem.Item1);
|
||||
if (item != null)
|
||||
{
|
||||
await item.RefreshMetadata(refreshItem.Item2, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
try
|
||||
{
|
||||
var artist = item as MusicArtist;
|
||||
var task = artist == null
|
||||
? RefreshItem(item, refreshItem.Item2, CancellationToken.None)
|
||||
: RefreshArtist(artist, refreshItem.Item2);
|
||||
|
||||
await task.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error refreshing item", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StopRefreshTimer();
|
||||
}
|
||||
|
||||
private async Task RefreshItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
if (item.IsFolder)
|
||||
{
|
||||
// Collection folders don't validate their children so we'll have to simulate that here
|
||||
var collectionFolder = item as CollectionFolder;
|
||||
|
||||
if (collectionFolder != null)
|
||||
{
|
||||
await RefreshCollectionFolderChildren(options, collectionFolder).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var folder = (Folder)item;
|
||||
|
||||
await folder.ValidateChildren(new Progress<double>(), cancellationToken, options).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshCollectionFolderChildren(MetadataRefreshOptions options, CollectionFolder collectionFolder)
|
||||
{
|
||||
foreach (var child in collectionFolder.Children.ToList())
|
||||
{
|
||||
await child.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
if (child.IsFolder)
|
||||
{
|
||||
var folder = (Folder)child;
|
||||
|
||||
await folder.ValidateChildren(new Progress<double>(), CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshArtist(MusicArtist item, MetadataRefreshOptions options)
|
||||
{
|
||||
var cancellationToken = CancellationToken.None;
|
||||
|
||||
var albums = _libraryManagerFactory().RootFolder
|
||||
.GetRecursiveChildren()
|
||||
.OfType<MusicAlbum>()
|
||||
.Where(i => i.HasAnyArtist(item.Name))
|
||||
.ToList();
|
||||
|
||||
var musicArtists = albums
|
||||
.Select(i => i.Parent)
|
||||
.OfType<MusicArtist>()
|
||||
.ToList();
|
||||
|
||||
var musicArtistRefreshTasks = musicArtists.Select(i => i.ValidateChildren(new Progress<double>(), cancellationToken, options, true));
|
||||
|
||||
await Task.WhenAll(musicArtistRefreshTasks).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error refreshing library", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Task RefreshFullItem(IHasMetadata item, MetadataRefreshOptions options,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return RefreshItem((BaseItem)item, options, cancellationToken);
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
@ -1673,7 +1673,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
throw new ArgumentNullException("viewType");
|
||||
}
|
||||
|
||||
var id = GetNewItemId("23_namedview_" + name + user.Id.ToString("N") + (parentId ?? string.Empty), typeof(UserView));
|
||||
var id = GetNewItemId("27_namedview_" + name + user.Id.ToString("N") + (parentId ?? string.Empty), typeof(UserView));
|
||||
|
||||
var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
|
||||
|
||||
|
|
|
@ -130,7 +130,8 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId))
|
||||
{
|
||||
list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false));
|
||||
//list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false));
|
||||
list.Add(await GetUserView(CollectionType.LiveTv, string.Empty, user, cancellationToken).ConfigureAwait(false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@
|
|||
<Compile Include="Localization\LocalizationManager.cs" />
|
||||
<Compile Include="Logging\PatternsLogger.cs" />
|
||||
<Compile Include="MediaEncoder\EncodingManager.cs" />
|
||||
<Compile Include="Photos\DynamicImageProvider.cs" />
|
||||
<Compile Include="UserViews\DynamicImageProvider.cs" />
|
||||
<Compile Include="News\NewsEntryPoint.cs" />
|
||||
<Compile Include="News\NewsService.cs" />
|
||||
<Compile Include="Notifications\CoreNotificationTypes.cs" />
|
||||
|
@ -248,7 +248,7 @@
|
|||
<Compile Include="Persistence\TypeMapper.cs" />
|
||||
<Compile Include="Photos\BaseDynamicImageProvider.cs" />
|
||||
<Compile Include="Photos\DynamicImageHelpers.cs" />
|
||||
<Compile Include="Photos\StripCollageBuilder.cs" />
|
||||
<Compile Include="UserViews\StripCollageBuilder.cs" />
|
||||
<Compile Include="Playlists\ManualPlaylistsFolder.cs" />
|
||||
<Compile Include="Photos\PhotoAlbumImageProvider.cs" />
|
||||
<Compile Include="Playlists\PlaylistImageProvider.cs" />
|
||||
|
@ -514,6 +514,14 @@
|
|||
<Link>swagger-ui\swagger-ui.min.js</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<EmbeddedResource Include="UserViews\livetv\1.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\2.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\3.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\4.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\5.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\6.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\7.jpg" />
|
||||
<EmbeddedResource Include="UserViews\livetv\8.jpg" />
|
||||
<EmbeddedResource Include="Localization\iso6392.txt" />
|
||||
<EmbeddedResource Include="Localization\Ratings\be.txt" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
@ -6,6 +7,7 @@ using MediaBrowser.Controller.Entities.TV;
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Server.Implementations.Photos;
|
||||
using MoreLinq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -13,7 +15,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Photos
|
||||
namespace MediaBrowser.Server.Implementations.UserViews
|
||||
{
|
||||
public class DynamicImageProvider : BaseDynamicImageProvider<UserView>
|
||||
{
|
||||
|
@ -54,6 +56,11 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
if (string.Equals(view.ViewType, SpecialFolder.GameGenre, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var list = new List<BaseItem>();
|
||||
|
@ -219,7 +226,8 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
CollectionType.Music,
|
||||
CollectionType.BoxSets,
|
||||
CollectionType.Playlists,
|
||||
CollectionType.Channels
|
||||
CollectionType.Channels,
|
||||
CollectionType.LiveTv
|
||||
};
|
||||
|
||||
return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty);
|
||||
|
@ -230,18 +238,45 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
var view = (UserView)item;
|
||||
if (imageType == ImageType.Primary && IsUsingCollectionStrip(view))
|
||||
{
|
||||
var stream = new StripCollageBuilder(ApplicationPaths).BuildThumbCollage(GetStripCollageImagePaths(itemsWithImages), item.Name, 960, 540);
|
||||
var stream = new StripCollageBuilder(ApplicationPaths).BuildThumbCollage(GetStripCollageImagePaths(itemsWithImages, view.ViewType), item.Name, 960, 540);
|
||||
return Task.FromResult(stream);
|
||||
}
|
||||
|
||||
return base.CreateImageAsync(item, itemsWithImages, imageType, imageIndex);
|
||||
}
|
||||
|
||||
private IEnumerable<String> GetStripCollageImagePaths(IEnumerable<BaseItem> items)
|
||||
private IEnumerable<String> GetStripCollageImagePaths(IEnumerable<BaseItem> items, string viewType)
|
||||
{
|
||||
if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var list = new List<string>();
|
||||
for (int i = 1; i <= 8; i++)
|
||||
{
|
||||
list.Add(ExtractLiveTvResource(i.ToString(CultureInfo.InvariantCulture), ApplicationPaths));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
return items
|
||||
.Select(i => i.GetImagePath(ImageType.Primary) ?? i.GetImagePath(ImageType.Thumb))
|
||||
.Where(i => !string.IsNullOrWhiteSpace(i));
|
||||
}
|
||||
|
||||
private string ExtractLiveTvResource(string name, IApplicationPaths paths)
|
||||
{
|
||||
var namespacePath = GetType().Namespace + ".livetv." + name + ".jpg";
|
||||
var tempPath = Path.Combine(paths.TempDirectory, Guid.NewGuid().ToString("N") + ".jpg");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
|
||||
|
||||
using (var stream = GetType().Assembly.GetManifestResourceStream(namespacePath))
|
||||
{
|
||||
using (var fileStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
stream.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
using ImageMagickSharp;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Server.Implementations.Drawing;
|
||||
using MediaBrowser.Server.Implementations.Photos;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Photos
|
||||
namespace MediaBrowser.Server.Implementations.UserViews
|
||||
{
|
||||
public class StripCollageBuilder
|
||||
{
|
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/1.jpg
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/2.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/3.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/4.jpg
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/5.jpg
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/6.jpg
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/7.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
MediaBrowser.Server.Implementations/UserViews/livetv/8.jpg
Normal file
After Width: | Height: | Size: 66 KiB |