diff options
18 files changed, 250 insertions, 283 deletions
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 57855008d..4d9999b37 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -290,8 +290,6 @@ <Compile Include="Providers\IImageFileSaver.cs" /> <Compile Include="Providers\IImageProvider.cs" /> <Compile Include="Providers\IImageSaver.cs" /> - <Compile Include="Providers\IItemIdentityConverter.cs" /> - <Compile Include="Providers\IItemIdentityProvider.cs" /> <Compile Include="Providers\ILocalImageFileProvider.cs" /> <Compile Include="Providers\ILocalMetadataProvider.cs" /> <Compile Include="Providers\ImageRefreshMode.cs" /> @@ -329,8 +327,6 @@ <Compile Include="Sorting\SortHelper.cs" /> <Compile Include="Subtitles\ISubtitleManager.cs" /> <Compile Include="Subtitles\ISubtitleProvider.cs" /> - <Compile Include="Providers\ItemIdentifier.cs" /> - <Compile Include="Providers\ItemIdentities.cs" /> <Compile Include="Providers\ItemLookupInfo.cs" /> <Compile Include="Providers\MetadataRefreshOptions.cs" /> <Compile Include="Providers\ISeriesOrderManager.cs" /> diff --git a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs b/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs deleted file mode 100644 index bfdd1dbf3..000000000 --- a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentityConverter { } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs b/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs deleted file mode 100644 index 6b403bb55..000000000 --- a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentityProvider { } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 57e4ff320..a976a7f71 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -97,13 +97,11 @@ namespace MediaBrowser.Controller.Providers /// </summary> /// <param name="imageProviders">The image providers.</param> /// <param name="metadataServices">The metadata services.</param> - /// <param name="identityProviders">The identity providers.</param> - /// <param name="identityConverters">The identity converters.</param> /// <param name="metadataProviders">The metadata providers.</param> /// <param name="savers">The savers.</param> /// <param name="imageSavers">The image savers.</param> /// <param name="externalIds">The external ids.</param> - void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IItemIdentityProvider> identityProviders, IEnumerable<IItemIdentityConverter> identityConverters, IEnumerable<IMetadataProvider> metadataProviders, + void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> savers, IEnumerable<IImageSaver> imageSavers, IEnumerable<IExternalId> externalIds); @@ -190,21 +188,5 @@ namespace MediaBrowser.Controller.Providers /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{HttpResponseInfo}.</returns> Task<HttpResponseInfo> GetSearchImage(string providerName, string url, CancellationToken cancellationToken); - - /// <summary> - /// Gets the item identity providers. - /// </summary> - /// <typeparam name="TLookupInfo">The type of the t lookup information.</typeparam> - /// <returns>IEnumerable<IItemIdentityProvider<TLookupInfo, TIdentity>>.</returns> - IEnumerable<IItemIdentityProvider<TLookupInfo>> GetItemIdentityProviders<TLookupInfo>() - where TLookupInfo : ItemLookupInfo; - - /// <summary> - /// Gets the item identity converters. - /// </summary> - /// <typeparam name="TLookupInfo">The type of the t lookup information.</typeparam> - /// <returns>IEnumerable<IItemIdentityConverter<TIdentity>>.</returns> - IEnumerable<IItemIdentityConverter<TLookupInfo>> GetItemIdentityConverters<TLookupInfo>() - where TLookupInfo : ItemLookupInfo; } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemIdentifier.cs b/MediaBrowser.Controller/Providers/ItemIdentifier.cs deleted file mode 100644 index bbc6dd76c..000000000 --- a/MediaBrowser.Controller/Providers/ItemIdentifier.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Providers -{ - public static class ItemIdentifier<TLookupInfo> - where TLookupInfo : ItemLookupInfo - { - public static async Task FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken) - { - var providers = providerManager.GetItemIdentityProviders<TLookupInfo>(); - var converters = providerManager.GetItemIdentityConverters<TLookupInfo>().ToList(); - - foreach (var provider in providers) - { - await provider.Identify(item); - } - - bool changesMade = true; - - while (changesMade) - { - changesMade = false; - - foreach (var converter in converters) - { - if (await converter.Convert(item)) - { - changesMade = true; - } - } - } - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemIdentities.cs b/MediaBrowser.Controller/Providers/ItemIdentities.cs deleted file mode 100644 index 48316d0f4..000000000 --- a/MediaBrowser.Controller/Providers/ItemIdentities.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentityProvider<in TLookupInfo> : IItemIdentityProvider - where TLookupInfo : ItemLookupInfo - { - Task Identify(TLookupInfo info); - } - - public interface IItemIdentityConverter<in TLookupInfo> : IItemIdentityConverter - where TLookupInfo : ItemLookupInfo - { - Task<bool> Convert(TLookupInfo info); - } -}
\ No newline at end of file diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index b84d1b0ff..678d495cb 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -179,18 +179,6 @@ namespace MediaBrowser.Providers.Manager lookupInfo.Year = result.ProductionYear; } - private async Task FindIdentities(TIdType id, CancellationToken cancellationToken) - { - try - { - await ItemIdentifier<TIdType>.FindIdentities(id, ProviderManager, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error in FindIdentities", ex); - } - } - private DateTime GetLastRefreshDate(IHasMetadata item) { return item.DateLastRefreshed; diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index c95d58a42..29897e073 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -55,8 +55,6 @@ namespace MediaBrowser.Providers.Manager private readonly IFileSystem _fileSystem; private IMetadataService[] _metadataServices = { }; - private IItemIdentityProvider[] _identityProviders = { }; - private IItemIdentityConverter[] _identityConverters = { }; private IMetadataProvider[] _metadataProviders = { }; private IEnumerable<IMetadataSaver> _savers; private IImageSaver[] _imageSavers; @@ -92,22 +90,17 @@ namespace MediaBrowser.Providers.Manager /// </summary> /// <param name="imageProviders">The image providers.</param> /// <param name="metadataServices">The metadata services.</param> - /// <param name="identityProviders">The identity providers.</param> - /// <param name="identityConverters">The identity converters.</param> /// <param name="metadataProviders">The metadata providers.</param> /// <param name="metadataSavers">The metadata savers.</param> /// <param name="imageSavers">The image savers.</param> /// <param name="externalIds">The external ids.</param> public void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, - IEnumerable<IItemIdentityProvider> identityProviders, IEnumerable<IItemIdentityConverter> identityConverters, IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> metadataSavers, IEnumerable<IImageSaver> imageSavers, IEnumerable<IExternalId> externalIds) { ImageProviders = imageProviders.ToArray(); _metadataServices = metadataServices.OrderBy(i => i.Order).ToArray(); - _identityProviders = identityProviders.ToArray(); - _identityConverters = identityConverters.ToArray(); _metadataProviders = metadataProviders.ToArray(); _imageSavers = imageSavers.ToArray(); _externalIds = externalIds.OrderBy(i => i.Name).ToArray(); @@ -301,18 +294,6 @@ namespace MediaBrowser.Providers.Manager .ThenBy(GetDefaultOrder); } - public IEnumerable<IItemIdentityProvider<TLookupInfo>> GetItemIdentityProviders<TLookupInfo>() - where TLookupInfo : ItemLookupInfo - { - return _identityProviders.OfType<IItemIdentityProvider<TLookupInfo>>(); - } - - public IEnumerable<IItemIdentityConverter<TLookupInfo>> GetItemIdentityConverters<TLookupInfo>() - where TLookupInfo : ItemLookupInfo - { - return _identityConverters.OfType<IItemIdentityConverter<TLookupInfo>>(); - } - private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item, bool includeDisabled) { var options = GetMetadataOptions(item); diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index bbfa20738..240b2e2cc 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -177,7 +177,6 @@ <Compile Include="TV\SeriesMetadataService.cs" /> <Compile Include="TV\TheTVDB\TvdbEpisodeImageProvider.cs" /> <Compile Include="People\TvdbPersonImageProvider.cs" /> - <Compile Include="TV\TheTVDB\TvdbSeasonIdentityProvider.cs" /> <Compile Include="TV\TheTVDB\TvdbSeasonImageProvider.cs" /> <Compile Include="TV\TheTVDB\TvdbSeriesImageProvider.cs" /> <Compile Include="TV\SeasonMetadataService.cs" /> diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs index 7005ba8f5..a41a95c12 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.TV /// <summary> /// Class RemoteEpisodeProvider /// </summary> - class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IItemIdentityProvider<EpisodeInfo> + class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo> { private static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; @@ -871,86 +871,6 @@ namespace MediaBrowser.Providers.TV }); } - public Task Identify(EpisodeInfo info) - { - if (info.ProviderIds.ContainsKey(FullIdKey)) - { - return Task.FromResult<object>(null); - } - - string seriesTvdbId; - info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesTvdbId); - - if (string.IsNullOrEmpty(seriesTvdbId) || info.IndexNumber == null) - { - return Task.FromResult<object>(null); - } - - var id = new Identity(seriesTvdbId, info.ParentIndexNumber, info.IndexNumber.Value, info.IndexNumberEnd); - info.SetProviderId(FullIdKey, id.ToString()); - - return Task.FromResult(id); - } - public int Order { get { return 0; } } - - public struct Identity - { - public string SeriesId { get; private set; } - public int? SeasonIndex { get; private set; } - public int EpisodeNumber { get; private set; } - public int? EpisodeNumberEnd { get; private set; } - - public Identity(string id) - : this() - { - this = ParseIdentity(id).Value; - } - - public Identity(string seriesId, int? seasonIndex, int episodeNumber, int? episodeNumberEnd) - : this() - { - SeriesId = seriesId; - SeasonIndex = seasonIndex; - EpisodeNumber = episodeNumber; - EpisodeNumberEnd = episodeNumberEnd; - } - - public override string ToString() - { - return string.Format("{0}:{1}:{2}", - SeriesId, - SeasonIndex != null ? SeasonIndex.Value.ToString() : "A", - EpisodeNumber + (EpisodeNumberEnd != null ? "-" + EpisodeNumberEnd.Value.ToString() : "")); - } - - public static Identity? ParseIdentity(string id) - { - if (string.IsNullOrEmpty(id)) - return null; - - try { - var parts = id.Split(':'); - var series = parts[0]; - var season = parts[1] != "A" ? (int?)int.Parse(parts[1]) : null; - - int index; - int? indexEnd; - - if (parts[2].Contains("-")) { - var split = parts[2].IndexOf("-", StringComparison.OrdinalIgnoreCase); - index = int.Parse(parts[2].Substring(0, split)); - indexEnd = int.Parse(parts[2].Substring(split + 1)); - } else { - index = int.Parse(parts[2]); - indexEnd = null; - } - - return new Identity(series, season, index, indexEnd); - } catch { - return null; - } - } - } } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs deleted file mode 100644 index 4198430c9..000000000 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Threading.Tasks; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; - -namespace MediaBrowser.Providers.TV -{ - public class TvdbSeasonIdentityProvider : IItemIdentityProvider<SeasonInfo> - { - public static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; - - public Task Identify(SeasonInfo info) - { - string tvdbSeriesId; - if (!info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out tvdbSeriesId) || string.IsNullOrEmpty(tvdbSeriesId) || info.IndexNumber == null) - { - return Task.FromResult<object>(null); - } - - if (string.IsNullOrEmpty(info.GetProviderId(FullIdKey))) - { - var id = string.Format("{0}:{1}", tvdbSeriesId, info.IndexNumber.Value); - info.SetProviderId(FullIdKey, id); - } - - return Task.FromResult<object>(null); - } - - public static TvdbSeasonIdentity? ParseIdentity(string id) - { - if (id == null) - { - return null; - } - - try - { - var parts = id.Split(':'); - return new TvdbSeasonIdentity(parts[0], int.Parse(parts[1])); - } - catch - { - return null; - } - } - } - - public struct TvdbSeasonIdentity - { - public string SeriesId { get; private set; } - public int Index { get; private set; } - - public TvdbSeasonIdentity(string id) - : this() - { - this = TvdbSeasonIdentityProvider.ParseIdentity(id).Value; - } - - public TvdbSeasonIdentity(string seriesId, int index) - : this() - { - SeriesId = seriesId; - Index = index; - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs index 71587db97..4b619665c 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs @@ -70,21 +70,6 @@ namespace MediaBrowser.Providers.TV var seriesProviderIds = series.ProviderIds; var seasonNumber = season.IndexNumber.Value; - var identity = TvdbSeasonIdentityProvider.ParseIdentity(season.GetProviderId(TvdbSeasonIdentityProvider.FullIdKey)); - if (identity == null) - { - identity = new TvdbSeasonIdentity(series.GetProviderId(MetadataProviders.Tvdb), seasonNumber); - } - - if (identity != null) - { - var id = identity.Value; - seasonNumber = AdjustForSeriesOffset(series, id.Index); - - seriesProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - seriesProviderIds[MetadataProviders.Tvdb.ToString()] = id.SeriesId; - } - var seriesDataPath = await TvdbSeriesProvider.Current.EnsureSeriesInfo(seriesProviderIds, series.GetPreferredMetadataLanguage(), cancellationToken).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(seriesDataPath)) diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index 15b0c97ac..49ca5cdf2 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -25,7 +25,7 @@ using CommonIO; namespace MediaBrowser.Providers.TV { - public class TvdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IItemIdentityProvider<SeriesInfo>, IHasOrder + public class TvdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder { private const string TvdbSeriesOffset = "TvdbSeriesOffset"; private const string TvdbSeriesOffsetFormat = "{0}-{1}"; diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs new file mode 100644 index 000000000..74dfbc679 --- /dev/null +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using CommonIO; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.ScheduledTasks; + +namespace MediaBrowser.Server.Implementations.IO +{ + public class FileRefresher : IDisposable + { + private ILogger Logger { get; set; } + private ITaskManager TaskManager { get; set; } + private ILibraryManager LibraryManager { get; set; } + private IServerConfigurationManager ConfigurationManager { get; set; } + private readonly IFileSystem _fileSystem; + private readonly List<string> _affectedPaths = new List<string>(); + private Timer _timer; + private readonly object _timerLock = new object(); + + public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger) + { + _affectedPaths.Add(path); + + _fileSystem = fileSystem; + ConfigurationManager = configurationManager; + LibraryManager = libraryManager; + TaskManager = taskManager; + Logger = logger; + } + + private void RestartTimer() + { + lock (_timerLock) + { + if (_timer == null) + { + _timer = new Timer(OnTimerCallback, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); + } + else + { + _timer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); + } + } + } + + private async void OnTimerCallback(object state) + { + // Extend the timer as long as any of the paths are still being written to. + if (_affectedPaths.Any(IsFileLocked)) + { + Logger.Info("Timer extended."); + RestartTimer(); + return; + } + + Logger.Debug("Timer stopped."); + + DisposeTimer(); + + try + { + await ProcessPathChanges(_affectedPaths).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.ErrorException("Error processing directory changes", ex); + } + } + + private async Task ProcessPathChanges(List<string> paths) + { + var itemsToRefresh = paths + .Select(GetAffectedBaseItem) + .Where(item => item != null) + .Distinct() + .ToList(); + + foreach (var p in paths) + { + Logger.Info(p + " reports change."); + } + + // If the root folder changed, run the library task so the user can see it + if (itemsToRefresh.Any(i => i is AggregateFolder)) + { + TaskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>(); + return; + } + + foreach (var item in itemsToRefresh) + { + Logger.Info(item.Name + " (" + item.Path + ") will be refreshed."); + + try + { + await item.ChangedExternally().ConfigureAwait(false); + } + catch (IOException ex) + { + // For now swallow and log. + // Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable) + // Should we remove it from it's parent? + Logger.ErrorException("Error refreshing {0}", ex, item.Name); + } + catch (Exception ex) + { + Logger.ErrorException("Error refreshing {0}", ex, item.Name); + } + } + } + + /// <summary> + /// Gets the affected base item. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>BaseItem.</returns> + private BaseItem GetAffectedBaseItem(string path) + { + BaseItem item = null; + + while (item == null && !string.IsNullOrEmpty(path)) + { + item = LibraryManager.FindByPath(path, null); + + path = Path.GetDirectoryName(path); + } + + if (item != null) + { + // If the item has been deleted find the first valid parent that still exists + while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path)) + { + item = item.GetParent(); + + if (item == null) + { + break; + } + } + } + + return item; + } + + private bool IsFileLocked(string path) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + // Causing lockups on linux + return false; + } + + try + { + var data = _fileSystem.GetFileSystemInfo(path); + + if (!data.Exists + || data.IsDirectory + + // Opening a writable stream will fail with readonly files + || data.Attributes.HasFlag(FileAttributes.ReadOnly)) + { + return false; + } + } + catch (IOException) + { + return false; + } + catch (Exception ex) + { + Logger.ErrorException("Error getting file system info for: {0}", ex, path); + return false; + } + + // In order to determine if the file is being written to, we have to request write access + // But if the server only has readonly access, this is going to cause this entire algorithm to fail + // So we'll take a best guess about our access level + var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta + ? FileAccess.ReadWrite + : FileAccess.Read; + + try + { + using (_fileSystem.GetFileStream(path, FileMode.Open, requestedFileAccess, FileShare.ReadWrite)) + { + //file is not locked + return false; + } + } + catch (DirectoryNotFoundException) + { + // File may have been deleted + return false; + } + catch (FileNotFoundException) + { + // File may have been deleted + return false; + } + catch (IOException) + { + //the file is unavailable because it is: + //still being written to + //or being processed by another thread + //or does not exist (has already been processed) + Logger.Debug("{0} is locked.", path); + return true; + } + catch (Exception ex) + { + Logger.ErrorException("Error determining if file is locked: {0}", ex, path); + return false; + } + } + + public void DisposeTimer() + { + lock (_timerLock) + { + if (_timer != null) + { + _timer.Dispose(); + } + } + } + + public void Dispose() + { + DisposeTimer(); + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 205000fdc..25822a81b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -929,10 +929,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath); recordPath = EnsureFileUnique(recordPath, timer.Id); - _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); - activeRecordingInfo.Path = recordPath; _libraryMonitor.ReportFileSystemChangeBeginning(recordPath); + _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); + activeRecordingInfo.Path = recordPath; var duration = recordingEndDate - DateTime.UtcNow; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 336310888..28edbfcc4 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -180,6 +180,7 @@ <Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" /> <Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" /> <Compile Include="Intros\DefaultIntroProvider.cs" /> + <Compile Include="IO\FileRefresher.cs" /> <Compile Include="IO\LibraryMonitor.cs" /> <Compile Include="Library\CoreResolutionIgnoreRule.cs" /> <Compile Include="Library\LibraryManager.cs" /> diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index ec10fdaf6..b1f43d20f 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -247,7 +247,8 @@ namespace MediaBrowser.Server.Implementations.Persistence { "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", "create index if not exists idx_Type on TypedBaseItems(Type)", - "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)" + "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)", + //"create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" }; _connection.RunQueries(postQueries, Logger); @@ -1673,7 +1674,7 @@ namespace MediaBrowser.Server.Implementations.Persistence var slowThreshold = 1000; #if DEBUG - slowThreshold = 200; + slowThreshold = 100; #endif if (elapsed >= slowThreshold) diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 7b958779d..59a8a4f78 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -804,8 +804,6 @@ namespace MediaBrowser.Server.Startup.Common ProviderManager.AddParts(GetExports<IImageProvider>(), GetExports<IMetadataService>(), - GetExports<IItemIdentityProvider>(), - GetExports<IItemIdentityConverter>(), GetExports<IMetadataProvider>(), GetExports<IMetadataSaver>(), GetExports<IImageSaver>(), |
