示例#1
0
        private void btnSave_Click(object sender, EventArgs e)
        {
            AddChangesToStory();
            if (_isNewStory)
            {
                _storyContainer.AddStory(_story);
            }
            else
            {
                _storyContainer.UpdateStory(_story);
            }

            this.Close();
        }
        private async Task SyncStory(WdcInteractiveStory story)
        {
            _log.Debug($"Syncing story '{story.ID}'");
            var ct = _ctSource.Token;

            ct.ThrowIfCancellationRequested();

            // Update story's status, mark as in progress
            //SetStoryStatusState(story.ID, StorySyncWorkerStoryState.Working);
            SetCurrentStatus(StorySyncWorkerState.WorkingStory, $"Working on story: {story.ID}", story.ID);
            //SetStoryStatusProgress(story.ID, 0, 0);

            // Catch specific exceptions
            try
            {
                if (CheckIfStoryInfoNeedsSync(story))
                {
                    SetStoryStatusState(story.ID, StorySyncWorkerStoryState.Working);
                    SetCurrentStatus(StorySyncWorkerState.WorkingStory, $"Updating story info: {story.ID}", story.ID);
                    await SyncStoryInfo(story);
                }
                else
                {
                    _log.Debug("Story info does not need updating");
                }

                if (CheckIfChapterOutlineNeedsSync(story))
                {
                    SetStoryStatusState(story.ID, StorySyncWorkerStoryState.Working);
                    SetCurrentStatus(StorySyncWorkerState.WorkingOutline, $"Updating chapter outline: {story.ID}", story.ID);
                    await SyncStoryChapterList(story);
                }
                else
                {
                    _log.Debug("Story chapter outline does not need updating");
                }

                ct.ThrowIfCancellationRequested();

                // Build a list of chapters that need updating
                SetCurrentStatus(StorySyncWorkerState.WorkingStory, $"Checking for any chapters that need syncing: {story.ID}", story.ID);
                List <WdcInteractiveChapter> chaptersToSync = new List <WdcInteractiveChapter>();
                foreach (var chapter in story.Chapters)
                {
                    if (CheckIfChapterNeedsSync(chapter))
                    {
                        chaptersToSync.Add(chapter);
                    }
                }

                ct.ThrowIfCancellationRequested();

                // If there are no chapters to update, set progress to maximum
                if (chaptersToSync.Count < 1)
                {
                    SetStoryStatusProgress(story.ID, story.Chapters.Count, story.Chapters.Count);
                    _log.Debug("No chapters need updating");
                }
                else
                {
                    SetStoryStatusState(story.ID, StorySyncWorkerStoryState.Working); // About to start working
                }

                // Start syncing the chapters
                for (var i = 0; i < chaptersToSync.Count; i++)
                {
                    ct.ThrowIfCancellationRequested();

                    var chapter = chaptersToSync[i];

                    // Update status

                    SetCurrentStatus(StorySyncWorkerState.WorkingChapter, $"Updating story chapter: {story.ID}, {chapter.Path}", story.ID);
                    SetStoryStatusProgress(story.ID, story.Chapters.Count - (chaptersToSync.Count - i), story.Chapters.Count);

                    // Sync the chapter
                    await SyncChapter(story, chapter);

                    // Save changes after updating the chapter
                    // TODO: is this too much? updating the entire sory when just a single chapter changes? Will it cause issues with stuff listening for container change events?
                    _storyContainer.UpdateStory(story);
                }

                // Done sync for this story. Mark story status as idle
                SetStoryStatusState(story.ID, StorySyncWorkerStoryState.Idle);
                SetCurrentStatus(StorySyncWorkerState.Idle, $"Story update complete: {story.ID}", string.Empty);
            } // End of try block
            catch (InteractivesTemporarilyUnavailableException)
            {
                _log.Info($"Encountered ITU message for story: {story.ID}");
                SetStoryStatusState(story.ID, StorySyncWorkerStoryState.WaitingItu);
            }
            catch (WritingClientHtmlParseException ex)
            {
                _log.Warn("Error trying to parse HTML from Writing.com", ex);

                // Dump the HTML
                var sbDump = new StringBuilder();
                sbDump.AppendLine($"<!-- Exception: {ex.Message} -->");
                sbDump.AppendLine($"<!-- URL: {ex.Address} -->");
                sbDump.AppendLine(ex.HtmlResult);
                var dumpFilePath = _fileDumper.DumpFile("HtmlParseError", sbDump.ToString());

                // Show an error message
                var sbExMsg = new StringBuilder();
                sbExMsg.AppendLine("A HTML parse exception was encountered with the below details:");
                sbExMsg.AppendLine("======================");
                sbExMsg.AppendLine(ex.Message);
                sbExMsg.AppendLine("======================");
                sbExMsg.AppendLine("The HTML response has been dumped to this location:");
                sbExMsg.AppendLine(dumpFilePath);

                _gui.ShowMessageBox("HTML parse exception", sbExMsg.ToString(), GuiMessageBoxIcon.Error);

                // Set the story's status to Error, so it doesn't keep trying to sync and cause more errors
                SetStoryStatusError(story.ID, ex.Message);
            }
            catch (Exception ex)
            {
                _log.Warn($"Encountered unhandled exception while syncing story '{story.ID}'", ex);

                var sb = new StringBuilder();
                sb.AppendLine(ex.GetType().Name);
                sb.AppendLine(ex.Message);

                SetStoryStatusError(story.ID, sb.ToString());

                _gui.ShowExceptionDialog(ex);
            }

            SetCurrentStatus(StorySyncWorkerState.Idle, $"Story update complete: {story.ID}", string.Empty);
        }