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);
        }
Beispiel #2
0
        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);
        }