diff options
15 files changed, 62 insertions, 328 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 180bac8ba..6543275a5 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -336,7 +336,7 @@ namespace MediaBrowser.Controller.Entities return _resolveArgs; } - set + private set { _resolveArgs = value; _resolveArgsInitialized = value != null; @@ -349,7 +349,17 @@ namespace MediaBrowser.Controller.Entities /// <param name="pathInfo">The path info.</param> public void ResetResolveArgs(FileSystemInfo pathInfo) { - ResolveArgs = CreateResolveArgs(pathInfo); + ResetResolveArgs(CreateResolveArgs(pathInfo)); + } + + public void ResetResolveArgs() + { + ResolveArgs = null; + } + + public void ResetResolveArgs(ItemResolveArgs args) + { + ResolveArgs = args; } /// <summary> @@ -887,10 +897,10 @@ namespace MediaBrowser.Controller.Entities /// <returns>true if a provider reports we changed</returns> public virtual async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) { - if (resetResolveArgs) + if (resetResolveArgs || ResolveArgs == null) { // Reload this - ResolveArgs = null; + ResetResolveArgs(); } // Refresh for the item diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 0f090f587..97ba64772 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -107,31 +107,36 @@ namespace MediaBrowser.Controller.Entities protected void AddChildrenInternal(IEnumerable<BaseItem> children) { - foreach (var child in children) + lock (_childrenSyncLock) { - AddChildInternal(child); + var newChildren = _children.ToList(); + newChildren.AddRange(children); + _children = newChildren; } } protected void AddChildInternal(BaseItem child) { - _children.Add(child); + lock (_childrenSyncLock) + { + var newChildren = _children.ToList(); + newChildren.Add(child); + _children = newChildren; + } } protected void RemoveChildrenInternal(IEnumerable<BaseItem> children) { - lock (ChildrenSyncLock) + lock (_childrenSyncLock) { - _children = new ConcurrentBag<BaseItem>(_children.Except(children)); + _children = _children.Except(children).ToList(); } } protected void ClearChildrenInternal() { - BaseItem removed; - - while (_children.TryTake(out removed)) + lock (_childrenSyncLock) { - + _children = new List<BaseItem>(); } } @@ -508,15 +513,11 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// The children /// </summary> - private ConcurrentBag<BaseItem> _children; - /// <summary> - /// The _children initialized - /// </summary> - private bool _childrenInitialized; + private IReadOnlyList<BaseItem> _children; /// <summary> /// The _children sync lock /// </summary> - protected object ChildrenSyncLock = new object(); + private readonly object _childrenSyncLock = new object(); /// <summary> /// Gets or sets the actual children. /// </summary> @@ -525,11 +526,15 @@ namespace MediaBrowser.Controller.Entities { get { - LazyInitializer.EnsureInitialized(ref _children, ref _childrenInitialized, ref ChildrenSyncLock, LoadChildrenInternal); return _children; } } + public void LoadSavedChildren() + { + _children = LoadChildrenInternal(); + } + /// <summary> /// thread-safe access to the actual children of this folder - without regard to user /// </summary> @@ -566,16 +571,15 @@ namespace MediaBrowser.Controller.Entities } } - private ConcurrentBag<BaseItem> LoadChildrenInternal() + private List<BaseItem> LoadChildrenInternal() { - return new ConcurrentBag<BaseItem>(LoadChildren()); + return LoadChildren().ToList(); } /// <summary> /// Loads our children. Validation will occur externally. /// We want this sychronous. /// </summary> - /// <returns>ConcurrentBag{BaseItem}.</returns> protected virtual IEnumerable<BaseItem> LoadChildren() { //just load our children from the repo - the library will be validated and maintained in other processes @@ -698,7 +702,7 @@ namespace MediaBrowser.Controller.Entities if (currentChildren.TryGetValue(child.Id, out currentChild)) { - currentChild.ResolveArgs = child.ResolveArgs; + currentChild.ResetResolveArgs(child.ResolveArgs); //existing item - check if it has changed if (currentChild.HasChanged(child)) @@ -760,12 +764,7 @@ namespace MediaBrowser.Controller.Entities await LibraryManager.CreateItems(newItems, cancellationToken).ConfigureAwait(false); - foreach (var item in newItems) - { - _children.Add(item); - - Logger.Debug("** " + item.Name + " Added to library."); - } + AddChildrenInternal(newItems); await ItemRepository.SaveChildren(Id, _children.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 152767860..13ac913f2 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -114,7 +114,7 @@ namespace MediaBrowser.Controller.Entities.Movies if (dbItem != null) { - dbItem.ResolveArgs = video.ResolveArgs; + dbItem.ResetResolveArgs(video.ResolveArgs); video = dbItem; } diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 79a813bb5..82d81e517 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -312,7 +312,7 @@ namespace MediaBrowser.Controller.Entities if (resetResolveArgs) { // Reload this - ResolveArgs = null; + ResetResolveArgs(); } var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index ed07e3175..0d1e22128 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -246,7 +246,7 @@ namespace MediaBrowser.Controller.Entities if (dbItem != null) { - dbItem.ResolveArgs = video.ResolveArgs; + dbItem.ResetResolveArgs(video.ResolveArgs); video = dbItem; } diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index f069d40c1..a4d99ae17 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Server.Implementations.IO public async void RemoveTempIgnore(string path) { // This is an arbitraty amount of time, but delay it because file system writes often trigger events after RemoveTempIgnore has been called. - await Task.Delay(1000).ConfigureAwait(false); + await Task.Delay(1500).ConfigureAwait(false); string val; _tempIgnoredPaths.TryRemove(path, out val); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 1bc3f1094..2ba16ab03 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1288,15 +1288,15 @@ namespace MediaBrowser.Server.Implementations.Library /// <returns>Task.</returns> public async Task UpdateItem(BaseItem item, ItemUpdateType updateReason, CancellationToken cancellationToken) { - await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); - - UpdateItemInLibraryCache(item); - if (item.LocationType == LocationType.FileSystem) { await SaveMetadata(item, updateReason).ConfigureAwait(false); } + await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); + + UpdateItemInLibraryCache(item); + if (ItemUpdated != null) { try @@ -1346,7 +1346,16 @@ namespace MediaBrowser.Server.Implementations.Library /// <returns>BaseItem.</returns> public BaseItem RetrieveItem(Guid id) { - return ItemRepository.RetrieveItem(id); + var item = ItemRepository.RetrieveItem(id); + + var folder = item as Folder; + + if (folder != null) + { + folder.LoadSavedChildren(); + } + + return item; } private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>(); diff --git a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs index ca878476f..5ef04ef9d 100644 --- a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs @@ -1,10 +1,4 @@ -using Lucene.Net.Analysis.Standard; -using Lucene.Net.Documents; -using Lucene.Net.Index; -using Lucene.Net.QueryParsers; -using Lucene.Net.Search; -using Lucene.Net.Store; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; @@ -30,37 +24,6 @@ namespace MediaBrowser.Server.Implementations.Library _libraryManager = libraryManager; _logger = logManager.GetLogger("Lucene"); - - //string luceneDbPath = serverPaths.DataPath + "\\SearchIndexDB"; - //if (!System.IO.Directory.Exists(luceneDbPath)) - // System.IO.Directory.CreateDirectory(luceneDbPath); - //else if(File.Exists(luceneDbPath + "\\write.lock")) - // File.Delete(luceneDbPath + "\\write.lock"); - - //LuceneSearch.Init(luceneDbPath, _logger); - - //BaseItem.LibraryManager.LibraryChanged += LibraryChanged; - } - - //public void LibraryChanged(object source, ChildrenChangedEventArgs changeInformation) - //{ - // Task.Run(() => - // { - // if (changeInformation.ItemsAdded.Count + changeInformation.ItemsUpdated.Count > 0) - // { - // LuceneSearch.AddUpdateLuceneIndex(changeInformation.ItemsAdded.Concat(changeInformation.ItemsUpdated)); - // } - - // if (changeInformation.ItemsRemoved.Count > 0) - // { - // LuceneSearch.RemoveFromLuceneIndex(changeInformation.ItemsRemoved); - // } - // }); - //} - - public void AddItemsToIndex(IEnumerable<BaseItem> items) - { - LuceneSearch.AddUpdateLuceneIndex(items); } /// <summary> @@ -72,15 +35,7 @@ namespace MediaBrowser.Server.Implementations.Library /// <exception cref="System.ArgumentNullException">searchTerm</exception> public IEnumerable<BaseItem> Search(IEnumerable<BaseItem> items, string searchTerm) { - if (string.IsNullOrEmpty(searchTerm)) - { - throw new ArgumentNullException("searchTerm"); - } - - var hits = LuceneSearch.Search(searchTerm, items.Count()); - - //return hits; - return hits.Where(searchHit => items.Any(p => p.Id == searchHit.Id)); + return items; } public void Dispose() @@ -362,231 +317,4 @@ namespace MediaBrowser.Server.Implementations.Library return term.Split().Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); } } - - public static class LuceneSearch - { - private static ILogger logger; - - private static string path; - private static object lockOb = new object(); - - private static FSDirectory _directory; - private static FSDirectory directory - { - get - { - if (_directory == null) - { - logger.Info("Opening new Directory: " + path); - _directory = FSDirectory.Open(path); - } - return _directory; - } - set - { - _directory = value; - } - } - - private static IndexWriter _writer; - private static IndexWriter writer - { - get - { - if (_writer == null) - { - logger.Info("Opening new IndexWriter"); - _writer = new IndexWriter(directory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED); - } - return _writer; - } - set - { - _writer = value; - } - } - - private static Dictionary<string, float> bonusTerms; - - public static void Init(string path, ILogger logger) - { - logger.Info("Lucene: Init"); - - bonusTerms = new Dictionary<string, float>(); - bonusTerms.Add("Name", 2); - bonusTerms.Add("Overview", 1); - - // Optimize the DB on initialization - // TODO: Test whether this has.. - // Any effect what-so-ever (apart from initializing the indexwriter on the mainthread context, which makes things a whole lot easier) - // Costs too much time - // Is heavy on the CPU / Memory - - LuceneSearch.logger = logger; - LuceneSearch.path = path; - - writer.Optimize(); - } - - private static StandardAnalyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30); - - private static Searcher searcher = null; - - private static Document createDocument(BaseItem data) - { - Document doc = new Document(); - - doc.Add(new Field("Id", data.Id.ToString(), Field.Store.YES, Field.Index.NO)); - doc.Add(new Field("Name", data.Name, Field.Store.YES, Field.Index.ANALYZED) { Boost = 2 }); - doc.Add(new Field("Overview", data.Overview != null ? data.Overview : "", Field.Store.YES, Field.Index.ANALYZED)); - - return doc; - } - - private static void Create(BaseItem item) - { - lock (lockOb) - { - try - { - if (searcher != null) - { - try - { - searcher.Dispose(); - } - catch (Exception e) - { - logger.ErrorException("Error in Lucene while creating index (disposing alive searcher)", e, item); - } - - searcher = null; - } - - _removeFromLuceneIndex(item); - _addToLuceneIndex(item); - } - catch (Exception e) - { - logger.ErrorException("Error in Lucene while creating index", e, item); - } - } - } - - private static void _addToLuceneIndex(BaseItem data) - { - // Prevent double entries - var doc = createDocument(data); - - writer.AddDocument(doc); - } - - private static void _removeFromLuceneIndex(BaseItem data) - { - var query = new TermQuery(new Term("Id", data.Id.ToString())); - writer.DeleteDocuments(query); - } - - public static void AddUpdateLuceneIndex(IEnumerable<BaseItem> items) - { - foreach (var item in items) - { - logger.Info("Adding/Updating BaseItem " + item.Name + "(" + item.Id.ToString() + ") to/on Lucene Index"); - Create(item); - } - - writer.Commit(); - writer.Flush(true, true, true); - } - - public static void RemoveFromLuceneIndex(IEnumerable<BaseItem> items) - { - foreach (var item in items) - { - logger.Info("Removing BaseItem " + item.Name + "(" + item.Id.ToString() + ") from Lucene Index"); - _removeFromLuceneIndex(item); - } - - writer.Commit(); - writer.Flush(true, true, true); - } - - public static IEnumerable<BaseItem> Search(string searchQuery, int maxHits) - { - var results = new List<BaseItem>(); - - lock (lockOb) - { - try - { - if (searcher == null) - { - searcher = new IndexSearcher(directory, true); - } - - BooleanQuery finalQuery = new BooleanQuery(); - - MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, new string[] { "Name", "Overview" }, analyzer, bonusTerms); - - string[] terms = searchQuery.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); - foreach (string term in terms) - finalQuery.Add(parser.Parse(term.Replace("~", "") + "~0.75"), Occur.SHOULD); - foreach (string term in terms) - finalQuery.Add(parser.Parse(term.Replace("*", "") + "*"), Occur.SHOULD); - - logger.Debug("Querying Lucene with query: " + finalQuery.ToString()); - - long start = DateTime.Now.Ticks; - var searchResult = searcher.Search(finalQuery, maxHits); - foreach (var searchHit in searchResult.ScoreDocs) - { - Document hit = searcher.Doc(searchHit.Doc); - results.Add(BaseItem.LibraryManager.GetItemById(Guid.Parse(hit.Get("Id")))); - } - long total = DateTime.Now.Ticks - start; - float msTotal = (float)total / TimeSpan.TicksPerMillisecond; - logger.Debug(searchResult.ScoreDocs.Length + " result" + (searchResult.ScoreDocs.Length == 1 ? "" : "s") + " in " + msTotal + " ms."); - } - catch (Exception e) - { - logger.ErrorException("Error while searching Lucene index", e); - } - } - - return results; - } - - public static void CloseAll() - { - logger.Debug("Lucene: CloseAll"); - if (writer != null) - { - logger.Debug("Lucene: CloseAll - Writer is alive"); - writer.Flush(true, true, true); - writer.Commit(); - writer.WaitForMerges(); - writer.Dispose(); - writer = null; - } - if (analyzer != null) - { - logger.Debug("Lucene: CloseAll - Analyzer is alive"); - analyzer.Close(); - analyzer.Dispose(); - analyzer = null; - } - if (searcher != null) - { - logger.Debug("Lucene: CloseAll - Searcher is alive"); - searcher.Dispose(); - searcher = null; - } - if (directory != null) - { - logger.Debug("Lucene: CloseAll - Directory is alive"); - directory.Dispose(); - directory = null; - } - } - } } diff --git a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs index 8b98a6944..a6b13f8dd 100644 --- a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs +++ b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Server.Implementations.Library /// <param name="args">The args.</param> public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args) { - item.ResolveArgs = args; + item.ResetResolveArgs(args); // If the resolver didn't specify this if (string.IsNullOrEmpty(item.Path)) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index f409b7205..86e250fe4 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -37,12 +37,6 @@ <Reference Include="Alchemy"> <HintPath>..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll</HintPath> </Reference> - <Reference Include="ICSharpCode.SharpZipLib"> - <HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath> - </Reference> - <Reference Include="Lucene.Net"> - <HintPath>..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll</HintPath> - </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Drawing" /> diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 5d9463408..d4d92f09f 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> <package id="Alchemy" version="2.2.1" targetFramework="net45" /> - <package id="Lucene.Net" version="3.0.3" targetFramework="net45" /> <package id="MediaBrowser.BdInfo" version="1.0.0.2" targetFramework="net45" /> <package id="morelinq" version="1.0.16006" targetFramework="net45" /> <package id="Rx-Core" version="2.1.30214.0" targetFramework="net45" /> @@ -13,6 +12,5 @@ <package id="ServiceStack.OrmLite.SqlServer" version="3.9.43" targetFramework="net45" /> <package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" /> <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" /> - <package id="SharpZipLib" version="0.86.0" targetFramework="net45" /> <package id="System.Data.SQLite.x86" version="1.0.88.0" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs index 706206d3a..ad4727023 100644 --- a/MediaBrowser.ServerApplication/App.xaml.cs +++ b/MediaBrowser.ServerApplication/App.xaml.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.ServerApplication EventHelper.FireEventIfNotNull(AppStarted, this, EventArgs.Empty, _logger); - await task.ConfigureAwait(false); + await task; } catch (Exception ex) { diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 0aa5179e0..3597e0755 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -119,10 +119,6 @@ <Reference Include="Hardcodet.Wpf.TaskbarNotification"> <HintPath>..\packages\Hardcodet.Wpf.TaskbarNotification.1.0.4.0\lib\net40\Hardcodet.Wpf.TaskbarNotification.dll</HintPath> </Reference> - <Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath> - </Reference> <Reference Include="MahApps.Metro"> <HintPath>..\packages\MahApps.Metro.0.11.0.17-ALPHA\lib\net45\MahApps.Metro.dll</HintPath> </Reference> diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index e680b556f..d776597ec 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="DotNetZip" version="1.9.1.8" targetFramework="net45" /> <package id="Hardcodet.Wpf.TaskbarNotification" version="1.0.4.0" targetFramework="net45" /> <package id="MahApps.Metro" version="0.11.0.17-ALPHA" targetFramework="net45" /> <package id="MediaBrowser.IsoMounting" version="3.0.56" targetFramework="net45" /> diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index eb846cd2f..0b8b04a2f 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -16,6 +16,7 @@ <dependency id="NLog" version="2.0.1.2" /> <dependency id="ServiceStack.Text" version="3.9.58" /> <dependency id="SimpleInjector" version="2.3.2" /> + <dependency id="sharpcompress" version="0.10.1.3" /> </dependencies> </metadata> <files> |
