diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/Sync')
4 files changed, 221 insertions, 63 deletions
diff --git a/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs index bc079ad80..7d29446b9 100644 --- a/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Server.Implementations.Sync { public string Name { - get { return "Dummy Sync"; } + get { return "Test Sync"; } } public IEnumerable<SyncTarget> GetSyncTargets() @@ -19,8 +19,8 @@ namespace MediaBrowser.Server.Implementations.Sync { new SyncTarget { - Id = "mock".GetMD5().ToString("N"), - Name = "Mock Sync" + Id = GetType().Name.GetMD5().ToString("N"), + Name = Name } }; } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs new file mode 100644 index 000000000..c7f02b3dd --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -0,0 +1,89 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Sync; +using MoreLinq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Sync +{ + public class SyncJobProcessor + { + private readonly ILibraryManager _libraryManager; + private readonly ISyncRepository _syncRepo; + + public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo) + { + _libraryManager = libraryManager; + _syncRepo = syncRepo; + } + + public void ProcessJobItem(SyncJob job, SyncJobItem jobItem, SyncTarget target) + { + + } + + public async Task EnsureJobItems(SyncJob job) + { + var items = GetItemsForSync(job.RequestedItemIds) + .ToList(); + + var jobItems = _syncRepo.GetJobItems(job.Id) + .ToList(); + + var created = 0; + + foreach (var item in items) + { + var itemId = item.Id.ToString("N"); + + var jobItem = jobItems.FirstOrDefault(i => string.Equals(i.ItemId, itemId, StringComparison.OrdinalIgnoreCase)); + + if (jobItem != null) + { + continue; + } + + jobItem = new SyncJobItem + { + Id = Guid.NewGuid().ToString("N"), + ItemId = itemId, + JobId = job.Id, + TargetId = job.TargetId + }; + + await _syncRepo.Create(jobItem).ConfigureAwait(false); + + created++; + } + + job.ItemCount = jobItems.Count + created; + await _syncRepo.Update(job).ConfigureAwait(false); + } + + public IEnumerable<BaseItem> GetItemsForSync(IEnumerable<string> itemIds) + { + return itemIds.SelectMany(GetItemsForSync).DistinctBy(i => i.Id); + } + + private IEnumerable<BaseItem> GetItemsForSync(string id) + { + var item = _libraryManager.GetItemById(id); + + if (item == null) + { + return new List<BaseItem>(); + } + + return GetItemsForSync(item); + } + + private IEnumerable<BaseItem> GetItemsForSync(BaseItem item) + { + return new[] { item }; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 201eb8c7f..0c7b5c2b9 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,11 +1,10 @@ -using System.IO; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Sync; -using MediaBrowser.Model.Devices; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; @@ -42,7 +41,14 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request) { - var items = GetItemsForSync(request.ItemIds).ToList(); + var items = new SyncJobProcessor(_libraryManager, _repo) + .GetItemsForSync(request.ItemIds) + .ToList(); + + if (items.Any(i => !SupportsSync(i))) + { + throw new ArgumentException("Item does not support sync."); + } if (items.Count == 1) { @@ -66,12 +72,14 @@ namespace MediaBrowser.Server.Implementations.Sync TargetId = target.Id, UserId = request.UserId, UnwatchedOnly = request.UnwatchedOnly, - Limit = request.Limit, - LimitType = request.LimitType, + ItemLimit = request.ItemLimit, RequestedItemIds = request.ItemIds, DateCreated = DateTime.UtcNow, DateLastModified = DateTime.UtcNow, - ItemCount = 1 + SyncNewContent = request.SyncNewContent, + RemoveWhenWatched = request.RemoveWhenWatched, + ItemCount = items.Count, + Quality = request.Quality }; await _repo.Create(job).ConfigureAwait(false); @@ -93,7 +101,8 @@ namespace MediaBrowser.Server.Implementations.Sync private void FillMetadata(SyncJob job) { - var item = GetItemsForSync(job.RequestedItemIds) + var item = new SyncJobProcessor(_libraryManager, _repo) + .GetItemsForSync(job.RequestedItemIds) .FirstOrDefault(); if (item != null) @@ -130,7 +139,11 @@ namespace MediaBrowser.Server.Implementations.Sync public Task CancelJob(string id) { - throw new NotImplementedException(); + var job = GetJob(id); + + job.Status = SyncJobStatus.Cancelled; + + return _repo.DeleteJob(id); } public SyncJob GetJob(string id) @@ -165,26 +178,26 @@ namespace MediaBrowser.Server.Implementations.Sync private string GetSyncProviderId(ISyncProvider provider) { - return (provider.GetType().Name + provider.Name).GetMD5().ToString("N"); + return (provider.GetType().Name).GetMD5().ToString("N"); } public bool SupportsSync(BaseItem item) { - if (item.LocationType == LocationType.Virtual) - { - return false; - } - if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) || string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { + if (item.LocationType == LocationType.Virtual) + { + return false; + } + if (item.RunTimeTicks.HasValue) { var video = item as Video; if (video != null) { - if (video.VideoType != VideoType.VideoFile) + if (video.VideoType == VideoType.Iso) { return false; } @@ -201,34 +214,7 @@ namespace MediaBrowser.Server.Implementations.Sync return false; } - return false; - } - - private IEnumerable<BaseItem> GetItemsForSync(IEnumerable<string> itemIds) - { - return itemIds.SelectMany(GetItemsForSync).DistinctBy(i => i.Id); - } - - private IEnumerable<BaseItem> GetItemsForSync(string id) - { - var item = _libraryManager.GetItemById(id); - - if (item == null) - { - throw new ArgumentException("Item with Id " + id + " not found."); - } - - if (!SupportsSync(item)) - { - throw new ArgumentException("Item with Id " + id + " does not support sync."); - } - - return GetItemsForSync(item); - } - - private IEnumerable<BaseItem> GetItemsForSync(BaseItem item) - { - return new[] { item }; + return item.LocationType == LocationType.FileSystem || item is Season; } private string GetDefaultName(BaseItem item) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 65da74f9e..338529043 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -23,6 +23,7 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly IServerApplicationPaths _appPaths; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + private IDbCommand _deleteJobCommand; private IDbCommand _saveJobCommand; private IDbCommand _saveJobItemCommand; @@ -34,13 +35,13 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync.db"); + var dbFile = Path.Combine(_appPaths.DataPath, "sync2.db"); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); string[] queries = { - "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, UnwatchedOnly BIT, SyncLimit BigInt, LimitType TEXT, IsDynamic BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", + "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, UnwatchedOnly BIT, ItemLimit INT, RemoveWhenWatched BIT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT)", @@ -59,8 +60,12 @@ namespace MediaBrowser.Server.Implementations.Sync private void PrepareStatements() { + _deleteJobCommand = _connection.CreateCommand(); + _deleteJobCommand.CommandText = "delete from SyncJobs where Id=@Id; delete from SyncJobItems where JobId=@Id"; + _deleteJobCommand.Parameters.Add(_deleteJobCommand, "@Id"); + _saveJobCommand = _connection.CreateCommand(); - _saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, SyncLimit, LimitType, IsDynamic, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @UnwatchedOnly, @SyncLimit, @LimitType, @IsDynamic, @DateCreated, @DateLastModified, @ItemCount)"; + _saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, ItemLimit, RemoveWhenWatched, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @UnwatchedOnly, @ItemLimit, @RemoveWhenWatched, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)"; _saveJobCommand.Parameters.Add(_saveJobCommand, "@Id"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@TargetId"); @@ -71,9 +76,9 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.Parameters.Add(_saveJobCommand, "@UserId"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemIds"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@UnwatchedOnly"); - _saveJobCommand.Parameters.Add(_saveJobCommand, "@SyncLimit"); - _saveJobCommand.Parameters.Add(_saveJobCommand, "@LimitType"); - _saveJobCommand.Parameters.Add(_saveJobCommand, "@IsDynamic"); + _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemLimit"); + _saveJobCommand.Parameters.Add(_saveJobCommand, "@RemoveWhenWatched"); + _saveJobCommand.Parameters.Add(_saveJobCommand, "@SyncNewContent"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@DateCreated"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@DateLastModified"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount"); @@ -88,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Status"); } - private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, SyncLimit, LimitType, IsDynamic, DateCreated, DateLastModified, ItemCount from SyncJobs"; + private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, ItemLimit, RemoveWhenWatched, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; private const string BaseJobItemSelectText = "select Id, ItemId, JobId, OutputPath, Status, TargetId from SyncJobItems"; public SyncJob GetJob(string id) @@ -159,15 +164,12 @@ namespace MediaBrowser.Server.Implementations.Sync if (!reader.IsDBNull(9)) { - info.Limit = reader.GetInt64(9); + info.ItemLimit = reader.GetInt32(9); } - if (!reader.IsDBNull(10)) - { - info.LimitType = (SyncLimitType)Enum.Parse(typeof(SyncLimitType), reader.GetString(10), true); - } + info.RemoveWhenWatched = reader.GetBoolean(10); + info.SyncNewContent = reader.GetBoolean(11); - info.IsDynamic = reader.GetBoolean(11); info.DateCreated = reader.GetDateTime(12).ToUniversalTime(); info.DateLastModified = reader.GetDateTime(13).ToUniversalTime(); info.ItemCount = reader.GetInt32(14); @@ -206,9 +208,9 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.GetParameter(index++).Value = job.UserId; _saveJobCommand.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray()); _saveJobCommand.GetParameter(index++).Value = job.UnwatchedOnly; - _saveJobCommand.GetParameter(index++).Value = job.Limit; - _saveJobCommand.GetParameter(index++).Value = job.LimitType; - _saveJobCommand.GetParameter(index++).Value = job.IsDynamic; + _saveJobCommand.GetParameter(index++).Value = job.ItemLimit; + _saveJobCommand.GetParameter(index++).Value = job.RemoveWhenWatched; + _saveJobCommand.GetParameter(index++).Value = job.SyncNewContent; _saveJobCommand.GetParameter(index++).Value = job.DateCreated; _saveJobCommand.GetParameter(index++).Value = job.DateLastModified; _saveJobCommand.GetParameter(index++).Value = job.ItemCount; @@ -250,6 +252,62 @@ namespace MediaBrowser.Server.Implementations.Sync } } + public async Task DeleteJob(string id) + { + if (string.IsNullOrWhiteSpace(id)) + { + throw new ArgumentNullException("id"); + } + + await _writeLock.WaitAsync().ConfigureAwait(false); + + IDbTransaction transaction = null; + + try + { + transaction = _connection.BeginTransaction(); + + var index = 0; + + _deleteJobCommand.GetParameter(index++).Value = new Guid(id); + + _deleteJobCommand.Transaction = transaction; + + _deleteJobCommand.ExecuteNonQuery(); + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + _logger.ErrorException("Failed to save record:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + + _writeLock.Release(); + } + } + public QueryResult<SyncJob> GetJobs(SyncJobQuery query) { if (query == null) @@ -336,6 +394,31 @@ namespace MediaBrowser.Server.Implementations.Sync return null; } + public IEnumerable<SyncJobItem> GetJobItems(string jobId) + { + if (string.IsNullOrEmpty(jobId)) + { + throw new ArgumentNullException("jobId"); + } + + var guid = new Guid(jobId); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = BaseJobItemSelectText + " where JobId=@Id"; + + cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + yield return GetSyncJobItem(reader); + } + } + } + } + public Task Create(SyncJobItem jobItem) { return Update(jobItem); |
