aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Sync
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Sync')
-rw-r--r--MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs26
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MediaSync.cs86
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs44
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs265
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs133
9 files changed, 328 insertions, 255 deletions
diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
index 99d758233..7b1fa4dec 100644
--- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
@@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public string Name
{
- get { return "App Sync"; }
+ get { return "Mobile Sync"; }
}
public IEnumerable<SyncTarget> GetAllSyncTargets()
diff --git a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs
index 73400f834..992f1d16c 100644
--- a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs
+++ b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs
@@ -195,17 +195,39 @@ namespace MediaBrowser.Server.Implementations.Sync
}
};
- var maxAudioChannels = supportsAc3 || supportsDca ? "5" : "2";
codecProfiles.Add(new CodecProfile
{
Type = CodecType.VideoAudio,
+ Codec = "ac3",
Conditions = new[]
{
new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.AudioChannels,
- Value = maxAudioChannels,
+ Value = "6",
+ IsRequired = false
+ },
+ new ProfileCondition
+ {
+ Condition = ProfileConditionType.Equals,
+ Property = ProfileConditionValue.IsSecondaryAudio,
+ Value = "false",
+ IsRequired = false
+ }
+ }
+ });
+ codecProfiles.Add(new CodecProfile
+ {
+ Type = CodecType.VideoAudio,
+ Codec = "aac,mp3",
+ Conditions = new[]
+ {
+ new ProfileCondition
+ {
+ Condition = ProfileConditionType.LessThanEqual,
+ Property = ProfileConditionValue.AudioChannels,
+ Value = "2",
IsRequired = true
},
new ProfileCondition
diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
index 5bc8b8088..96e996ff1 100644
--- a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
@@ -1,7 +1,8 @@
-using System.Globalization;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -10,12 +11,14 @@ using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Sync;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Interfaces.IO;
namespace MediaBrowser.Server.Implementations.Sync
{
@@ -25,13 +28,18 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IServerApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
+ private readonly IConfigurationManager _config;
- public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem)
+ public const string PathSeparatorString = "/";
+ public const char PathSeparatorChar = '/';
+
+ public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem, IConfigurationManager config)
{
_logger = logger;
_syncManager = syncManager;
_appHost = appHost;
_fileSystem = fileSystem;
+ _config = config;
}
public async Task Sync(IServerSyncProvider provider,
@@ -67,7 +75,24 @@ namespace MediaBrowser.Server.Implementations.Sync
SyncTarget target,
CancellationToken cancellationToken)
{
- var jobItemIds = await dataProvider.GetSyncJobItemIds(target, serverId).ConfigureAwait(false);
+ var localItems = await dataProvider.GetLocalItems(target, serverId).ConfigureAwait(false);
+ var remoteFiles = await provider.GetFiles(new FileQuery(), target, cancellationToken).ConfigureAwait(false);
+ var remoteIds = remoteFiles.Items.Select(i => i.Id).ToList();
+
+ var jobItemIds = new List<string>();
+
+ foreach (var localItem in localItems)
+ {
+ // TODO: Remove this after a while
+ if (string.IsNullOrWhiteSpace(localItem.FileId))
+ {
+ jobItemIds.Add(localItem.SyncJobItemId);
+ }
+ else if (remoteIds.Contains(localItem.FileId, StringComparer.OrdinalIgnoreCase))
+ {
+ jobItemIds.Add(localItem.SyncJobItemId);
+ }
+ }
var result = await _syncManager.SyncData(new SyncDataRequest
{
@@ -152,12 +177,14 @@ namespace MediaBrowser.Server.Implementations.Sync
var transferSuccess = false;
Exception transferException = null;
+ var options = _config.GetSyncOptions();
+
try
{
var fileTransferProgress = new ActionableProgress<double>();
fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
- var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath, target, fileTransferProgress, cancellationToken).ConfigureAwait(false);
+ var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath.Split(PathSeparatorChar), target, options, fileTransferProgress, cancellationToken).ConfigureAwait(false);
if (localItem.Item.MediaSources != null)
{
@@ -171,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
+ localItem.FileId = sendFileResult.Id;
+
// Create db record
await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);
@@ -179,7 +208,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
if (mediaSource != null)
{
- await SendSubtitles(localItem, mediaSource, provider, dataProvider, target, cancellationToken).ConfigureAwait(false);
+ await SendSubtitles(localItem, mediaSource, provider, dataProvider, target, options, cancellationToken).ConfigureAwait(false);
}
}
@@ -207,7 +236,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private async Task SendSubtitles(LocalItem localItem, MediaSourceInfo mediaSource, IServerSyncProvider provider, ISyncDataProvider dataProvider, SyncTarget target, CancellationToken cancellationToken)
+ private async Task SendSubtitles(LocalItem localItem, MediaSourceInfo mediaSource, IServerSyncProvider provider, ISyncDataProvider dataProvider, SyncTarget target, SyncOptions options, CancellationToken cancellationToken)
{
var failedSubtitles = new List<MediaStream>();
var requiresSave = false;
@@ -219,13 +248,13 @@ namespace MediaBrowser.Server.Implementations.Sync
try
{
var remotePath = GetRemoteSubtitlePath(localItem, mediaStream, provider, target);
- var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, new Progress<double>(), cancellationToken).ConfigureAwait(false);
+ var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, options, new Progress<double>(), cancellationToken).ConfigureAwait(false);
// This is the path that will be used when talking to the provider
- mediaStream.ExternalId = remotePath;
+ mediaStream.ExternalId = sendFileResult.Id;
// Keep track of all additional files for cleanup later.
- localItem.AdditionalFiles.Add(remotePath);
+ localItem.AdditionalFiles.Add(sendFileResult.Id);
// This is the public path clients will use
mediaStream.Path = sendFileResult.Path;
@@ -250,17 +279,15 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private string GetRemoteSubtitlePath(LocalItem item, MediaStream stream, IServerSyncProvider provider, SyncTarget target)
+ private string[] GetRemoteSubtitlePath(LocalItem item, MediaStream stream, IServerSyncProvider provider, SyncTarget target)
{
- var path = item.LocalPath;
-
var filename = GetSubtitleSaveFileName(item, stream.Language, stream.IsForced) + "." + stream.Codec.ToLower();
- var parentPath = provider.GetParentDirectoryPath(path, target);
-
- path = Path.Combine(parentPath, filename);
+ var pathParts = item.LocalPath.Split(PathSeparatorChar);
+ var list = pathParts.Take(pathParts.Length - 1).ToList();
+ list.Add(filename);
- return path;
+ return list.ToArray();
}
private string GetSubtitleSaveFileName(LocalItem item, string language, bool isForced)
@@ -289,17 +316,21 @@ namespace MediaBrowser.Server.Implementations.Sync
SyncTarget target,
CancellationToken cancellationToken)
{
- var localItems = await dataProvider.GetCachedItemsBySyncJobItemId(target, serverId, syncJobItemId);
+ var localItems = await dataProvider.GetItemsBySyncJobItemId(target, serverId, syncJobItemId);
foreach (var localItem in localItems)
{
var files = localItem.AdditionalFiles.ToList();
- files.Insert(0, localItem.LocalPath);
+
+ // TODO: Remove this. Have to check it for now since this is a new property
+ if (!string.IsNullOrWhiteSpace(localItem.FileId))
+ {
+ files.Insert(0, localItem.FileId);
+ }
foreach (var file in files)
{
_logger.Debug("Removing {0} from {1}.", file, target.Name);
-
await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
}
@@ -307,12 +338,19 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private async Task<SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string remotePath, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task<SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string[] pathParts, SyncTarget target, SyncOptions options, IProgress<double> progress, CancellationToken cancellationToken)
{
- _logger.Debug("Sending {0} to {1}. Remote path: {2}", inputPath, provider.Name, remotePath);
- using (var stream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
+ _logger.Debug("Sending {0} to {1}. Remote path: {2}", inputPath, provider.Name, string.Join("/", pathParts));
+ using (var fileStream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
{
- return await provider.SendFile(stream, remotePath, target, progress, cancellationToken).ConfigureAwait(false);
+ Stream stream = fileStream;
+
+ if (options.UploadSpeedLimitBytes > 0 && provider is IRemoteSyncProvider)
+ {
+ stream = new ThrottledStream(stream, options.UploadSpeedLimitBytes);
+ }
+
+ return await provider.SendFile(stream, pathParts, target, progress, cancellationToken).ConfigureAwait(false);
}
}
@@ -336,7 +374,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var path = GetDirectoryPath(provider, job, syncedItem, libraryItem, serverName);
path.Add(GetLocalFileName(provider, libraryItem, originalFileName));
- var localPath = provider.GetFullPath(path, target);
+ var localPath = string.Join(PathSeparatorString, path.ToArray());
foreach (var mediaSource in libraryItem.MediaSources)
{
diff --git a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
index a8bc24c2a..6f09e96f0 100644
--- a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Sync;
@@ -18,13 +19,15 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IServerApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
+ private readonly IConfigurationManager _config;
- public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem)
+ public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem, IConfigurationManager config)
{
_syncManager = syncManager;
_appHost = appHost;
_logger = logger;
_fileSystem = fileSystem;
+ _config = config;
}
public async Task Sync(IEnumerable<IServerSyncProvider> providers, IProgress<double> progress, CancellationToken cancellationToken)
@@ -56,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var dataProvider = _syncManager.GetDataProvider(target.Item1, target.Item2);
- await new MediaSync(_logger, _syncManager, _appHost, _fileSystem)
+ await new MediaSync(_logger, _syncManager, _appHost, _fileSystem, _config)
.Sync(target.Item1, dataProvider, target.Item2, innerProgress, cancellationToken)
.ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
index 148602bd4..9477a23f1 100644
--- a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Sync;
@@ -17,13 +18,15 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IServerApplicationHost _appHost;
+ private readonly IConfigurationManager _config;
- public ServerSyncScheduledTask(ISyncManager syncManager, ILogger logger, IFileSystem fileSystem, IServerApplicationHost appHost)
+ public ServerSyncScheduledTask(ISyncManager syncManager, ILogger logger, IFileSystem fileSystem, IServerApplicationHost appHost, IConfigurationManager config)
{
_syncManager = syncManager;
_logger = logger;
_fileSystem = fileSystem;
_appHost = appHost;
+ _config = config;
}
public string Name
@@ -46,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
- return new MultiProviderSync((SyncManager)_syncManager, _appHost, _logger, _fileSystem)
+ return new MultiProviderSync((SyncManager)_syncManager, _appHost, _logger, _fileSystem, _config)
.Sync(ServerSyncProviders, progress, cancellationToken);
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
index 271b2bb39..fd4092974 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
@@ -67,9 +67,10 @@ namespace MediaBrowser.Server.Implementations.Sync
var items = (await GetItemsForSync(job.Category, job.ParentId, job.RequestedItemIds, user, job.UnwatchedOnly).ConfigureAwait(false))
.ToList();
- var jobItems = _syncRepo.GetJobItems(new SyncJobItemQuery
+ var jobItems = _syncManager.GetJobItems(new SyncJobItemQuery
{
- JobId = job.Id
+ JobId = job.Id,
+ AddMetadata = false
}).Items.ToList();
@@ -140,9 +141,10 @@ namespace MediaBrowser.Server.Implementations.Sync
throw new ArgumentNullException("job");
}
- var result = _syncRepo.GetJobItems(new SyncJobItemQuery
+ var result = _syncManager.GetJobItems(new SyncJobItemQuery
{
- JobId = job.Id
+ JobId = job.Id,
+ AddMetadata = false
});
return UpdateJobStatus(job, result.Items.ToList());
@@ -362,9 +364,10 @@ namespace MediaBrowser.Server.Implementations.Sync
await EnsureSyncJobItems(null, cancellationToken).ConfigureAwait(false);
// If it already has a converting status then is must have been aborted during conversion
- var result = _syncRepo.GetJobItems(new SyncJobItemQuery
+ var result = _syncManager.GetJobItems(new SyncJobItemQuery
{
- Statuses = new SyncJobItemStatus[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting }
+ Statuses = new[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
+ AddMetadata = false
});
await SyncJobItems(result.Items, true, progress, cancellationToken).ConfigureAwait(false);
@@ -384,13 +387,14 @@ namespace MediaBrowser.Server.Implementations.Sync
await EnsureSyncJobItems(targetId, cancellationToken).ConfigureAwait(false);
// If it already has a converting status then is must have been aborted during conversion
- var result = _syncRepo.GetJobItems(new SyncJobItemQuery
+ var result = _syncManager.GetJobItems(new SyncJobItemQuery
{
- Statuses = new SyncJobItemStatus[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
- TargetId = targetId
+ Statuses = new[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
+ TargetId = targetId,
+ AddMetadata = false
});
- await SyncJobItems(result.Items, true, progress, cancellationToken).ConfigureAwait(false);
+ await SyncJobItems(result.Items, enableConversion, progress, cancellationToken).ConfigureAwait(false);
}
public async Task SyncJobItems(SyncJobItem[] items, bool enableConversion, IProgress<double> progress, CancellationToken cancellationToken)
@@ -452,17 +456,18 @@ namespace MediaBrowser.Server.Implementations.Sync
jobItem.Progress = 0;
+ var syncOptions = _config.GetSyncOptions();
var user = _userManager.GetUserById(job.UserId);
var video = item as Video;
if (video != null)
{
- await Sync(jobItem, job, video, user, enableConversion, progress, cancellationToken).ConfigureAwait(false);
+ await Sync(jobItem, job, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false);
}
else if (item is Audio)
{
- await Sync(jobItem, job, (Audio)item, user, enableConversion, progress, cancellationToken).ConfigureAwait(false);
+ await Sync(jobItem, job, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false);
}
else if (item is Photo)
@@ -476,7 +481,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken)
{
var jobOptions = _syncManager.GetVideoOptions(jobItem, job);
var conversionOptions = new VideoOptions
@@ -489,7 +494,7 @@ namespace MediaBrowser.Server.Implementations.Sync
conversionOptions.ItemId = item.Id.ToString("N");
conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
- var streamInfo = new StreamBuilder().BuildVideoItem(conversionOptions);
+ var streamInfo = new StreamBuilder(_logger).BuildVideoItem(conversionOptions);
var mediaSource = streamInfo.MediaSource;
// No sense creating external subs if we're already burning one into the video
@@ -538,7 +543,9 @@ namespace MediaBrowser.Server.Implementations.Sync
jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, conversionOptions.Profile)
{
- OutputDirectory = jobItem.TemporaryPath
+ OutputDirectory = jobItem.TemporaryPath,
+ CpuCoreLimit = syncOptions.TranscodingCpuCoreLimit,
+ ReadInputAtNativeFramerate = !syncOptions.EnableFullSpeedTranscoding
}, innerProgress, cancellationToken);
}
@@ -673,7 +680,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private const int DatabaseProgressUpdateIntervalSeconds = 2;
- private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken)
{
var jobOptions = _syncManager.GetAudioOptions(jobItem, job);
var conversionOptions = new AudioOptions
@@ -686,7 +693,7 @@ namespace MediaBrowser.Server.Implementations.Sync
conversionOptions.ItemId = item.Id.ToString("N");
conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
- var streamInfo = new StreamBuilder().BuildAudioItem(conversionOptions);
+ var streamInfo = new StreamBuilder(_logger).BuildAudioItem(conversionOptions);
var mediaSource = streamInfo.MediaSource;
jobItem.MediaSourceId = streamInfo.MediaSourceId;
@@ -721,7 +728,8 @@ namespace MediaBrowser.Server.Implementations.Sync
jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, conversionOptions.Profile)
{
- OutputDirectory = jobItem.TemporaryPath
+ OutputDirectory = jobItem.TemporaryPath,
+ CpuCoreLimit = syncOptions.TranscodingCpuCoreLimit
}, innerProgress, cancellationToken);
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index 102218979..0e4a3bcf1 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -182,19 +182,21 @@ namespace MediaBrowser.Server.Implementations.Sync
await processor.EnsureJobItems(job).ConfigureAwait(false);
// If it already has a converting status then is must have been aborted during conversion
- var jobItemsResult = _repo.GetJobItems(new SyncJobItemQuery
+ var jobItemsResult = GetJobItems(new SyncJobItemQuery
{
- Statuses = new SyncJobItemStatus[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
- JobId = jobId
+ Statuses = new[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
+ JobId = jobId,
+ AddMetadata = false
});
await processor.SyncJobItems(jobItemsResult.Items, false, new Progress<double>(), CancellationToken.None)
.ConfigureAwait(false);
- jobItemsResult = _repo.GetJobItems(new SyncJobItemQuery
+ jobItemsResult = GetJobItems(new SyncJobItemQuery
{
- Statuses = new SyncJobItemStatus[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
- JobId = jobId
+ Statuses = new[] { SyncJobItemStatus.Queued, SyncJobItemStatus.Converting },
+ JobId = jobId,
+ AddMetadata = false
});
var returnResult = new SyncJobCreationResult
@@ -510,12 +512,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var video = item as Video;
if (video != null)
{
- if (video.VideoType == VideoType.Iso)
- {
- return false;
- }
-
- if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd || video.VideoType == VideoType.HdDvd)
+ if (video.VideoType == VideoType.Iso || video.VideoType == VideoType.HdDvd)
{
return false;
}
@@ -550,7 +547,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- if (item is LiveTvChannel || item is IChannelItem || item is ILiveTvRecording)
+ if (item is LiveTvChannel || item is IChannelItem)
{
return false;
}
@@ -564,7 +561,7 @@ namespace MediaBrowser.Server.Implementations.Sync
return true;
}
- return item.LocationType == LocationType.FileSystem || item is Season || item is ILiveTvRecording;
+ return item.LocationType == LocationType.FileSystem || item is Season;
}
private string GetDefaultName(BaseItem item)
@@ -726,14 +723,19 @@ namespace MediaBrowser.Server.Implementations.Sync
TargetId = targetId,
Statuses = new[]
{
- SyncJobItemStatus.ReadyToTransfer
+ SyncJobItemStatus.ReadyToTransfer,
+ SyncJobItemStatus.Transferring
}
});
- return jobItemResult.Items
+ var readyItems = jobItemResult.Items
.Select(GetJobItemInfo)
.Where(i => i != null)
.ToList();
+
+ _logger.Debug("Returning {0} ready sync items for targetId {1}", readyItems.Count, targetId);
+
+ return readyItems;
}
public async Task<SyncDataResponse> SyncData(SyncDataRequest request)
@@ -753,6 +755,11 @@ namespace MediaBrowser.Server.Implementations.Sync
foreach (var jobItem in jobItemResult.Items)
{
+ var requiresSaving = false;
+ var removeFromDevice = false;
+
+ var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
+
if (request.LocalItemIds.Contains(jobItem.ItemId, StringComparer.OrdinalIgnoreCase))
{
var job = _repo.GetJob(jobItem.JobId);
@@ -761,36 +768,55 @@ namespace MediaBrowser.Server.Implementations.Sync
if (jobItem.IsMarkedForRemoval)
{
// Tell the device to remove it since it has been marked for removal
- response.ItemIdsToRemove.Add(jobItem.ItemId);
+ _logger.Debug("Adding ItemIdsToRemove {0} because IsMarkedForRemoval is set.", jobItem.ItemId);
+ removeFromDevice = true;
}
else if (user == null)
{
// Tell the device to remove it since the user is gone now
- response.ItemIdsToRemove.Add(jobItem.ItemId);
+ _logger.Debug("Adding ItemIdsToRemove {0} because the user is no longer valid.", jobItem.ItemId);
+ removeFromDevice = true;
+ }
+ else if (!IsLibraryItemAvailable(libraryItem))
+ {
+ // Tell the device to remove it since it's no longer available
+ _logger.Debug("Adding ItemIdsToRemove {0} because it is no longer available.", jobItem.ItemId);
+ removeFromDevice = true;
}
else if (job.UnwatchedOnly)
{
- var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
-
- if (IsLibraryItemAvailable(libraryItem))
- {
- if (libraryItem.IsPlayed(user) && libraryItem is Video)
- {
- // Tell the device to remove it since it has been played
- response.ItemIdsToRemove.Add(jobItem.ItemId);
- }
- }
- else
+ if (libraryItem.IsPlayed(user) && libraryItem is Video)
{
- // Tell the device to remove it since it's no longer available
- response.ItemIdsToRemove.Add(jobItem.ItemId);
+ // Tell the device to remove it since it has been played
+ _logger.Debug("Adding ItemIdsToRemove {0} because it has been marked played.", jobItem.ItemId);
+ removeFromDevice = true;
}
}
}
else
{
// Content is no longer on the device
- jobItem.Status = SyncJobItemStatus.RemovedFromDevice;
+ if (jobItem.IsMarkedForRemoval)
+ {
+ jobItem.Status = SyncJobItemStatus.RemovedFromDevice;
+ }
+ else
+ {
+ _logger.Debug("Setting status to Queued for {0} because it is no longer on the device.", jobItem.ItemId);
+ jobItem.Status = SyncJobItemStatus.Queued;
+ }
+ requiresSaving = true;
+ }
+
+ if (removeFromDevice)
+ {
+ response.ItemIdsToRemove.Add(jobItem.ItemId);
+ jobItem.IsMarkedForRemoval = true;
+ requiresSaving = true;
+ }
+
+ if (requiresSaving)
+ {
await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
}
}
@@ -834,6 +860,11 @@ namespace MediaBrowser.Server.Implementations.Sync
foreach (var jobItem in jobItemResult.Items)
{
+ var requiresSaving = false;
+ var removeFromDevice = false;
+
+ var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
+
if (request.SyncJobItemIds.Contains(jobItem.Id, StringComparer.OrdinalIgnoreCase))
{
var job = _repo.GetJob(jobItem.JobId);
@@ -842,36 +873,55 @@ namespace MediaBrowser.Server.Implementations.Sync
if (jobItem.IsMarkedForRemoval)
{
// Tell the device to remove it since it has been marked for removal
- response.ItemIdsToRemove.Add(jobItem.Id);
+ _logger.Debug("Adding ItemIdsToRemove {0} because IsMarkedForRemoval is set.", jobItem.Id);
+ removeFromDevice = true;
}
else if (user == null)
{
// Tell the device to remove it since the user is gone now
- response.ItemIdsToRemove.Add(jobItem.Id);
+ _logger.Debug("Adding ItemIdsToRemove {0} because the user is no longer valid.", jobItem.Id);
+ removeFromDevice = true;
+ }
+ else if (!IsLibraryItemAvailable(libraryItem))
+ {
+ // Tell the device to remove it since it's no longer available
+ _logger.Debug("Adding ItemIdsToRemove {0} because it is no longer available.", jobItem.Id);
+ removeFromDevice = true;
}
else if (job.UnwatchedOnly)
{
- var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
-
- if (IsLibraryItemAvailable(libraryItem))
- {
- if (libraryItem.IsPlayed(user) && libraryItem is Video)
- {
- // Tell the device to remove it since it has been played
- response.ItemIdsToRemove.Add(jobItem.Id);
- }
- }
- else
+ if (libraryItem.IsPlayed(user) && libraryItem is Video)
{
- // Tell the device to remove it since it's no longer available
- response.ItemIdsToRemove.Add(jobItem.Id);
+ // Tell the device to remove it since it has been played
+ _logger.Debug("Adding ItemIdsToRemove {0} because it has been marked played.", jobItem.Id);
+ removeFromDevice = true;
}
}
}
else
{
// Content is no longer on the device
- jobItem.Status = SyncJobItemStatus.RemovedFromDevice;
+ if (jobItem.IsMarkedForRemoval)
+ {
+ jobItem.Status = SyncJobItemStatus.RemovedFromDevice;
+ }
+ else
+ {
+ _logger.Debug("Setting status to Queued for {0} because it is no longer on the device.", jobItem.Id);
+ jobItem.Status = SyncJobItemStatus.Queued;
+ }
+ requiresSaving = true;
+ }
+
+ if (removeFromDevice)
+ {
+ response.ItemIdsToRemove.Add(jobItem.Id);
+ jobItem.IsMarkedForRemoval = true;
+ requiresSaving = true;
+ }
+
+ if (requiresSaving)
+ {
await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
}
}
@@ -894,12 +944,6 @@ namespace MediaBrowser.Server.Implementations.Sync
response.ItemIdsToRemove = response.ItemIdsToRemove.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
- var itemsOnDevice = request.LocalItemIds
- .Except(response.ItemIdsToRemove)
- .ToList();
-
- SetUserAccess(request, response, itemsOnDevice);
-
return response;
}
@@ -962,16 +1006,39 @@ namespace MediaBrowser.Server.Implementations.Sync
await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
}
+ public async Task CancelItems(string targetId, IEnumerable<string> itemIds)
+ {
+ foreach (var item in itemIds)
+ {
+ var syncJobItemResult = GetJobItems(new SyncJobItemQuery
+ {
+ AddMetadata = false,
+ ItemId = item,
+ TargetId = targetId,
+ Statuses = new[] { SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Converting, SyncJobItemStatus.Synced, SyncJobItemStatus.Failed }
+ });
+
+ foreach (var jobItem in syncJobItemResult.Items)
+ {
+ await CancelJobItem(jobItem.Id).ConfigureAwait(false);
+ }
+ }
+ }
+
public async Task CancelJobItem(string id)
{
var jobItem = _repo.GetJobItem(id);
- if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting)
+ if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting && jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Synced)
{
throw new ArgumentException("Operation is not valid for this job item");
}
- jobItem.Status = SyncJobItemStatus.Cancelled;
+ if (jobItem.Status != SyncJobItemStatus.Synced)
+ {
+ jobItem.Status = SyncJobItemStatus.Cancelled;
+ }
+
jobItem.Progress = 0;
jobItem.IsMarkedForRemoval = true;
@@ -995,24 +1062,24 @@ namespace MediaBrowser.Server.Implementations.Sync
{
_logger.ErrorException("Error deleting directory {0}", ex, path);
}
+
+ //var jobItemsResult = GetJobItems(new SyncJobItemQuery
+ //{
+ // AddMetadata = false,
+ // JobId = jobItem.JobId,
+ // Limit = 0,
+ // Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Failed, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring }
+ //});
+
+ //if (jobItemsResult.TotalRecordCount == 0)
+ //{
+ // await CancelJob(jobItem.JobId).ConfigureAwait(false);
+ //}
}
- public async Task MarkJobItemForRemoval(string id)
+ public Task MarkJobItemForRemoval(string id)
{
- var jobItem = _repo.GetJobItem(id);
-
- if (jobItem.Status != SyncJobItemStatus.Synced)
- {
- throw new ArgumentException("Operation is not valid for this job item");
- }
-
- jobItem.IsMarkedForRemoval = true;
-
- await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
-
- var processor = GetSyncJobProcessor();
-
- await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
+ return CancelJobItem(id);
}
public async Task UnmarkJobItemForRemoval(string id)
@@ -1137,13 +1204,18 @@ namespace MediaBrowser.Server.Implementations.Sync
public IEnumerable<SyncQualityOption> GetQualityOptions(string targetId)
{
+ return GetQualityOptions(targetId, null);
+ }
+
+ public IEnumerable<SyncQualityOption> GetQualityOptions(string targetId, User user)
+ {
foreach (var provider in _providers)
{
foreach (var target in GetSyncTargets(provider))
{
if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
{
- return GetQualityOptions(provider, target);
+ return GetQualityOptions(provider, target, user);
}
}
}
@@ -1151,12 +1223,19 @@ namespace MediaBrowser.Server.Implementations.Sync
return new List<SyncQualityOption>();
}
- private IEnumerable<SyncQualityOption> GetQualityOptions(ISyncProvider provider, SyncTarget target)
+ private IEnumerable<SyncQualityOption> GetQualityOptions(ISyncProvider provider, SyncTarget target, User user)
{
var hasQuality = provider as IHasSyncQuality;
if (hasQuality != null)
{
- return hasQuality.GetQualityOptions(target);
+ var options = hasQuality.GetQualityOptions(target);
+
+ if (user != null && !user.Policy.EnableSyncTranscoding)
+ {
+ options = options.Where(i => i.IsOriginalQuality);
+ }
+
+ return options;
}
// Default options for providers that don't override
@@ -1186,7 +1265,7 @@ namespace MediaBrowser.Server.Implementations.Sync
};
}
- public IEnumerable<SyncProfileOption> GetProfileOptions(string targetId)
+ public IEnumerable<SyncProfileOption> GetProfileOptions(string targetId, User user)
{
foreach (var provider in _providers)
{
@@ -1194,7 +1273,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
{
- return GetProfileOptions(provider, target);
+ return GetProfileOptions(provider, target, user);
}
}
}
@@ -1202,7 +1281,12 @@ namespace MediaBrowser.Server.Implementations.Sync
return new List<SyncProfileOption>();
}
- private IEnumerable<SyncProfileOption> GetProfileOptions(ISyncProvider provider, SyncTarget target)
+ public IEnumerable<SyncProfileOption> GetProfileOptions(string targetId)
+ {
+ return GetProfileOptions(targetId, null);
+ }
+
+ private IEnumerable<SyncProfileOption> GetProfileOptions(ISyncProvider provider, SyncTarget target, User user)
{
var hasQuality = provider as IHasSyncQuality;
if (hasQuality != null)
@@ -1220,20 +1304,23 @@ namespace MediaBrowser.Server.Implementations.Sync
EnableQualityOptions = false
});
- list.Add(new SyncProfileOption
+ if (user == null || user.Policy.EnableSyncTranscoding)
{
- Name = "Baseline",
- Id = "baseline",
- Description = "Designed for compatibility with all devices, including web browsers. Targets H264/AAC video and MP3 audio."
- });
+ list.Add(new SyncProfileOption
+ {
+ Name = "Baseline",
+ Id = "baseline",
+ Description = "Designed for compatibility with all devices, including web browsers. Targets H264/AAC video and MP3 audio."
+ });
- list.Add(new SyncProfileOption
- {
- Name = "General",
- Id = "general",
- Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
- IsDefault = true
- });
+ list.Add(new SyncProfileOption
+ {
+ Name = "General",
+ Id = "general",
+ Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
+ IsDefault = true
+ });
+ }
return list;
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs
index d1ef523e1..f7f320741 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs
@@ -56,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var syncProvider = targetTuple.Item1;
var dataProvider = _syncManager.GetDataProvider(targetTuple.Item1, syncTarget);
- var localItems = await dataProvider.GetCachedItems(syncTarget, serverId, item.Id.ToString("N")).ConfigureAwait(false);
+ var localItems = await dataProvider.GetItems(syncTarget, serverId, item.Id.ToString("N")).ConfigureAwait(false);
foreach (var localItem in localItems)
{
@@ -109,8 +109,13 @@ namespace MediaBrowser.Server.Implementations.Sync
var dataProvider = _syncManager.GetDataProvider(provider, target);
var localItem = await dataProvider.Get(target, openKeys[2]).ConfigureAwait(false);
+ var fileId = localItem.FileId;
+ if (string.IsNullOrWhiteSpace(fileId))
+ {
+ }
+
var requiresDynamicAccess = (IHasDynamicAccess)provider;
- var dynamicInfo = await requiresDynamicAccess.GetSyncedFileInfo(localItem.LocalPath, target, cancellationToken).ConfigureAwait(false);
+ var dynamicInfo = await requiresDynamicAccess.GetSyncedFileInfo(fileId, target, cancellationToken).ConfigureAwait(false);
var mediaSource = localItem.Item.MediaSources.First();
mediaSource.LiveStreamId = Guid.NewGuid().ToString();
diff --git a/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs b/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs
index dea868848..676adad34 100644
--- a/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Sync;
@@ -12,6 +11,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Interfaces.IO;
namespace MediaBrowser.Server.Implementations.Sync
{
@@ -29,8 +29,6 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IApplicationPaths _appPaths;
private readonly IServerApplicationHost _appHost;
- private readonly SemaphoreSlim _cacheFileLock = new SemaphoreSlim(1, 1);
-
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
{
_logger = logger;
@@ -42,12 +40,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_appHost = appHost;
}
- private string GetCachePath()
- {
- return Path.Combine(_appPaths.DataPath, "sync", _target.Id.GetMD5().ToString("N") + ".json");
- }
-
- private string GetRemotePath()
+ private string[] GetRemotePath()
{
var parts = new List<string>
{
@@ -57,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync
parts = parts.Select(i => GetValidFilename(_provider, i)).ToList();
- return _provider.GetFullPath(parts, _target);
+ return parts.ToArray();
}
private string GetValidFilename(IServerSyncProvider provider, string filename)
@@ -66,58 +59,29 @@ namespace MediaBrowser.Server.Implementations.Sync
return _fileSystem.GetValidFilename(filename);
}
- private async Task CacheData(Stream stream)
- {
- var cachePath = GetCachePath();
-
- await _cacheFileLock.WaitAsync().ConfigureAwait(false);
-
- try
- {
- Directory.CreateDirectory(Path.GetDirectoryName(cachePath));
- using (var fileStream = _fileSystem.GetFileStream(cachePath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
- {
- await stream.CopyToAsync(fileStream).ConfigureAwait(false);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error saving sync data to {0}", ex, cachePath);
- }
- finally
- {
- _cacheFileLock.Release();
- }
- }
-
private async Task EnsureData(CancellationToken cancellationToken)
{
if (_items == null)
{
- try
+ _logger.Debug("Getting {0} from {1}", string.Join(MediaSync.PathSeparatorString, GetRemotePath().ToArray()), _provider.Name);
+
+ var fileResult = await _provider.GetFiles(new FileQuery
+ {
+ FullPath = GetRemotePath().ToArray()
+
+ }, _target, cancellationToken).ConfigureAwait(false);
+
+ if (fileResult.Items.Length > 0)
{
- using (var stream = await _provider.GetFile(GetRemotePath(), _target, new Progress<double>(), cancellationToken))
+ using (var stream = await _provider.GetFile(fileResult.Items[0].Id, _target, new Progress<double>(), cancellationToken))
{
_items = _json.DeserializeFromStream<List<LocalItem>>(stream);
}
}
- catch (FileNotFoundException)
- {
- _items = new List<LocalItem>();
- }
- catch (DirectoryNotFoundException)
+ else
{
_items = new List<LocalItem>();
}
-
- using (var memoryStream = new MemoryStream())
- {
- _json.SerializeToStream(_items, memoryStream);
-
- // Now cache it
- memoryStream.Position = 0;
- await CacheData(memoryStream).ConfigureAwait(false);
- }
}
}
@@ -130,10 +94,6 @@ namespace MediaBrowser.Server.Implementations.Sync
// Save to sync provider
stream.Position = 0;
await _provider.SendFile(stream, GetRemotePath(), _target, new Progress<double>(), cancellationToken).ConfigureAwait(false);
-
- // Now cache it
- stream.Position = 0;
- await CacheData(stream).ConfigureAwait(false);
}
}
@@ -171,14 +131,9 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- public Task<List<string>> GetServerItemIds(SyncTarget target, string serverId)
+ public Task<List<LocalItem>> GetLocalItems(SyncTarget target, string serverId)
{
- return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.ItemId).ToList());
- }
-
- public Task<List<string>> GetSyncJobItemIds(SyncTarget target, string serverId)
- {
- return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.SyncJobItemId).Where(i => !string.IsNullOrWhiteSpace(i)).ToList());
+ return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).ToList());
}
public Task AddOrUpdate(SyncTarget target, LocalItem item)
@@ -204,62 +159,14 @@ namespace MediaBrowser.Server.Implementations.Sync
return GetData(items => items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)));
}
- private async Task<List<LocalItem>> GetCachedData()
- {
- if (_items == null)
- {
- await _cacheFileLock.WaitAsync().ConfigureAwait(false);
-
- try
- {
- if (_items == null)
- {
- try
- {
- _items = _json.DeserializeFromFile<List<LocalItem>>(GetCachePath());
- }
- catch (FileNotFoundException)
- {
- _items = new List<LocalItem>();
- }
- catch (DirectoryNotFoundException)
- {
- _items = new List<LocalItem>();
- }
- }
- }
- finally
- {
- _cacheFileLock.Release();
- }
- }
-
- return _items.ToList();
- }
-
- public async Task<List<string>> GetCachedServerItemIds(SyncTarget target, string serverId)
- {
- var items = await GetCachedData().ConfigureAwait(false);
-
- return items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase))
- .Select(i => i.ItemId)
- .ToList();
- }
-
- public async Task<List<LocalItem>> GetCachedItems(SyncTarget target, string serverId, string itemId)
+ public Task<List<LocalItem>> GetItems(SyncTarget target, string serverId, string itemId)
{
- var items = await GetCachedData().ConfigureAwait(false);
-
- return items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.ItemId, itemId, StringComparison.OrdinalIgnoreCase))
- .ToList();
+ return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.ItemId, itemId, StringComparison.OrdinalIgnoreCase)).ToList());
}
- public async Task<List<LocalItem>> GetCachedItemsBySyncJobItemId(SyncTarget target, string serverId, string syncJobItemId)
+ public Task<List<LocalItem>> GetItemsBySyncJobItemId(SyncTarget target, string serverId, string syncJobItemId)
{
- var items = await GetCachedData().ConfigureAwait(false);
-
- return items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.SyncJobItemId, syncJobItemId, StringComparison.OrdinalIgnoreCase))
- .ToList();
+ return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.SyncJobItemId, syncJobItemId, StringComparison.OrdinalIgnoreCase)).ToList());
}
}
}