sync updates

pull/702/head
Luke Pulverenti 10 years ago
parent 9e809b06c4
commit f636c10e24

@ -3,7 +3,6 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using ServiceStack; using ServiceStack;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -18,7 +17,6 @@ namespace MediaBrowser.Api.Library
/// Class GetDefaultVirtualFolders /// Class GetDefaultVirtualFolders
/// </summary> /// </summary>
[Route("/Library/VirtualFolders", "GET")] [Route("/Library/VirtualFolders", "GET")]
[Route("/Users/{UserId}/VirtualFolders", "GET")]
public class GetVirtualFolders : IReturn<List<VirtualFolderInfo>> public class GetVirtualFolders : IReturn<List<VirtualFolderInfo>>
{ {
/// <summary> /// <summary>
@ -143,11 +141,6 @@ namespace MediaBrowser.Api.Library
/// </summary> /// </summary>
private readonly IServerApplicationPaths _appPaths; private readonly IServerApplicationPaths _appPaths;
/// <summary>
/// The _user manager
/// </summary>
private readonly IUserManager _userManager;
/// <summary> /// <summary>
/// The _library manager /// The _library manager
/// </summary> /// </summary>
@ -156,27 +149,21 @@ namespace MediaBrowser.Api.Library
private readonly ILibraryMonitor _libraryMonitor; private readonly ILibraryMonitor _libraryMonitor;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LibraryStructureService"/> class. /// Initializes a new instance of the <see cref="LibraryStructureService" /> class.
/// </summary> /// </summary>
/// <param name="appPaths">The app paths.</param> public LibraryStructureService(IServerApplicationPaths appPaths, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem)
/// <param name="userManager">The user manager.</param>
/// <param name="libraryManager">The library manager.</param>
public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger)
{ {
if (appPaths == null) if (appPaths == null)
{ {
throw new ArgumentNullException("appPaths"); throw new ArgumentNullException("appPaths");
} }
_userManager = userManager;
_appPaths = appPaths; _appPaths = appPaths;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_libraryMonitor = libraryMonitor; _libraryMonitor = libraryMonitor;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_logger = logger;
} }
/// <summary> /// <summary>
@ -186,20 +173,9 @@ namespace MediaBrowser.Api.Library
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public object Get(GetVirtualFolders request) public object Get(GetVirtualFolders request)
{ {
if (string.IsNullOrEmpty(request.UserId)) var result = _libraryManager.GetVirtualFolders().OrderBy(i => i.Name).ToList();
{
var result = _libraryManager.GetDefaultVirtualFolders().OrderBy(i => i.Name).ToList();
return ToOptimizedSerializedResultUsingCache(result); return ToOptimizedSerializedResultUsingCache(result);
}
else
{
var user = _userManager.GetUserById(request.UserId);
var result = _libraryManager.GetVirtualFolders(user).OrderBy(i => i.Name).ToList();
return ToOptimizedSerializedResultUsingCache(result);
}
} }
/// <summary> /// <summary>

@ -141,7 +141,7 @@ namespace MediaBrowser.Api.ScheduledTasks
result = result.Where(i => result = result.Where(i =>
{ {
var isEnabled = false; var isEnabled = true;
var configurableTask = i.ScheduledTask as IConfigurableScheduledTask; var configurableTask = i.ScheduledTask as IConfigurableScheduledTask;

@ -63,6 +63,7 @@ namespace MediaBrowser.Api
_config.Configuration.IsStartupWizardCompleted = true; _config.Configuration.IsStartupWizardCompleted = true;
_config.Configuration.EnableLocalizedGuids = true; _config.Configuration.EnableLocalizedGuids = true;
_config.Configuration.StoreArtistsInMetadata = true; _config.Configuration.StoreArtistsInMetadata = true;
_config.Configuration.EnableStandaloneMetadata = true;
_config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableLibraryMetadataSubFolder = true;
_config.SaveConfiguration(); _config.SaveConfiguration();
} }

@ -37,6 +37,20 @@ namespace MediaBrowser.Api.Sync
{ {
} }
[Route("/Sync/JobItems/{Id}/Enable", "POST", Summary = "Enables a cancelled or queued sync job item")]
public class EnableSyncJobItem : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
}
[Route("/Sync/JobItems/{Id}", "DELETE", Summary = "Cancels a sync job item")]
public class CancelSyncJobItem : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; }
}
[Route("/Sync/Jobs", "GET", Summary = "Gets sync jobs.")] [Route("/Sync/Jobs", "GET", Summary = "Gets sync jobs.")]
public class GetSyncJobs : SyncJobQuery, IReturn<QueryResult<SyncJob>> public class GetSyncJobs : SyncJobQuery, IReturn<QueryResult<SyncJob>>
{ {
@ -271,5 +285,19 @@ namespace MediaBrowser.Api.Sync
return ToStaticFileResult(file.Path); return ToStaticFileResult(file.Path);
} }
public void Post(EnableSyncJobItem request)
{
var task = _syncManager.ReEnableJobItem(request.Id);
Task.WaitAll(task);
}
public void Delete(CancelSyncJobItem request)
{
var task = _syncManager.CancelJobItem(request.Id);
Task.WaitAll(task);
}
} }
} }

@ -14,9 +14,19 @@ namespace MediaBrowser.Controller.Channels
public override bool IsVisible(User user) public override bool IsVisible(User user)
{ {
if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) if (user.Policy.BlockedChannels != null)
{ {
return false; if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
{
return false;
}
}
else
{
if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
{
return false;
}
} }
return base.IsVisible(user); return base.IsVisible(user);

@ -303,9 +303,22 @@ namespace MediaBrowser.Controller.Entities
{ {
if (this is ICollectionFolder) if (this is ICollectionFolder)
{ {
if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) if (user.Policy.BlockedMediaFolders != null)
{ {
return false; if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) ||
// Backwards compatibility
user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
}
else
{
if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
{
return false;
}
} }
} }
@ -675,12 +688,12 @@ namespace MediaBrowser.Controller.Entities
path = System.IO.Path.GetDirectoryName(path); path = System.IO.Path.GetDirectoryName(path);
} }
if (ContainsPath(LibraryManager.GetDefaultVirtualFolders(), originalPath)) if (ContainsPath(LibraryManager.GetVirtualFolders(), originalPath))
{ {
return true; return true;
} }
return UserManager.Users.Any(user => ContainsPath(LibraryManager.GetVirtualFolders(user), originalPath)); return ContainsPath(LibraryManager.GetVirtualFolders(), originalPath);
} }
/// <summary> /// <summary>

@ -123,14 +123,7 @@ namespace MediaBrowser.Controller.Library
/// Gets the default view. /// Gets the default view.
/// </summary> /// </summary>
/// <returns>IEnumerable{VirtualFolderInfo}.</returns> /// <returns>IEnumerable{VirtualFolderInfo}.</returns>
IEnumerable<VirtualFolderInfo> GetDefaultVirtualFolders(); IEnumerable<VirtualFolderInfo> GetVirtualFolders();
/// <summary>
/// Gets the view.
/// </summary>
/// <param name="user">The user.</param>
/// <returns>IEnumerable{VirtualFolderInfo}.</returns>
IEnumerable<VirtualFolderInfo> GetVirtualFolders(User user);
/// <summary> /// <summary>
/// Gets the item by id. /// Gets the item by id.

@ -1,8 +1,10 @@
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying; using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Sync; using MediaBrowser.Model.Sync;
using MediaBrowser.Model.Users; using MediaBrowser.Model.Users;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,6 +12,9 @@ namespace MediaBrowser.Controller.Sync
{ {
public interface ISyncManager public interface ISyncManager
{ {
event EventHandler<GenericEventArgs<SyncJob>> SyncJobCreated;
event EventHandler<GenericEventArgs<SyncJob>> SyncJobCancelled;
/// <summary> /// <summary>
/// Creates the job. /// Creates the job.
/// </summary> /// </summary>
@ -44,6 +49,20 @@ namespace MediaBrowser.Controller.Sync
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task UpdateJob(SyncJob job); Task UpdateJob(SyncJob job);
/// <summary>
/// Res the enable job item.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>Task.</returns>
Task ReEnableJobItem(string id);
/// <summary>
/// Cnacels the job item.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>Task.</returns>
Task CancelJobItem(string id);
/// <summary> /// <summary>
/// Cancels the job. /// Cancels the job.
/// </summary> /// </summary>

@ -169,6 +169,7 @@ namespace MediaBrowser.Model.Configuration
public string DashboardSourcePath { get; set; } public string DashboardSourcePath { get; set; }
public bool StoreArtistsInMetadata { get; set; } public bool StoreArtistsInMetadata { get; set; }
public bool EnableStandaloneMetadata { get; set; }
/// <summary> /// <summary>
/// Gets or sets the image saving convention. /// Gets or sets the image saving convention.

@ -88,6 +88,8 @@ namespace MediaBrowser.Model.Sync
public string TemporaryPath { get; set; } public string TemporaryPath { get; set; }
public List<ItemFileInfo> AdditionalFiles { get; set; } public List<ItemFileInfo> AdditionalFiles { get; set; }
public bool IsMarkedForRemoval { get; set; }
public SyncJobItem() public SyncJobItem()
{ {
AdditionalFiles = new List<ItemFileInfo>(); AdditionalFiles = new List<ItemFileInfo>();

@ -99,10 +99,20 @@ namespace MediaBrowser.Server.Implementations.Configuration
private void UpdateMetadataPath() private void UpdateMetadataPath()
{ {
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ? ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ?
null : GetInternalMetadataPath() :
Configuration.MetadataPath; Configuration.MetadataPath;
} }
private string GetInternalMetadataPath()
{
if (Configuration.EnableStandaloneMetadata)
{
return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
}
return null;
}
/// <summary> /// <summary>
/// Updates the transcoding temporary path. /// Updates the transcoding temporary path.
/// </summary> /// </summary>

@ -1124,21 +1124,11 @@ namespace MediaBrowser.Server.Implementations.Library
/// Gets the default view. /// Gets the default view.
/// </summary> /// </summary>
/// <returns>IEnumerable{VirtualFolderInfo}.</returns> /// <returns>IEnumerable{VirtualFolderInfo}.</returns>
public IEnumerable<VirtualFolderInfo> GetDefaultVirtualFolders() public IEnumerable<VirtualFolderInfo> GetVirtualFolders()
{ {
return GetView(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath); return GetView(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath);
} }
/// <summary>
/// Gets the view.
/// </summary>
/// <param name="user">The user.</param>
/// <returns>IEnumerable{VirtualFolderInfo}.</returns>
public IEnumerable<VirtualFolderInfo> GetVirtualFolders(User user)
{
return GetDefaultVirtualFolders();
}
/// <summary> /// <summary>
/// Gets the view. /// Gets the view.
/// </summary> /// </summary>

@ -3,7 +3,6 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO; using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Connect; using MediaBrowser.Controller.Connect;
using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Drawing;
@ -13,7 +12,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Connect; using MediaBrowser.Model.Connect;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
@ -72,12 +70,10 @@ namespace MediaBrowser.Server.Implementations.Library
private readonly Func<IImageProcessor> _imageProcessorFactory; private readonly Func<IImageProcessor> _imageProcessorFactory;
private readonly Func<IDtoService> _dtoServiceFactory; private readonly Func<IDtoService> _dtoServiceFactory;
private readonly Func<IConnectManager> _connectFactory; private readonly Func<IConnectManager> _connectFactory;
private readonly Func<IChannelManager> _channelManager;
private readonly Func<ILibraryManager> _libraryManager;
private readonly IServerApplicationHost _appHost; private readonly IServerApplicationHost _appHost;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, Func<IChannelManager> channelManager, Func<ILibraryManager> libraryManager) public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem)
{ {
_logger = logger; _logger = logger;
UserRepository = userRepository; UserRepository = userRepository;
@ -89,8 +85,6 @@ namespace MediaBrowser.Server.Implementations.Library
_appHost = appHost; _appHost = appHost;
_jsonSerializer = jsonSerializer; _jsonSerializer = jsonSerializer;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_channelManager = channelManager;
_libraryManager = libraryManager;
ConfigurationManager = configurationManager; ConfigurationManager = configurationManager;
Users = new List<User>(); Users = new List<User>();
@ -174,8 +168,6 @@ namespace MediaBrowser.Server.Implementations.Library
foreach (var user in users) foreach (var user in users)
{ {
await DoPolicyMigration(user).ConfigureAwait(false); await DoPolicyMigration(user).ConfigureAwait(false);
await DoChannelMigration(user).ConfigureAwait(false);
await DoLibraryMigration(user).ConfigureAwait(false);
} }
// If there are no local users with admin rights, make them all admins // If there are no local users with admin rights, make them all admins
@ -354,84 +346,6 @@ namespace MediaBrowser.Server.Implementations.Library
} }
} }
private async Task DoChannelMigration(User user)
{
if (user.Policy.BlockedChannels != null)
{
if (user.Policy.BlockedChannels.Length > 0)
{
user.Policy.EnableAllChannels = false;
try
{
var channelResult = await _channelManager().GetChannelsInternal(new ChannelQuery
{
UserId = user.Id.ToString("N")
}, CancellationToken.None).ConfigureAwait(false);
user.Policy.EnabledChannels = channelResult.Items
.Select(i => i.Id.ToString("N"))
.Except(user.Policy.BlockedChannels)
.ToArray();
}
catch
{
user.Policy.EnabledChannels = new string[] { };
}
}
else
{
user.Policy.EnableAllChannels = true;
user.Policy.EnabledChannels = new string[] { };
}
user.Policy.BlockedChannels = null;
await UpdateUserPolicy(user, user.Policy, false);
}
}
private async Task DoLibraryMigration(User user)
{
if (user.Policy.BlockedMediaFolders != null)
{
if (user.Policy.BlockedMediaFolders.Length > 0)
{
user.Policy.EnableAllFolders = false;
try
{
user.Policy.EnabledFolders = _libraryManager().RootFolder
.Children
.Where(i => !user.Policy.BlockedMediaFolders.Contains(i.Name, StringComparer.OrdinalIgnoreCase) && !user.Policy.BlockedMediaFolders.Contains(i.Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
.Select(i => i.Id.ToString("N"))
.ToArray();
}
catch
{
user.Policy.EnabledFolders = new string[] { };
user.Policy.EnableAllFolders = true;
}
}
else
{
user.Policy.EnableAllFolders = true;
user.Policy.EnabledFolders = new string[] { };
}
// Just to be safe
if (user.Policy.EnabledFolders.Length == 0)
{
user.Policy.EnableAllFolders = true;
}
user.Policy.BlockedMediaFolders = null;
await UpdateUserPolicy(user, user.Policy, false);
}
}
public UserDto GetUserDto(User user, string remoteEndPoint = null) public UserDto GetUserDto(User user, string remoteEndPoint = null)
{ {
if (user == null) if (user == null)

@ -56,6 +56,9 @@
"HeaderChannelAccess": "Channel Access", "HeaderChannelAccess": "Channel Access",
"HeaderDeviceAccess": "Device Access", "HeaderDeviceAccess": "Device Access",
"HeaderSelectDevices": "Select Devices", "HeaderSelectDevices": "Select Devices",
"ButtonCancelItem": "Cancel item",
"ButtonQueueForRetry": "Queue for retry",
"ButtonReenable": "Re-enable",
"LabelAbortedByServerShutdown": "(Aborted by server shutdown)", "LabelAbortedByServerShutdown": "(Aborted by server shutdown)",
"LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.",
"HeaderDeleteTaskTrigger": "Delete Task Trigger", "HeaderDeleteTaskTrigger": "Delete Task Trigger",
@ -71,6 +74,8 @@
"LabelForcedStream": "(Forced)", "LabelForcedStream": "(Forced)",
"LabelDefaultForcedStream": "(Default/Forced)", "LabelDefaultForcedStream": "(Default/Forced)",
"LabelUnknownLanguage": "Unknown language", "LabelUnknownLanguage": "Unknown language",
"HeaderConfirmation": "Confirmation",
"MessageConfirmSyncJobItemCancellation": "Are you sure you wish to cancel this item?",
"ButtonMute": "Mute", "ButtonMute": "Mute",
"ButtonUnmute": "Unmute", "ButtonUnmute": "Unmute",
"ButtonStop": "Stop", "ButtonStop": "Stop",

@ -1,5 +1,4 @@
using System.Globalization; using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO; using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress; using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
@ -361,11 +360,20 @@ namespace MediaBrowser.Server.Implementations.Sync
var innerProgress = new ActionableProgress<double>(); var innerProgress = new ActionableProgress<double>();
innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerItem * p))); innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerItem * p)));
var job = _syncRepo.GetJob(item.JobId); // Pull it fresh from the db just to make sure it wasn't deleted or cancelled while another item was converting
await ProcessJobItem(job, item, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); var jobItem = enableConversion ? _syncRepo.GetJobItem(item.Id) : item;
job = _syncRepo.GetJob(item.JobId); if (jobItem != null)
await UpdateJobStatus(job).ConfigureAwait(false); {
var job = _syncRepo.GetJob(jobItem.JobId);
if (jobItem.Status != SyncJobItemStatus.Cancelled)
{
await ProcessJobItem(job, jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false);
}
job = _syncRepo.GetJob(jobItem.JobId);
await UpdateJobStatus(job).ConfigureAwait(false);
}
numComplete++; numComplete++;
double percent = numComplete; double percent = numComplete;

@ -1,5 +1,6 @@
using MediaBrowser.Common; using MediaBrowser.Common;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO; using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Channels;
@ -16,6 +17,7 @@ using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying; using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Sync; using MediaBrowser.Model.Sync;
@ -47,6 +49,9 @@ namespace MediaBrowser.Server.Implementations.Sync
private ISyncProvider[] _providers = { }; private ISyncProvider[] _providers = { };
public event EventHandler<GenericEventArgs<SyncJob>> SyncJobCreated;
public event EventHandler<GenericEventArgs<SyncJob>> SyncJobCancelled;
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) 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)
{ {
_libraryManager = libraryManager; _libraryManager = libraryManager;
@ -144,6 +149,15 @@ namespace MediaBrowser.Server.Implementations.Sync
await processor.SyncJobItems(jobItemsResult.Items, false, new Progress<double>(), CancellationToken.None) await processor.SyncJobItems(jobItemsResult.Items, false, new Progress<double>(), CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
if (SyncJobCreated != null)
{
EventHelper.FireEventIfNotNull(SyncJobCreated, this, new GenericEventArgs<SyncJob>
{
Argument = job
}, _logger);
}
return new SyncJobCreationResult return new SyncJobCreationResult
{ {
Job = GetJob(jobId) Job = GetJob(jobId)
@ -275,9 +289,25 @@ namespace MediaBrowser.Server.Implementations.Sync
} }
} }
public Task CancelJob(string id) public async Task CancelJob(string id)
{ {
return _repo.DeleteJob(id); var job = GetJob(id);
if (job == null)
{
throw new ArgumentException("Job not found.");
}
await _repo.DeleteJob(id).ConfigureAwait(false);
if (SyncJobCancelled != null)
{
EventHelper.FireEventIfNotNull(SyncJobCancelled, this, new GenericEventArgs<SyncJob>
{
Argument = job
}, _logger);
}
} }
public SyncJob GetJob(string id) public SyncJob GetJob(string id)
@ -496,7 +526,7 @@ namespace MediaBrowser.Server.Implementations.Sync
.FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId)); .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId));
syncedItem.Item.MediaSources = new List<MediaSourceInfo>(); syncedItem.Item.MediaSources = new List<MediaSourceInfo>();
// This will be null for items that are not audio/video // This will be null for items that are not audio/video
if (mediaSource == null) if (mediaSource == null)
{ {
@ -545,7 +575,12 @@ namespace MediaBrowser.Server.Implementations.Sync
var job = _repo.GetJob(jobItem.JobId); var job = _repo.GetJob(jobItem.JobId);
var user = _userManager.GetUserById(job.UserId); var user = _userManager.GetUserById(job.UserId);
if (user == null) if (jobItem.IsMarkedForRemoval)
{
// Tell the device to remove it since it has been marked for removal
response.ItemIdsToRemove.Add(jobItem.ItemId);
}
else if (user == null)
{ {
// Tell the device to remove it since the user is gone now // Tell the device to remove it since the user is gone now
response.ItemIdsToRemove.Add(jobItem.ItemId); response.ItemIdsToRemove.Add(jobItem.ItemId);
@ -609,5 +644,45 @@ namespace MediaBrowser.Server.Implementations.Sync
return true; return true;
} }
public async Task ReEnableJobItem(string id)
{
var jobItem = _repo.GetJobItem(id);
if (jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Cancelled)
{
throw new ArgumentException("Operation is not valid for this job item");
}
jobItem.Status = SyncJobItemStatus.Queued;
jobItem.Progress = 0;
jobItem.IsMarkedForRemoval = false;
await _repo.Update(jobItem).ConfigureAwait(false);
var processor = GetSyncJobProcessor();
await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
}
public async Task CancelJobItem(string id)
{
var jobItem = _repo.GetJobItem(id);
if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.Transferring && jobItem.Status != SyncJobItemStatus.Converting)
{
throw new ArgumentException("Operation is not valid for this job item");
}
jobItem.Status = SyncJobItemStatus.Cancelled;
jobItem.Progress = 0;
jobItem.IsMarkedForRemoval = true;
await _repo.Update(jobItem).ConfigureAwait(false);
var processor = GetSyncJobProcessor();
await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
}
} }
} }

@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public async Task Initialize() public async Task Initialize()
{ {
var dbFile = Path.Combine(_appPaths.DataPath, "sync12.db"); var dbFile = Path.Combine(_appPaths.DataPath, "sync13.db");
_connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync
"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, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent 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, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)",
"create index if not exists idx_SyncJobs on SyncJobs(Id)", "create index if not exists idx_SyncJobs on SyncJobs(Id)",
"create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT)", "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT)",
"create index if not exists idx_SyncJobItems on SyncJobs(Id)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)",
//pragmas //pragmas
@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount"); _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount");
_saveJobItemCommand = _connection.CreateCommand(); _saveJobItemCommand = _connection.CreateCommand();
_saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource)"; _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval)";
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId");
@ -110,10 +110,11 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Progress"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Progress");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource");
_saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@IsMarkedForRemoval");
} }
private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs";
private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource from SyncJobItems"; private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval from SyncJobItems";
public SyncJob GetJob(string id) public SyncJob GetJob(string id)
{ {
@ -572,6 +573,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress; _saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress;
_saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); _saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles);
_saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource);
_saveJobItemCommand.GetParameter(index++).Value = jobItem.IsMarkedForRemoval;
_saveJobItemCommand.Transaction = transaction; _saveJobItemCommand.Transaction = transaction;
@ -673,6 +675,8 @@ namespace MediaBrowser.Server.Implementations.Sync
} }
} }
info.IsMarkedForRemoval = reader.GetBoolean(13);
return info; return info;
} }

@ -407,7 +407,7 @@ namespace MediaBrowser.Server.Startup.Common
SyncRepository = await GetSyncRepository().ConfigureAwait(false); SyncRepository = await GetSyncRepository().ConfigureAwait(false);
RegisterSingleInstance(SyncRepository); RegisterSingleInstance(SyncRepository);
UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, () => ChannelManager, () => LibraryManager); UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager);
RegisterSingleInstance(UserManager); RegisterSingleInstance(UserManager);
LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager); LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager);

Loading…
Cancel
Save