Ejemplo n.º 1
0
 /// <summary>
 /// This is an additional check on delete AFTER we make sure the book is checked out.
 /// Even if it is, we can't delete it while disconnected because we don't have a way
 /// to actually remove it from the TC. Our current Delete mechanism, unlike git etc.,
 /// does not postpone delete until commit.
 /// </summary>
 /// <param name="bookFolderPath"></param>
 /// <returns></returns>
 public bool CannotDeleteBecauseDisconnected(string bookFolderPath)
 {
     if (CurrentCollectionEvenIfDisconnected == null)
     {
         return(false);
     }
     return(CurrentCollectionEvenIfDisconnected.CannotDeleteBecauseDisconnected(bookFolderPath));
 }
 /// <summary>
 /// Return true if the user must check this book out before editing it,
 /// deleting it, etc. This is automatically false if the collection is not
 /// a TC; if it is a TC (even a disconnected one), it's true if the book is
 /// NOT checked out.
 /// </summary>
 /// <remarks>if bookFolderPath is null or empty, it currently returns false.
 /// This is a bit arbitrary. If there's no book currently selected, then we can't
 /// do editing operations...in that sense this situation is similar to a selected
 /// book that needs to be checked out. But strictly it's not true that we need
 /// to check out the selected book to edit...we need a book to be selected!
 /// I wanted to settle on some answer so that callers don't each have to be careful
 /// not to pass null, so I settled on false.</remarks>
 public bool NeedCheckoutToEdit(string bookFolderPath)
 {
     // We use the EvenIfDisconnected version here because we want
     // editing attempts to FAIL if we are in a disconnected TC and don't already have it
     // checked out; we don't just want to edit it as if the collection was not a TC at all.
     if (CurrentCollectionEvenIfDisconnected == null || string.IsNullOrEmpty(bookFolderPath))
     {
         return(false);
     }
     return(CurrentCollectionEvenIfDisconnected.NeedCheckoutToEdit(bookFolderPath));
 }
Ejemplo n.º 3
0
        public TeamCollectionManager(string localCollectionPath, BloomWebSocketServer webSocketServer,
                                     BookRenamedEvent bookRenamedEvent, BookStatusChangeEvent bookStatusChangeEvent,
                                     BookSelection bookSelection, CollectionClosing collectionClosingEvent, BookCollectionHolder bookCollectionHolder)
        {
            _webSocketServer       = webSocketServer;
            _bookStatusChangeEvent = bookStatusChangeEvent;
            _localCollectionFolder = Path.GetDirectoryName(localCollectionPath);
            _bookCollectionHolder  = bookCollectionHolder;
            BookSelection          = bookSelection;
            collectionClosingEvent?.Subscribe((x) =>
            {
                // When closing the collection...especially if we're restarting due to
                // changed settings!...we need to save any settings changes to the repo.
                // In such cases we can't safely wait for the change watcher to write things,
                // because (a) if we're shutting down for good, we just might not detect the
                // change before everything shuts down; and (b) if we're reopening the collection,
                // we might overwrite the change with current collection settings before we
                // save the new ones.
                if (CurrentCollection != null)
                {
                    CurrentCollection.SyncLocalAndRepoCollectionFiles(false);
                }
                else if (Settings.HaveEnterpriseFeatures && CurrentCollectionEvenIfDisconnected != null &&
                         CurrentCollectionEvenIfDisconnected is DisconnectedTeamCollection disconnectedTC && disconnectedTC.DisconnectedBecauseNoEnterprise)
                {
                    // We were disconnected because of Enterprise being off, but now the user has
                    // turned Enterprise on again. We really need to save that, even though we usually don't
                    // save settings changes when disconnected. Otherwise, restarting will restore the
                    // no-enterprise state, and we will be stuck.
                    // Note: We don't need to check for admin privileges here. If the user isn't an admin,
                    // he could not have made any changes to settings, including turning on enterprise.
                    var tempCollectionLinkPath = GetTcLinkPathFromLcPath(_localCollectionFolder);
                    if (RobustFile.Exists(tempCollectionLinkPath))
                    {
                        try
                        {
                            var repoFolderPath        = RepoFolderPathFromLinkPath(tempCollectionLinkPath);
                            var tempCollection        = new FolderTeamCollection(this, _localCollectionFolder, repoFolderPath, bookCollectionHolder: _bookCollectionHolder);
                            var problemWithConnection = tempCollection.CheckConnection();
                            if (problemWithConnection == null)
                            {
                                tempCollection.SyncLocalAndRepoCollectionFiles(false);
                            }
                            else
                            {
                                NonFatalProblem.Report(ModalIf.All, PassiveIf.All, "Bloom could not save your settings to the Team Collection: " + problemWithConnection.TextForDisplay,
                                                       null, null, true);
                            }
                        }
                        catch (Exception ex)
                        {
                            NonFatalProblem.Report(ModalIf.All, PassiveIf.All, "Bloom could not save your settings to the Team Collection",
                                                   null, ex, true);
                        }
                    }
                    // What if there's NOT a TC link file? Then it would be pathological to have a CurrentCollectionEvenIfDisconnected.
                    // It's no longer a TC, so we don't need to save the settings to the TC. For now I'm just not going to do anything.
                }
            });
            bookRenamedEvent.Subscribe(pair =>
            {
                CurrentCollectionEvenIfDisconnected?.HandleBookRename(Path.GetFileName(pair.Key), Path.GetFileName(pair.Value));
            });
            var impersonatePath = Path.Combine(_localCollectionFolder, "impersonate.txt");

            if (RobustFile.Exists(impersonatePath))
            {
                var lines = RobustFile.ReadAllLines(impersonatePath);
                _overrideCurrentUser = lines.FirstOrDefault();
                if (lines.Length > 1)
                {
                    _overrideMachineName = lines[1];
                }
                if (lines.Length > 2)
                {
                    _overrideCurrentUserFirstName = lines[2];
                }
                if (lines.Length > 3)
                {
                    _overrideCurrentUserSurname = lines[3];
                }
            }

            var localCollectionLinkPath = GetTcLinkPathFromLcPath(_localCollectionFolder);

            if (RobustFile.Exists(localCollectionLinkPath))
            {
                try
                {
                    var repoFolderPath = RepoFolderPathFromLinkPath(localCollectionLinkPath);
                    CurrentCollection = new FolderTeamCollection(this, _localCollectionFolder, repoFolderPath,
                                                                 bookCollectionHolder: _bookCollectionHolder); // will be replaced if CheckConnection fails
                    // BL-10704: We set this to the CurrentCollection BEFORE checking the connection,
                    // so that there will be a valid MessageLog if we need it during CheckConnection().
                    // If CheckConnection() fails, it will reset this to a DisconnectedTeamCollection.
                    CurrentCollectionEvenIfDisconnected = CurrentCollection;
                    if (CheckConnection())
                    {
                        CurrentCollection.SocketServer = SocketServer;
                        CurrentCollection.TCManager    = this;
                        // Later, we will sync everything else, but we want the current collection settings before
                        // we create the CollectionSettings object.
                        if (ForceNextSyncToLocal)
                        {
                            ForceNextSyncToLocal = false;
                            CurrentCollection.CopyRepoCollectionFilesToLocal(_localCollectionFolder);
                        }
                        else
                        {
                            CurrentCollection.SyncLocalAndRepoCollectionFiles();
                        }
                    }
                    // else CheckConnection has set up a DisconnectedRepo if that is relevant.
                }
                catch (Exception ex)
                {
                    NonFatalProblem.Report(ModalIf.All, PassiveIf.All, "Bloom found Team Collection settings but could not process them", null, ex, true);
                    CurrentCollection = null;
                    CurrentCollectionEvenIfDisconnected = null;
                }
            }
        }