aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-03-07 23:44:31 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-03-07 23:44:31 -0500
commitd9518be3ed3923d3fd2ff4470c9dfbd7c80ad8d9 (patch)
tree5a8b603737aeda218d8a3c27247e8ea7e3832214
parent43f0a1bbfe36e76cee773a6ba774b2b0dd7c3740 (diff)
update server sync
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs2
-rw-r--r--MediaBrowser.Api/Sync/SyncService.cs34
-rw-r--r--MediaBrowser.Controller/Sync/IServerSyncProvider.cs12
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs7
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs5
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs10
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs2
-rw-r--r--MediaBrowser.Model/ApiClient/ApiClientExtensions.cs9
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs7
-rw-r--r--MediaBrowser.Model/Sync/SyncDialogOptions.cs24
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj1
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MediaSync.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs14
-rw-r--r--MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs242
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs7
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Model.Signed.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
24 files changed, 349 insertions, 70 deletions
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index b99b3f77d..35ecbd142 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -154,7 +154,7 @@ namespace MediaBrowser.Api.Playback.Hls
throw;
}
- await WaitForMinimumSegmentCount(playlistPath, 2, cancellationTokenSource.Token).ConfigureAwait(false);
+ await WaitForMinimumSegmentCount(playlistPath, 1, cancellationTokenSource.Token).ConfigureAwait(false);
}
}
}
diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs
index 3f57ca2a0..06c2dc2df 100644
--- a/MediaBrowser.Api/Sync/SyncService.cs
+++ b/MediaBrowser.Api/Sync/SyncService.cs
@@ -94,6 +94,9 @@ namespace MediaBrowser.Api.Sync
[ApiMember(Name = "ParentId", Description = "ParentId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ParentId { get; set; }
+ [ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string TargetId { get; set; }
+
[ApiMember(Name = "Category", Description = "Category", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public SyncCategory? Category { get; set; }
}
@@ -226,6 +229,13 @@ namespace MediaBrowser.Api.Sync
result.Targets = _syncManager.GetSyncTargets(request.UserId)
.ToList();
+ if (!string.IsNullOrWhiteSpace(request.TargetId))
+ {
+ result.Targets = result.Targets
+ .Where(i => string.Equals(i.Id, request.TargetId, StringComparison.OrdinalIgnoreCase))
+ .ToList();
+ }
+
if (request.Category.HasValue)
{
result.Options = SyncHelper.GetSyncOptions(request.Category.Value);
@@ -254,6 +264,30 @@ namespace MediaBrowser.Api.Sync
result.Options = SyncHelper.GetSyncOptions(dtos);
}
+ result.QualityOptions = new List<SyncQualityOption>
+ {
+ new SyncQualityOption
+ {
+ Name = SyncQuality.Original.ToString(),
+ Id = SyncQuality.Original.ToString()
+ },
+ new SyncQualityOption
+ {
+ Name = SyncQuality.High.ToString(),
+ Id = SyncQuality.High.ToString()
+ },
+ new SyncQualityOption
+ {
+ Name = SyncQuality.Medium.ToString(),
+ Id = SyncQuality.Medium.ToString()
+ },
+ new SyncQualityOption
+ {
+ Name = SyncQuality.Low.ToString(),
+ Id = SyncQuality.Low.ToString()
+ }
+ };
+
return ToOptimizedResult(result);
}
diff --git a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs
index 775a3648d..98ea2ce06 100644
--- a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs
+++ b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs
@@ -12,13 +12,13 @@ namespace MediaBrowser.Controller.Sync
/// <summary>
/// Transfers the file.
/// </summary>
- /// <param name="inputFile">The input file.</param>
- /// <param name="path">The path.</param>
+ /// <param name="stream">The stream.</param>
+ /// <param name="remotePath">The remote path.</param>
/// <param name="target">The target.</param>
/// <param name="progress">The progress.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- Task SendFile(string inputFile, string path, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
+ Task SendFile(Stream stream, string remotePath, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken);
/// <summary>
/// Deletes the file.
@@ -62,11 +62,5 @@ namespace MediaBrowser.Controller.Sync
/// <param name="target">The target.</param>
/// <returns>Task&lt;List&lt;DeviceFileInfo&gt;&gt;.</returns>
Task<List<DeviceFileInfo>> GetFileSystemEntries(string path, SyncTarget target);
-
- /// <summary>
- /// Gets the data provider.
- /// </summary>
- /// <returns>ISyncDataProvider.</returns>
- ISyncDataProvider GetDataProvider();
}
}
diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs
index 75f1579ac..2ab27fde5 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs
@@ -25,6 +25,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
private readonly IUserManager _userManager;
private readonly ILocalizationManager _localization;
private readonly IChannelManager _channelManager;
+ private readonly IMediaSourceManager _mediaSourceManager;
public ContentDirectory(IDlnaManager dlna,
IUserDataManager userDataManager,
@@ -33,7 +34,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
IServerConfigurationManager config,
IUserManager userManager,
ILogger logger,
- IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager)
+ IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager)
: base(logger, httpClient)
{
_dlna = dlna;
@@ -44,6 +45,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
_userManager = userManager;
_localization = localization;
_channelManager = channelManager;
+ _mediaSourceManager = mediaSourceManager;
}
private int SystemUpdateId
@@ -83,7 +85,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
SystemUpdateId,
_config,
_localization,
- _channelManager)
+ _channelManager,
+ _mediaSourceManager)
.ProcessControlRequest(request);
}
diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
index 17a9e7dc0..5ccea52ba 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
@@ -46,9 +46,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
private readonly DidlBuilder _didlBuilder;
private readonly DeviceProfile _profile;
- private readonly IMediaSourceManager _mediaSourceManager;
- public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager)
+ public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager)
: base(config, logger)
{
_libraryManager = libraryManager;
@@ -59,7 +58,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
_profile = profile;
_config = config;
- _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, _mediaSourceManager);
+ _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager);
}
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, Headers methodParams)
diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
index 52221d349..a6a87a3fc 100644
--- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
public class AudioEncoder : BaseEncoder
{
- public AudioEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder) : base(mediaEncoder, logger, configurationManager, fileSystem, liveTvManager, isoManager, libraryManager, channelManager, sessionManager, subtitleEncoder)
+ public AudioEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager) : base(mediaEncoder, logger, configurationManager, fileSystem, liveTvManager, isoManager, libraryManager, channelManager, sessionManager, subtitleEncoder, mediaSourceManager)
{
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index ead080c60..6ddc3487d 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -36,6 +36,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
protected readonly IChannelManager ChannelManager;
protected readonly ISessionManager SessionManager;
protected readonly ISubtitleEncoder SubtitleEncoder;
+ protected readonly IMediaSourceManager MediaSourceManager;
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
@@ -47,7 +48,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
IIsoManager isoManager,
ILibraryManager libraryManager,
IChannelManager channelManager,
- ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder)
+ ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager)
{
MediaEncoder = mediaEncoder;
Logger = logger;
@@ -59,13 +60,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
ChannelManager = channelManager;
SessionManager = sessionManager;
SubtitleEncoder = subtitleEncoder;
+ MediaSourceManager = mediaSourceManager;
}
public async Task<EncodingJob> Start(EncodingJobOptions options,
IProgress<double> progress,
CancellationToken cancellationToken)
{
- var encodingJob = await new EncodingJobFactory(Logger, LiveTvManager, LibraryManager, ChannelManager)
+ var encodingJob = await new EncodingJobFactory(Logger, LiveTvManager, LibraryManager, ChannelManager, MediaSourceManager)
.CreateJob(options, IsVideoEncoder, progress, cancellationToken).ConfigureAwait(false);
encodingJob.OutputFilePath = GetOutputFilePath(encodingJob);
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
index 3488551dc..916174c4b 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
@@ -4,7 +4,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
@@ -23,16 +22,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly ILiveTvManager _liveTvManager;
private readonly ILibraryManager _libraryManager;
private readonly IChannelManager _channelManager;
- private IMediaSourceManager _mediaSourceManager;
+ private readonly IMediaSourceManager _mediaSourceManager;
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- public EncodingJobFactory(ILogger logger, ILiveTvManager liveTvManager, ILibraryManager libraryManager, IChannelManager channelManager)
+ public EncodingJobFactory(ILogger logger, ILiveTvManager liveTvManager, ILibraryManager libraryManager, IChannelManager channelManager, IMediaSourceManager mediaSourceManager)
{
_logger = logger;
_liveTvManager = liveTvManager;
_libraryManager = libraryManager;
_channelManager = channelManager;
+ _mediaSourceManager = mediaSourceManager;
}
public async Task<EncodingJob> CreateJob(EncodingJobOptions options, bool isVideoRequest, IProgress<double> progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index b75d7bee3..7fd91bf6f 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -70,8 +70,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
protected readonly IChannelManager ChannelManager;
protected readonly ISessionManager SessionManager;
protected readonly Func<ISubtitleEncoder> SubtitleEncoder;
+ protected readonly Func<IMediaSourceManager> MediaSourceManager;
- public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder)
+ public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
@@ -84,6 +85,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
ChannelManager = channelManager;
SessionManager = sessionManager;
SubtitleEncoder = subtitleEncoder;
+ MediaSourceManager = mediaSourceManager;
FFProbePath = ffProbePath;
FFMpegPath = ffMpegPath;
}
@@ -580,7 +582,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
LibraryManager,
ChannelManager,
SessionManager,
- SubtitleEncoder())
+ SubtitleEncoder(),
+ MediaSourceManager())
.Start(options, progress, cancellationToken).ConfigureAwait(false);
await job.TaskCompletionSource.Task.ConfigureAwait(false);
@@ -601,7 +604,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
LibraryManager,
ChannelManager,
SessionManager,
- SubtitleEncoder())
+ SubtitleEncoder(),
+ MediaSourceManager())
.Start(options, progress, cancellationToken).ConfigureAwait(false);
await job.TaskCompletionSource.Task.ConfigureAwait(false);
diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
index 941649add..efd0bd909 100644
--- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
public class VideoEncoder : BaseEncoder
{
- public VideoEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder) : base(mediaEncoder, logger, configurationManager, fileSystem, liveTvManager, isoManager, libraryManager, channelManager, sessionManager, subtitleEncoder)
+ public VideoEncoder(MediaEncoder mediaEncoder, ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, ISubtitleEncoder subtitleEncoder, IMediaSourceManager mediaSourceManager) : base(mediaEncoder, logger, configurationManager, fileSystem, liveTvManager, isoManager, libraryManager, channelManager, sessionManager, subtitleEncoder, mediaSourceManager)
{
}
diff --git a/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs b/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs
index b5bf29990..4ae4fe822 100644
--- a/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs
+++ b/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs
@@ -35,7 +35,14 @@ namespace MediaBrowser.Model.ApiClient
public static Task<SyncDialogOptions> GetSyncOptions(this IApiClient apiClient, SyncJob job)
{
- return apiClient.GetSyncOptions(job.RequestedItemIds, job.UserId, job.ParentId, job.Category);
+ return apiClient.GetSyncOptions(new SyncJobRequest
+ {
+ Category = job.Category,
+ ItemIds = job.RequestedItemIds,
+ ParentId = job.ParentId,
+ TargetId = job.TargetId,
+ UserId = job.UserId
+ });
}
}
}
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index ca49c6c5a..ebf3dd6bd 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -1519,11 +1519,8 @@ namespace MediaBrowser.Model.ApiClient
/// <summary>
/// Gets the synchronize options.
/// </summary>
- /// <param name="userId">The user identifier.</param>
- /// <param name="itemIds">The item ids.</param>
- /// <param name="parentId">The parent identifier.</param>
- /// <param name="category">The category.</param>
+ /// <param name="jobInfo">The job information.</param>
/// <returns>Task&lt;SyncOptions&gt;.</returns>
- Task<SyncDialogOptions> GetSyncOptions(IEnumerable<string> itemIds, string userId, string parentId = null, SyncCategory? category = null);
+ Task<SyncDialogOptions> GetSyncOptions(SyncJobRequest jobInfo);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/Sync/SyncDialogOptions.cs b/MediaBrowser.Model/Sync/SyncDialogOptions.cs
index 751fbbb13..080f7f2a8 100644
--- a/MediaBrowser.Model/Sync/SyncDialogOptions.cs
+++ b/MediaBrowser.Model/Sync/SyncDialogOptions.cs
@@ -24,29 +24,7 @@ namespace MediaBrowser.Model.Sync
{
Targets = new List<SyncTarget>();
Options = new List<SyncJobOption>();
- QualityOptions = new List<SyncQualityOption>
- {
- new SyncQualityOption
- {
- Name = SyncQuality.Original.ToString(),
- Id = SyncQuality.Original.ToString()
- },
- new SyncQualityOption
- {
- Name = SyncQuality.High.ToString(),
- Id = SyncQuality.High.ToString()
- },
- new SyncQualityOption
- {
- Name = SyncQuality.Medium.ToString(),
- Id = SyncQuality.Medium.ToString()
- },
- new SyncQualityOption
- {
- Name = SyncQuality.Low.ToString(),
- Id = SyncQuality.Low.ToString()
- }
- };
+ QualityOptions = new List<SyncQualityOption>();
}
}
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 607ba3c41..41f970041 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -316,6 +316,7 @@
<Compile Include="Sync\SyncManager.cs" />
<Compile Include="Sync\SyncRepository.cs" />
<Compile Include="Sync\SyncConvertScheduledTask.cs" />
+ <Compile Include="Sync\TargetDataProvider.cs" />
<Compile Include="Themes\AppThemeManager.cs" />
<Compile Include="TV\TVSeriesManager.cs" />
<Compile Include="Udp\UdpMessageReceivedEventArgs.cs" />
diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
index 70c366bf5..246a82b20 100644
--- a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
@@ -206,9 +206,12 @@ namespace MediaBrowser.Server.Implementations.Sync
await dataProvider.Delete(target, localId).ConfigureAwait(false);
}
- private Task SendFile(IServerSyncProvider provider, string inputPath, LocalItem item, SyncTarget target, CancellationToken cancellationToken)
+ private async Task SendFile(IServerSyncProvider provider, string inputPath, LocalItem item, SyncTarget target, CancellationToken cancellationToken)
{
- return provider.SendFile(inputPath, item.LocalPath, target, new Progress<double>(), cancellationToken);
+ using (var stream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
+ {
+ await provider.SendFile(stream, item.LocalPath, target, new Progress<double>(), cancellationToken).ConfigureAwait(false);
+ }
}
private string GetLocalId(string serverId, string itemId)
diff --git a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
index cbfa82f1d..a8bc24c2a 100644
--- a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
@@ -14,12 +14,12 @@ namespace MediaBrowser.Server.Implementations.Sync
{
public class MultiProviderSync
{
- private readonly ISyncManager _syncManager;
+ private readonly SyncManager _syncManager;
private readonly IServerApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
- public MultiProviderSync(ISyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem)
+ public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem)
{
_syncManager = syncManager;
_appHost = appHost;
@@ -54,8 +54,10 @@ namespace MediaBrowser.Server.Implementations.Sync
progress.Report(totalProgress);
});
+ var dataProvider = _syncManager.GetDataProvider(target.Item1, target.Item2);
+
await new MediaSync(_logger, _syncManager, _appHost, _fileSystem)
- .Sync(target.Item1, target.Item1.GetDataProvider(), target.Item2, innerProgress, cancellationToken)
+ .Sync(target.Item1, dataProvider, target.Item2, innerProgress, cancellationToken)
.ConfigureAwait(false);
numComplete++;
diff --git a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
index 170860dc2..33b1e13bd 100644
--- a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
@@ -46,7 +46,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
- return new MultiProviderSync(_syncManager, _appHost, _logger, _fileSystem)
+ return new MultiProviderSync((SyncManager)_syncManager, _appHost, _logger, _fileSystem)
.Sync(ServerSyncProviders, progress, cancellationToken);
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index d0d65d437..8474cc8c5 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -21,10 +21,12 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Sync;
using MediaBrowser.Model.Users;
using MoreLinq;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -49,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IConfigurationManager _config;
private readonly IUserDataManager _userDataManager;
private readonly Func<IMediaSourceManager> _mediaSourceManager;
+ private readonly IJsonSerializer _json;
private ISyncProvider[] _providers = { };
@@ -58,7 +61,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
- public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager)
+ public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json)
{
_libraryManager = libraryManager;
_repo = repo;
@@ -74,6 +77,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_config = config;
_userDataManager = userDataManager;
_mediaSourceManager = mediaSourceManager;
+ _json = json;
}
public void AddParts(IEnumerable<ISyncProvider> providers)
@@ -86,6 +90,14 @@ namespace MediaBrowser.Server.Implementations.Sync
get { return _providers.OfType<IServerSyncProvider>(); }
}
+ private readonly ConcurrentDictionary<string, ISyncDataProvider> _dataProviders =
+ new ConcurrentDictionary<string, ISyncDataProvider>(StringComparer.OrdinalIgnoreCase);
+
+ public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target)
+ {
+ return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost.SystemId, _logger, _json, _fileSystem, _config.CommonApplicationPaths));
+ }
+
public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
{
var processor = GetSyncJobProcessor();
diff --git a/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs b/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs
new file mode 100644
index 000000000..d068a9e4a
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs
@@ -0,0 +1,242 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Sync;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+ public class TargetDataProvider : ISyncDataProvider
+ {
+ private readonly SyncTarget _target;
+ private readonly IServerSyncProvider _provider;
+
+ private readonly SemaphoreSlim _dataLock = new SemaphoreSlim(1, 1);
+ private List<LocalItem> _items;
+
+ private readonly ILogger _logger;
+ private readonly IJsonSerializer _json;
+ private readonly IFileSystem _fileSystem;
+ private readonly IApplicationPaths _appPaths;
+ private readonly string _serverId;
+
+ private readonly SemaphoreSlim _cacheFileLock = new SemaphoreSlim(1, 1);
+
+ public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, string serverId, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
+ {
+ _logger = logger;
+ _json = json;
+ _provider = provider;
+ _target = target;
+ _fileSystem = fileSystem;
+ _appPaths = appPaths;
+ _serverId = serverId;
+ }
+
+ private string GetCachePath()
+ {
+ return Path.Combine(_appPaths.DataPath, "sync", _target.Id.GetMD5().ToString("N") + ".json");
+ }
+
+ private string GetRemotePath()
+ {
+ var parts = new List<string>
+ {
+ _serverId,
+ "data.json"
+ };
+
+ return _provider.GetFullPath(parts, _target);
+ }
+
+ 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
+ {
+ using (var stream = await _provider.GetFile(GetRemotePath(), _target, new Progress<double>(), cancellationToken))
+ {
+ _items = _json.DeserializeFromStream<List<LocalItem>>(stream);
+ }
+ }
+ catch (FileNotFoundException)
+ {
+ _items = new List<LocalItem>();
+ }
+ catch (DirectoryNotFoundException)
+ {
+ _items = new List<LocalItem>();
+ }
+
+ using (var memoryStream = new MemoryStream())
+ {
+ _json.SerializeToStream(_items, memoryStream);
+
+ // Now cache it
+ memoryStream.Position = 0;
+ await CacheData(memoryStream).ConfigureAwait(false);
+ }
+ }
+ }
+
+ private async Task SaveData(CancellationToken cancellationToken)
+ {
+ using (var stream = new MemoryStream())
+ {
+ _json.SerializeToStream(_items, stream);
+
+ // 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);
+ }
+ }
+
+ private async Task<T> GetData<T>(Func<List<LocalItem>, T> dataFactory)
+ {
+ await _dataLock.WaitAsync().ConfigureAwait(false);
+
+ try
+ {
+ await EnsureData(CancellationToken.None).ConfigureAwait(false);
+
+ return dataFactory(_items);
+ }
+ finally
+ {
+ _dataLock.Release();
+ }
+ }
+
+ private async Task UpdateData(Func<List<LocalItem>, List<LocalItem>> action)
+ {
+ await _dataLock.WaitAsync().ConfigureAwait(false);
+
+ try
+ {
+ await EnsureData(CancellationToken.None).ConfigureAwait(false);
+
+ _items = action(_items);
+
+ await SaveData(CancellationToken.None).ConfigureAwait(false);
+ }
+ finally
+ {
+ _dataLock.Release();
+ }
+ }
+
+ public Task<List<string>> GetServerItemIds(SyncTarget target, string serverId)
+ {
+ return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.ItemId).ToList());
+ }
+
+ public Task AddOrUpdate(SyncTarget target, LocalItem item)
+ {
+ return UpdateData(items =>
+ {
+ var list = items.Where(i => !string.Equals(i.Id, item.Id, StringComparison.OrdinalIgnoreCase))
+ .ToList();
+
+ list.Add(item);
+
+ return list;
+ });
+ }
+
+ public Task Delete(SyncTarget target, string id)
+ {
+ return UpdateData(items => items.Where(i => !string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)).ToList());
+ }
+
+ public Task<LocalItem> Get(SyncTarget target, string id)
+ {
+ 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<LocalItem> GetCachedItem(SyncTarget target, string id)
+ {
+ var items = await GetCachedData().ConfigureAwait(false);
+
+ return items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 4eb510f18..1c8e14f9e 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -447,7 +447,7 @@ namespace MediaBrowser.Server.Startup.Common
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager);
RegisterSingleInstance(TVSeriesManager);
- SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager);
+ SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager, () => DtoService, this, TVSeriesManager, () => MediaEncoder, FileSystemManager, () => SubtitleEncoder, ServerConfigurationManager, UserDataManager, () => MediaSourceManager, JsonSerializer);
RegisterSingleInstance(SyncManager);
DtoService = new DtoService(LogManager.GetLogger("DtoService"), LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this, () => DeviceManager, () => MediaSourceManager);
@@ -500,7 +500,7 @@ namespace MediaBrowser.Server.Startup.Common
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, playlistManager, CollectionManager, ServerConfigurationManager);
RegisterSingleInstance(UserViewManager);
- var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager);
+ var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager);
RegisterSingleInstance<IContentDirectory>(contentDirectory);
var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager);
@@ -573,7 +573,8 @@ namespace MediaBrowser.Server.Startup.Common
LibraryManager,
ChannelManager,
SessionManager,
- () => SubtitleEncoder);
+ () => SubtitleEncoder,
+ () => MediaSourceManager);
RegisterSingleInstance(MediaEncoder);
}
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 94d843174..05c2807c0 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.581</version>
+ <version>3.0.582</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.581" />
+ <dependency id="MediaBrowser.Common" version="3.0.582" />
<dependency id="NLog" version="3.2.0.0" />
<dependency id="SimpleInjector" version="2.7.0" />
</dependencies>
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 578cda06a..8d6ecd1a1 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.581</version>
+ <version>3.0.582</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
index ae5e261f9..c907f9c51 100644
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ b/Nuget/MediaBrowser.Model.Signed.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Model.Signed</id>
- <version>3.0.581</version>
+ <version>3.0.582</version>
<title>MediaBrowser.Model - Signed Edition</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index d3de0bb79..31064cfe0 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.581</version>
+ <version>3.0.582</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.581" />
+ <dependency id="MediaBrowser.Common" version="3.0.582" />
</dependencies>
</metadata>
<files>