public IMediaLocation Create(string path) { //Debug.Assert(path != null); (null path okay sometimes) if (path == null) { return(null); } if (Helper.IsShortcut(path)) { path = Helper.ResolveShortcut(path); } IMediaLocation location = null; if (Directory.Exists(path)) { var info = new DirectoryInfo(path).ToFileInfo(); location = new FolderMediaLocation(info, null); } else if (File.Exists(path)) { var info = new System.IO.FileInfo(path).ToFileInfo(); if (path.ToLower().EndsWith(".vf")) { location = new VirtualFolderMediaLocation(info, null); } else { location = new MediaLocation(info, null); } } return(location); }
bool ValidateChildrenImpl() { location = null; int unavailableItems = 0; // cache a copy of the children var childrenCopy = ActualChildren.ToList(); //changed this to reference actual children so it wouldn't keep mucking up hidden ones -ebr var validChildren = GetChildren(false); var currentChildren = new Dictionary <Guid, BaseItem>(); // in case some how we have a non distinct list foreach (var item in childrenCopy) { currentChildren[item.Id] = item; } if (currentChildren.Count != validChildren.Count) { Logger.ReportVerbose("Validating " + this.Name + ". CurrentChildren: " + currentChildren.Count + ". Physical Children: " + validChildren.Count); } bool changed = false; foreach (var item in validChildren) { BaseItem currentChild; if (currentChildren.TryGetValue(item.Id, out currentChild)) { if (currentChild != null) { bool thisItemChanged = currentChild.AssignFromItem(item); if (thisItemChanged) { item.RefreshMetadata(MediaBrowser.Library.Metadata.MetadataRefreshOptions.Default); Kernel.Instance.ItemRepository.SaveItem(item); } currentChildren[item.Id] = null; } } else { changed = true; Logger.ReportInfo("Adding new item to library: " + item.Name + " (" + item.Path + ")"); lock (ActualChildren) { item.Parent = this; ActualChildren.Add(item); item.RefreshMetadata(MediaBrowser.Library.Metadata.MetadataRefreshOptions.Force); //necessary to get it to show up without user intervention Kernel.Instance.ItemRepository.SaveItem(item); // Notify the kernel that a new item was added Kernel.Instance.OnItemAddedToLibrary(item); var folder = item as Folder; if (folder != null) { Logger.ReportVerbose(item.Name + " is folder - validating and refreshing children..."); folder.ValidateChildren(); foreach (var child in folder.Children) //necessary to get new sub-items to refresh properly { child.RefreshMetadata(MediaBrowser.Library.Metadata.MetadataRefreshOptions.Force); } } } } } foreach (var item in currentChildren.Values.Where(item => item != null)) { if (FolderMediaLocation != null && FolderMediaLocation.IsUnavailable(item.Path)) { Logger.ReportInfo("Not removing missing item " + item.Name + " because its location is unavailable."); unavailableItems++; } else { changed = true; Logger.ReportInfo("Removing missing item from library: (" + item.Id + ") " + item.Path); lock (ActualChildren) { ActualChildren.RemoveAll(current => current.Id == item.Id); } // Notify the kernel that an item was removed Kernel.Instance.OnItemRemovedFromLibrary(item); } } // this is a rare concurrency bug workaround - which I already fixed (it protects against regressions) if (!changed && childrenCopy.Count != (validChildren.Count + unavailableItems)) { Logger.ReportWarning("For some reason we have duplicate items in folder " + Name + ", fixing this up!"); Logger.ReportVerbose("ChildrenCopy count: " + childrenCopy.Count + " ValidChildren count: " + (validChildren.Count + unavailableItems)); //Logger.ReportVerbose("ChildrenCopy contents are: "); //foreach (var item in childrenCopy) Logger.ReportVerbose(" --- " + item.Name + " Path: " + item.Path); //Logger.ReportVerbose("ValidChildren contents are: "); //foreach (var item in validChildren) Logger.ReportVerbose(" --- " + item.Name + " Path: " + item.Path); childrenCopy = childrenCopy .Distinct(i => i.Id) .ToList(); lock (ActualChildren) { ActualChildren.Clear(); ActualChildren.AddRange(childrenCopy); } changed = true; } if (changed) { lock (ActualChildren) SaveChildren(ActualChildren); //we need to blank out the persisted RAL items for the top level folder var item = this; while (item != null && item.Parent != Kernel.Instance.RootFolder) { item = item.Parent; } if (item != null) { item.RemoveQuicklist(); } OnChildrenChanged(new ChildrenChangedEventArgs { FolderContentChanged = true }); } return(changed); }