Esempio n. 1
0
        public ServerEvents(WebShellFolderServer server)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            Server = server;
            // build SignalR connection
            _connection = new HubConnectionBuilder()
                          .WithUrl(WebApi.RootUrl + "events")
                          .WithAutomaticReconnect()
                          .Build();

            _connection.Closed += async(error) =>
            {
                // restart
                await Task.Delay(new Random().Next(0, 5) * 1000).ConfigureAwait(false);

                await _connection.StartAsync().ConfigureAwait(false);
            };

            // must match server's IFileSystemEvents method signature
            // Change(Guid id, Guid itemId, Guid parentId, WatcherChangeTypes types, DateTime creationTimeUtc, string oldName);
            _connection.On <Guid, Guid, Guid, WatcherChangeTypes, DateTime, string, Guid?>("Change", (id, itemId, parentId, type, creationTimeUtc, oldName, oldParentId) =>
            {
                // invalidate the cache using server information
                // note we don't force files update. this will be done when the use opens it
                server.Log(System.Diagnostics.TraceLevel.Warning, "UpdateCache id: " + id + " itemId: " + itemId + " parentId: " + parentId + " type: " + type + " oldName: " + oldName + " oldParentId: " + oldParentId);
                WebApi.UpdateCache(itemId, parentId, type);

                // tell the Shell that this pidl has changed
                // which will eventually call back in views that may be opened to our folders
                var item = server.GetItem(itemId);
                if (item != null)
                {
                    if (item.IsFolder)
                    {
                        switch (type)
                        {
                        case WatcherChangeTypes.Changed:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_UPDATEDIR, 0, item.IdList);
                            break;

                        case WatcherChangeTypes.Created:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_MKDIR, 0, item.IdList);
                            break;

                        case WatcherChangeTypes.Deleted:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_RMDIR, 0, item.IdList);
                            break;

                        case WatcherChangeTypes.Renamed:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_RENAMEFOLDER, 0, item.IdList);
                            break;
                        }
                    }
                    else
                    {
                        switch (type)
                        {
                        case WatcherChangeTypes.Changed:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_UPDATEITEM, 0, item.IdList);
                            break;

                        case WatcherChangeTypes.Created:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_CREATE, 0, item.IdList);
                            break;

                        case WatcherChangeTypes.Deleted:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_DELETE, 0, item.IdList);
                            break;

                        case WatcherChangeTypes.Renamed:
                            ShellUtilities.ChangeNotify(SHCNE.SHCNE_RENAMEITEM, 0, item.IdList);
                            break;
                        }
                    }
                }

                item = server.GetItem(parentId);
                if (item != null)
                {
                    ShellUtilities.ChangeNotify(SHCNE.SHCNE_UPDATEDIR, 0, item.IdList);
                }
            });

            _connection.StartAsync();
        }
Esempio n. 2
0
        private void OnWatcherEvent(object sender, LocalFileSystemWatcherEventArgs e)
        {
            // basic checks
            if (!IOUtilities.PathIsChildOrEqual(WebApi.LocalDirectory.FullName, e.Path))
            {
                return;
            }

            // skip some well known files (office, etc.)
            if (!ConsiderForRemote(Path.GetFileName(e.Path)))
            {
                return;
            }

            var isDir = IOUtilities.PathIsDirectory(e.Path);

            Server.Log(TraceLevel.Verbose, "Action:" + e.Action + " Get remote item for local: " + e.Path);
            var item = Server.GetRemoteItem(e.Path);

            if (item != null)
            {
                if (e.Action == WatcherChangeTypes.Deleted)
                {
                    // a delete in a local file doesn't mean a delete in the server
                    ShellUtilities.ChangeNotify(SHCNE.SHCNE_UPDATEITEM, 0, item.IdList);
                }
                else if (e.Action == WatcherChangeTypes.Changed)
                {
                    ShellUtilities.ChangeNotify(isDir ? SHCNE.SHCNE_UPDATEDIR : SHCNE.SHCNE_UPDATEITEM, 0, item.IdList);
                    if (!isDir)
                    {
                        SynchronizeFile(e.Path);
                    }
                }
                else if (e.Action == WatcherChangeTypes.Renamed)
                {
                    ShellUtilities.ChangeNotify(isDir ? SHCNE.SHCNE_RENAMEFOLDER : SHCNE.SHCNE_RENAMEITEM, 0, item.IdList);
                    if (!isDir)
                    {
                        SynchronizeFile(e.Path);
                    }
                }
                // else create do nothing
            }
            else // try parent
            {
                var parentPath = Path.GetDirectoryName(e.Path);
                item = Server.GetRemoteItem(parentPath);
                if (item != null)
                {
                    // new item creation in the local directories? could come from the "New ..." menu in virtual folder's context
                    // we don't use created just changed
                    if (e.Action != WatcherChangeTypes.Deleted && e.Action != WatcherChangeTypes.Created && item is IObjectWithApiItem owa)
                    {
                        var atts = IOUtilities.PathGetAttributes(e.Path);
                        if (atts.HasValue &&
                            !atts.Value.HasFlag(FileAttributes.Directory) &&
                            !atts.Value.HasFlag(FileAttributes.Hidden) &&
                            !atts.Value.HasFlag(FileAttributes.System))
                        {
                            WebApi.CreateAsync(owa.ApiItem.Id, e.Path, null, atts.Value);
                        }
                    }

                    ShellUtilities.ChangeNotify(SHCNE.SHCNE_UPDATEDIR, 0, item.IdList);
                }
            }
        }
        private void OnChangeNotifierNotify(object sender, ChangeNotifyEventArgs e)
        {
            // get our equivalent item
            if (e.FileSystemPath1 != null)
            {
                // is it really about us?
                if (e.FileSystemPath1.StartsWith(RootPath, StringComparison.OrdinalIgnoreCase))
                {
                    // get relative path and normalize a bit
                    var relPath1 = IOUtilities.PathRemoveStartSlash(e.FileSystemPath1.Substring(RootPath.Length));

                    // build a PIDL corresponding to our namespace from a file system path (not in our namespace)
                    // and get/update the corresponding ShellItem from the cache, if it exists.
                    ShellItem       item;
                    ShellItemIdList idl;
                    switch (e.Event)
                    {
                    case SHCNE.SHCNE_DELETE:
                    case SHCNE.SHCNE_RMDIR:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_RMDIR ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)
                        {
                            item.NotifyDelete();
                            Server.RemoveFromCache(item.IdList);
                        }
                        break;

                    case SHCNE.SHCNE_RENAMEFOLDER:
                    case SHCNE.SHCNE_RENAMEITEM:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_RENAMEFOLDER ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)
                        {
                            Server.RemoveFromCache(item.IdList);
                        }

                        // 1 is previous, 2 is new
                        var relPath2 = IOUtilities.PathRemoveStartSlash(e.FileSystemPath2.Substring(RootPath.Length));
                        var idl2     = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath2, e.Event == SHCNE.SHCNE_RENAMEFOLDER ? FileAttributes.Directory : FileAttributes.Normal);
                        ShellUtilities.ChangeNotify(e.Event, 0, idl, idl2);
                        break;

                    case SHCNE.SHCNE_UPDATEITEM:
                    case SHCNE.SHCNE_UPDATEDIR:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_UPDATEDIR ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)
                        {
                            item.NotifyUpdate();
                        }
                        break;

                    case SHCNE.SHCNE_CREATE:
                    case SHCNE.SHCNE_MKDIR:
                        idl  = ShellItemIdList.FromFileSystem(RootPhysical.IdList, relPath1, e.Event == SHCNE.SHCNE_MKDIR ? FileAttributes.Directory : FileAttributes.Normal);
                        item = Server.GetFromCache(idl);
                        if (item != null)     // item should in general be null (creation)
                        {
                            item.NotifyCreate();
                        }
                        else
                        {
                            ShellUtilities.ChangeNotify(e.Event, 0, idl);
                        }
                        break;
                    }
                }
            }
        }