add more methods to file system interface

This commit is contained in:
Luke Pulverenti
2014-01-01 13:26:31 -05:00
parent 88b638fbd6
commit b9d17c9bc7
54 changed files with 737 additions and 459 deletions

View File

@@ -172,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
var quality = options.Quality ?? 90;
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, options.OutputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.BackgroundColor);
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, options.OutputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
try
{
@@ -241,7 +241,9 @@ namespace MediaBrowser.Server.Implementations.Drawing
thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
thumbnailGraph.CompositingMode = string.IsNullOrEmpty(options.BackgroundColor) && !options.PercentPlayed.HasValue && !options.AddPlayedIndicator ? CompositingMode.SourceCopy : CompositingMode.SourceOver;
thumbnailGraph.CompositingMode = string.IsNullOrEmpty(options.BackgroundColor) && !options.UnplayedCount.HasValue && !options.AddPlayedIndicator && !options.PercentPlayed.HasValue ?
CompositingMode.SourceCopy :
CompositingMode.SourceOver;
SetBackgroundColor(thumbnailGraph, options);
@@ -347,28 +349,31 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <param name="options">The options.</param>
private void DrawIndicator(Graphics graphics, int imageWidth, int imageHeight, ImageProcessingOptions options)
{
if (!options.AddPlayedIndicator && !options.PercentPlayed.HasValue)
if (!options.AddPlayedIndicator && !options.UnplayedCount.HasValue && !options.PercentPlayed.HasValue)
{
return;
}
try
{
var percentOffset = 0;
if (options.AddPlayedIndicator)
{
var currentImageSize = new Size(imageWidth, imageHeight);
new WatchedIndicatorDrawer().Process(graphics, currentImageSize);
percentOffset = 0 - WatchedIndicatorDrawer.IndicatorWidth;
new PlayedIndicatorDrawer().DrawPlayedIndicator(graphics, currentImageSize);
}
else if (options.UnplayedCount.HasValue)
{
var currentImageSize = new Size(imageWidth, imageHeight);
new UnplayedCountIndicator().DrawUnplayedCountIndicator(graphics, currentImageSize, options.UnplayedCount.Value);
}
if (options.PercentPlayed.HasValue)
{
var currentImageSize = new Size(imageWidth, imageHeight);
new PercentPlayedDrawer().Process(graphics, currentImageSize, options.PercentPlayed.Value, percentOffset);
new PercentPlayedDrawer().Process(graphics, currentImageSize, options.PercentPlayed.Value);
}
}
catch (Exception ex)
@@ -465,10 +470,15 @@ namespace MediaBrowser.Server.Implementations.Drawing
return new Tuple<string, DateTime>(croppedImagePath, _fileSystem.GetLastWriteTimeUtc(croppedImagePath));
}
/// <summary>
/// Increment this when indicator drawings change
/// </summary>
private const string IndicatorVersion = "1";
/// <summary>
/// Gets the cache file path based on a set of parameters
/// </summary>
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageOutputFormat format, bool addPlayedIndicator, int? percentPlayed, string backgroundColor)
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageOutputFormat format, bool addPlayedIndicator, double? percentPlayed, int? unwatchedCount, string backgroundColor)
{
var filename = originalPath;
@@ -485,16 +495,31 @@ namespace MediaBrowser.Server.Implementations.Drawing
filename += "f=" + format;
}
var hasIndicator = false;
if (addPlayedIndicator)
{
filename += "pl=true";
hasIndicator = true;
}
if (percentPlayed.HasValue)
{
filename += "p=" + percentPlayed.Value;
hasIndicator = true;
}
if (unwatchedCount.HasValue)
{
filename += "p=" + unwatchedCount.Value;
hasIndicator = true;
}
if (hasIndicator)
{
filename += "iv=" + IndicatorVersion;
}
if (!string.IsNullOrEmpty(backgroundColor))
{
filename += "b=" + backgroundColor;

View File

@@ -1,36 +1,34 @@
using System.Drawing;
using System.Globalization;
using System;
using System.Drawing;
namespace MediaBrowser.Server.Implementations.Drawing
{
public class PercentPlayedDrawer
{
private const int IndicatorWidth = 80;
private const int IndicatorHeight = 50;
private const int FontSize = 30;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private const int IndicatorHeight = 10;
public void Process(Graphics graphics, Size imageSize, int percent, int rightOffset)
public void Process(Graphics graphics, Size imageSize, double percent)
{
var x = imageSize.Width - IndicatorWidth + rightOffset;
var y = imageSize.Height - IndicatorHeight;
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 102, 192, 16)))
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 0, 0, 0)))
{
graphics.FillRectangle(backdroundBrush, x, 0, IndicatorWidth, IndicatorHeight);
const int innerX = 0;
var innerY = y;
var innerWidth = imageSize.Width;
var innerHeight = imageSize.Height;
var text = string.Format("{0}%", percent.ToString(_usCulture));
graphics.FillRectangle(backdroundBrush, innerX, innerY, innerWidth, innerHeight);
x = imageSize.Width - (percent < 10 ? 66 : 75) + rightOffset;
using (var font = new Font(FontFamily.GenericSansSerif, FontSize, FontStyle.Regular, GraphicsUnit.Pixel))
using (var foregroundBrush = new SolidBrush(Color.FromArgb(82, 181, 75)))
{
using (var fontBrush = new SolidBrush(Color.White))
{
graphics.DrawString(text, font, fontBrush, x, 6);
}
double foregroundWidth = innerWidth;
foregroundWidth *= percent;
foregroundWidth /= 100;
graphics.FillRectangle(foregroundBrush, innerX, innerY, Convert.ToInt32(Math.Round(foregroundWidth)), innerHeight);
}
}
}
}
}

View File

@@ -2,33 +2,31 @@
namespace MediaBrowser.Server.Implementations.Drawing
{
public class WatchedIndicatorDrawer
public class PlayedIndicatorDrawer
{
private const int IndicatorHeight = 50;
public const int IndicatorWidth = 50;
private const int FontSize = 50;
private const int OffsetFromTopRightCorner = 10;
public void Process(Graphics graphics, Size imageSize)
public void DrawPlayedIndicator(Graphics graphics, Size imageSize)
{
var x = imageSize.Width - IndicatorWidth;
var x = imageSize.Width - IndicatorWidth - OffsetFromTopRightCorner;
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 204, 51, 51)))
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 82, 181, 75)))
{
graphics.FillRectangle(backdroundBrush, x, 0, IndicatorWidth, IndicatorHeight);
graphics.FillEllipse(backdroundBrush, x, OffsetFromTopRightCorner, IndicatorWidth, IndicatorHeight);
const string text = "a";
x = imageSize.Width - 55;
x = imageSize.Width - 55 - OffsetFromTopRightCorner;
using (var font = new Font("Webdings", FontSize, FontStyle.Regular, GraphicsUnit.Pixel))
{
using (var fontBrush = new SolidBrush(Color.White))
{
graphics.DrawString(text, font, fontBrush, x, -2);
graphics.DrawString("a", font, fontBrush, x, OffsetFromTopRightCorner - 2);
}
}
}
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Drawing
{
public class UnplayedCountIndicator
{
private const int IndicatorHeight = 50;
public const int IndicatorWidth = 50;
private const int OffsetFromTopRightCorner = 10;
public void DrawUnplayedCountIndicator(Graphics graphics, Size imageSize, int count)
{
var x = imageSize.Width - IndicatorWidth - OffsetFromTopRightCorner;
using (var backdroundBrush = new SolidBrush(Color.FromArgb(225, 82, 181, 75)))
{
graphics.FillEllipse(backdroundBrush, x, OffsetFromTopRightCorner, IndicatorWidth, IndicatorHeight);
var text = count.ToString();
x = imageSize.Width - 50 - OffsetFromTopRightCorner;
var y = OffsetFromTopRightCorner + 7;
var fontSize = 30;
if (text.Length == 1)
{
x += 11;
}
else if (text.Length == 2)
{
x += 3;
}
else if (text.Length == 3)
{
//x += 1;
y += 3;
fontSize = 24;
}
using (var font = new Font("Sans-Serif", fontSize, FontStyle.Regular, GraphicsUnit.Pixel))
{
using (var fontBrush = new SolidBrush(Color.White))
{
graphics.DrawString(text, font, fontBrush, x, y);
}
}
}
}
}
}

View File

@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using System;
@@ -30,6 +31,13 @@ namespace MediaBrowser.Server.Implementations.Library
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
private readonly IFileSystem _fileSystem;
public CoreResolutionIgnoreRule(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
/// <summary>
/// Shoulds the ignore.
/// </summary>
@@ -60,23 +68,12 @@ namespace MediaBrowser.Server.Implementations.Library
return false;
}
// Drives will sometimes be hidden
if (args.Path.EndsWith(Path.VolumeSeparatorChar + "\\", StringComparison.OrdinalIgnoreCase))
// Sometimes these are marked hidden
if (_fileSystem.IsRootPath(args.Path))
{
return false;
}
// Shares will sometimes be hidden
if (args.Path.StartsWith("\\", StringComparison.OrdinalIgnoreCase))
{
// Look for a share, e.g. \\server\movies
// Is there a better way to detect if a path is a share without using native code?
if (args.Path.Substring(2).Split(Path.DirectorySeparatorChar).Length == 2)
{
return false;
}
}
return true;
}

View File

@@ -499,21 +499,18 @@ namespace MediaBrowser.Server.Implementations.Library
// When resolving the root, we need it's grandchildren (children of user views)
var flattenFolderDepth = isPhysicalRoot ? 2 : 0;
args.FileSystemDictionary = FileData.GetFilteredFileSystemEntries(args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
var fileSystemDictionary = FileData.GetFilteredFileSystemEntries(args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
// Need to remove subpaths that may have been resolved from shortcuts
// Example: if \\server\movies exists, then strip out \\server\movies\action
if (isPhysicalRoot)
{
var paths = args.FileSystemDictionary.Keys.ToList();
var paths = NormalizeRootPathList(fileSystemDictionary.Keys);
foreach (var subPath in paths
.Where(subPath => !subPath.EndsWith(":\\", StringComparison.OrdinalIgnoreCase) && paths.Any(i => subPath.StartsWith(i.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))))
{
_logger.Info("Ignoring duplicate path: {0}", subPath);
args.FileSystemDictionary.Remove(subPath);
}
fileSystemDictionary = paths.Select(i => (FileSystemInfo)new DirectoryInfo(i)).ToDictionary(i => i.FullName);
}
args.FileSystemDictionary = fileSystemDictionary;
}
// Check to see if we should resolve based on our contents
@@ -525,6 +522,23 @@ namespace MediaBrowser.Server.Implementations.Library
return ResolveItem(args);
}
public IEnumerable<string> NormalizeRootPathList(IEnumerable<string> paths)
{
var list = paths.Select(_fileSystem.NormalizePath)
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
var dupes = list.Where(subPath => !subPath.EndsWith(":\\", StringComparison.OrdinalIgnoreCase) && list.Any(i => _fileSystem.ContainsSubPath(i, subPath)))
.ToList();
foreach (var dupe in dupes)
{
_logger.Info("Found duplicate path: {0}", dupe);
}
return list.Except(dupes, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Determines whether a path should be ignored based on its contents - called after the contents have been read
/// </summary>

View File

@@ -4,11 +4,13 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -21,13 +23,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly IUserDataManager _userDataManager;
private readonly IDtoService _dtoService;
private readonly IItemRepository _itemRepo;
public LiveTvDtoService(IDtoService dtoService, IUserDataManager userDataManager, IImageProcessor imageProcessor, ILogger logger)
public LiveTvDtoService(IDtoService dtoService, IUserDataManager userDataManager, IImageProcessor imageProcessor, ILogger logger, IItemRepository itemRepo)
{
_dtoService = dtoService;
_userDataManager = userDataManager;
_imageProcessor = imageProcessor;
_logger = logger;
_itemRepo = itemRepo;
}
public TimerInfoDto GetTimerInfoDto(TimerInfo info, ILiveTvService service, LiveTvProgram program, LiveTvChannel channel)
@@ -180,7 +184,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return status.ToString();
}
public RecordingInfoDto GetRecordingInfoDto(LiveTvRecording recording, LiveTvChannel channel, ILiveTvService service, User user = null)
public RecordingInfoDto GetRecordingInfoDto(ILiveTvRecording recording, LiveTvChannel channel, ILiveTvService service, User user = null)
{
var info = recording.RecordingInfo;
@@ -216,7 +220,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
IsNews = info.IsNews,
IsKids = info.IsKids,
IsPremiere = info.IsPremiere,
RunTimeTicks = (info.EndDate - info.StartDate).Ticks
RunTimeTicks = (info.EndDate - info.StartDate).Ticks,
LocationType = recording.LocationType,
MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery
{
ItemId = recording.Id
}).ToList()
};
var imageTag = GetImageTag(recording);
@@ -330,7 +341,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return dto;
}
private Guid? GetImageTag(BaseItem info)
private Guid? GetImageTag(IHasImages info)
{
var path = info.PrimaryImagePath;
@@ -351,39 +362,41 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return null;
}
private const string InternalVersionNumber = "2";
public Guid GetInternalChannelId(string serviceName, string externalId)
{
var name = serviceName + externalId;
var name = serviceName + externalId + InternalVersionNumber;
return name.ToLower().GetMBId(typeof(LiveTvChannel));
}
public Guid GetInternalTimerId(string serviceName, string externalId)
{
var name = serviceName + externalId;
var name = serviceName + externalId + InternalVersionNumber;
return name.ToLower().GetMD5();
}
public Guid GetInternalSeriesTimerId(string serviceName, string externalId)
{
var name = serviceName + externalId;
var name = serviceName + externalId + InternalVersionNumber;
return name.ToLower().GetMD5();
}
public Guid GetInternalProgramId(string serviceName, string externalId)
{
var name = serviceName + externalId;
var name = serviceName + externalId + InternalVersionNumber;
return name.ToLower().GetMD5();
return name.ToLower().GetMBId(typeof(LiveTvProgram));
}
public Guid GetInternalRecordingId(string serviceName, string externalId)
{
var name = serviceName + externalId;
var name = serviceName + externalId + InternalVersionNumber;
return name.ToLower().GetMD5();
return name.ToLower().GetMBId(typeof(ILiveTvRecording));
}
public async Task<TimerInfo> GetTimerInfo(TimerInfoDto dto, bool isNew, ILiveTvManager liveTv, CancellationToken cancellationToken)

View File

@@ -6,8 +6,8 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
@@ -31,7 +31,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly IItemRepository _itemRepo;
private readonly IUserManager _userManager;
private readonly ILocalizationManager _localization;
private readonly LiveTvDtoService _tvDtoService;
private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
@@ -39,16 +38,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private Dictionary<Guid, LiveTvChannel> _channels = new Dictionary<Guid, LiveTvChannel>();
private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>();
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, ILocalizationManager localization, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager)
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager)
{
_appPaths = appPaths;
_fileSystem = fileSystem;
_logger = logger;
_itemRepo = itemRepo;
_localization = localization;
_userManager = userManager;
_tvDtoService = new LiveTvDtoService(dtoService, userDataManager, imageProcessor, logger);
_tvDtoService = new LiveTvDtoService(dtoService, userDataManager, imageProcessor, logger, _itemRepo);
}
/// <summary>
@@ -82,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (user != null)
{
channels = channels
.Where(i => i.IsParentalAllowed(user, _localization))
.Where(i => i.IsParentalAllowed(user))
.OrderBy(i =>
{
double number = 0;
@@ -144,7 +142,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return obj;
}
public async Task<LiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken)
public async Task<ILiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken)
{
var service = ActiveService;
@@ -255,23 +253,46 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
private async Task<LiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
private async Task<ILiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
{
var isNew = false;
var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);
var item = _itemRepo.RetrieveItem(id) as LiveTvRecording;
var item = _itemRepo.RetrieveItem(id) as ILiveTvRecording;
if (item == null)
{
item = new LiveTvRecording
if (info.ChannelType == ChannelType.TV)
{
Name = info.Name,
Id = id,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};
item = new LiveTvVideoRecording
{
Name = info.Name,
Id = id,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow,
VideoType = VideoType.VideoFile
};
}
else
{
item = new LiveTvAudioRecording
{
Name = info.Name,
Id = id,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};
}
if (!string.IsNullOrEmpty(info.Path))
{
item.Path = info.Path;
}
else if (!string.IsNullOrEmpty(info.Url))
{
item.Path = info.Url;
}
isNew = true;
}
@@ -331,7 +352,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (user != null)
{
programs = programs.Where(i => i.IsParentalAllowed(user, _localization));
programs = programs.Where(i => i.IsParentalAllowed(user));
}
var returnArray = programs
@@ -450,10 +471,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
var list = new List<RecordingInfo>();
var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
list.AddRange(recordings);
if (!string.IsNullOrEmpty(query.ChannelId))
{
@@ -461,9 +479,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var currentServiceName = service.Name;
list = list
.Where(i => _tvDtoService.GetInternalChannelId(currentServiceName, i.ChannelId) == guid)
.ToList();
recordings = recordings
.Where(i => _tvDtoService.GetInternalChannelId(currentServiceName, i.ChannelId) == guid);
}
if (!string.IsNullOrEmpty(query.Id))
@@ -472,27 +489,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var currentServiceName = service.Name;
list = list
.Where(i => _tvDtoService.GetInternalRecordingId(currentServiceName, i.Id) == guid)
.ToList();
recordings = recordings
.Where(i => _tvDtoService.GetInternalRecordingId(currentServiceName, i.Id) == guid);
}
if (!string.IsNullOrEmpty(query.GroupId))
{
var guid = new Guid(query.GroupId);
list = list.Where(i => GetRecordingGroupIds(i).Contains(guid))
.ToList();
recordings = recordings.Where(i => GetRecordingGroupIds(i).Contains(guid));
}
IEnumerable<LiveTvRecording> entities = await GetEntities(list, service.Name, cancellationToken).ConfigureAwait(false);
if (query.IsRecording.HasValue)
{
var val = query.IsRecording.Value;
recordings = recordings.Where(i => (i.Status == RecordingStatus.InProgress) == val);
}
IEnumerable<ILiveTvRecording> entities = await GetEntities(recordings, service.Name, cancellationToken).ConfigureAwait(false);
entities = entities.OrderByDescending(i => i.RecordingInfo.StartDate);
if (user != null)
{
var currentUser = user;
entities = entities.Where(i => i.IsParentalAllowed(currentUser, _localization));
entities = entities.Where(i => i.IsParentalAllowed(currentUser));
}
if (query.StartIndex.HasValue)
@@ -520,7 +541,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
private Task<LiveTvRecording[]> GetEntities(IEnumerable<RecordingInfo> recordings, string serviceName, CancellationToken cancellationToken)
private Task<ILiveTvRecording[]> GetEntities(IEnumerable<RecordingInfo> recordings, string serviceName, CancellationToken cancellationToken)
{
var tasks = recordings.Select(i => GetRecording(i, serviceName, cancellationToken));

View File

@@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public override bool Supports(BaseItem item)
{
return item is LiveTvRecording;
return item is ILiveTvRecording;
}
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
@@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
try
{
changed = await DownloadImage((LiveTvRecording)item, cancellationToken).ConfigureAwait(false);
changed = await DownloadImage((ILiveTvRecording)item, cancellationToken).ConfigureAwait(false);
}
catch (HttpException ex)
{
@@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return changed;
}
private async Task<bool> DownloadImage(LiveTvRecording item, CancellationToken cancellationToken)
private async Task<bool> DownloadImage(ILiveTvRecording item, CancellationToken cancellationToken)
{
var recordingInfo = item.RecordingInfo;
@@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
// Dummy up the original url
var url = item.ServiceName + recordingInfo.Id;
await _providerManager.SaveImage(item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false);
await _providerManager.SaveImage((BaseItem)item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false);
return true;
}

View File

@@ -100,7 +100,8 @@
<Compile Include="Configuration\ServerConfigurationManager.cs" />
<Compile Include="Drawing\ImageHeader.cs" />
<Compile Include="Drawing\PercentPlayedDrawer.cs" />
<Compile Include="Drawing\WatchedIndicatorDrawer.cs" />
<Compile Include="Drawing\PlayedIndicatorDrawer.cs" />
<Compile Include="Drawing\UnplayedCountIndicator.cs" />
<Compile Include="Dto\DtoService.cs" />
<Compile Include="EntryPoints\LibraryChangedNotifier.cs" />
<Compile Include="EntryPoints\LoadRegistrations.cs" />

View File

@@ -73,7 +73,7 @@ namespace MediaBrowser.Server.Implementations.Providers
throw new ArgumentNullException("mimeType");
}
var saveLocally = _config.Configuration.SaveLocalMeta && item.Parent != null && !(item is Audio);
var saveLocally = item.IsSaveLocalMetadataEnabled() && item.Parent != null && !(item is Audio);
if (item is IItemByName || item is User)
{