/// <summary> /// Saves the information from the provided quest wrapper into this config object. /// Also pulls global advanced options. /// </summary> /// <param name="questWrapper">The quest wrapper.</param> public void Save(QuestCollectionWrapper questWrapper) { if (questWrapper == null) { throw new ArgumentNullException(nameof(questWrapper)); } DisplayMode = AdvancedOptions.Instance.DisplayMode; AllowRankedVotes = AdvancedOptions.Instance.AllowRankedVotes; IgnoreSpoilers = AdvancedOptions.Instance.IgnoreSpoilers; TrimExtendedText = AdvancedOptions.Instance.TrimExtendedText; GlobalSpoilers = AdvancedOptions.Instance.GlobalSpoilers; DisableProxyVotes = AdvancedOptions.Instance.DisableProxyVotes; ForcePinnedProxyVotes = AdvancedOptions.Instance.ForcePinnedProxyVotes; ForbidVoteLabelPlanNames = AdvancedOptions.Instance.ForbidVoteLabelPlanNames; WhitespaceAndPunctuationIsSignificant = AdvancedOptions.Instance.WhitespaceAndPunctuationIsSignificant; DisplayPlansWithNoVotes = AdvancedOptions.Instance.DisplayPlansWithNoVotes; CurrentQuest = questWrapper.CurrentQuest; Quests.Clear(); foreach (var quest in questWrapper.QuestCollection) { Quests.Add(quest); } }
public MainViewModel(QuestCollectionWrapper config, HttpClientHandler handler, IPageProvider pageProvider, ITextResultsProvider textResults, IErrorLogger errorLogger, Func <string, CompareInfo, CompareOptions, int> hashFunction) { ErrorLog.LogUsing(errorLogger); Agnostic.HashStringsUsing(hashFunction); if (config != null) { QuestList = config.QuestCollection; QuestList.Sort(); SelectQuest(config.CurrentQuest); } else { QuestList = new QuestCollection(); SelectQuest(null); } SetupNetwork(pageProvider, handler); SetupTextResults(textResults); AllVotesCollection = new ObservableCollectionExt <string>(); AllVotersCollection = new ObservableCollectionExt <string>(); BuildCheckForNewRelease(); BuildTally(); BindVoteCounter(); SetupCommands(); }
/// <summary> /// Loads the program user data config and returns a collection of /// quests. /// </summary> /// <returns>Returns the quests wrapper to store data in.</returns> public static QuestCollectionWrapper Load() { QuestCollectionWrapper questsWrapper = new QuestCollectionWrapper(); List <Configuration> configs = NetTallyConfigHelper.GetConfigsToLoadFrom(); ReadConfigInformation(configs, questsWrapper); return(questsWrapper); }
/// <summary> /// Loads the configuration information into the provided quest wrapper. /// Global information is stored in the advanced options instance. /// </summary> /// <param name="questWrapper">The quest wrapper.</param> public void Load(QuestCollectionWrapper questWrapper) { if (questWrapper == null) { throw new ArgumentNullException(nameof(questWrapper)); } AdvancedOptions.Instance.DisplayMode = DisplayMode; AdvancedOptions.Instance.AllowRankedVotes = AllowRankedVotes; AdvancedOptions.Instance.IgnoreSpoilers = IgnoreSpoilers; AdvancedOptions.Instance.TrimExtendedText = TrimExtendedText; AdvancedOptions.Instance.GlobalSpoilers = GlobalSpoilers; AdvancedOptions.Instance.DisableProxyVotes = DisableProxyVotes; AdvancedOptions.Instance.ForcePinnedProxyVotes = ForcePinnedProxyVotes; AdvancedOptions.Instance.ForbidVoteLabelPlanNames = ForbidVoteLabelPlanNames; AdvancedOptions.Instance.WhitespaceAndPunctuationIsSignificant = WhitespaceAndPunctuationIsSignificant; AdvancedOptions.Instance.DisplayPlansWithNoVotes = DisplayPlansWithNoVotes; questWrapper.CurrentQuest = CurrentQuest; foreach (QuestElement questElement in Quests) { try { IQuest q = new Quest { DisplayName = questElement.DisplayName, ThreadName = questElement.ThreadName, PostsPerPage = questElement.PostsPerPage, StartPost = questElement.StartPost, EndPost = questElement.EndPost, CheckForLastThreadmark = questElement.CheckForLastThreadmark, PartitionMode = questElement.PartitionMode, UseCustomThreadmarkFilters = questElement.UseCustomThreadmarkFilters, CustomThreadmarkFilters = questElement.CustomThreadmarkFilters, UseCustomUsernameFilters = questElement.UseCustomUsernameFilters, CustomUsernameFilters = questElement.CustomUsernameFilters, UseCustomPostFilters = questElement.UseCustomPostFilters, CustomPostFilters = questElement.CustomPostFilters }; questWrapper.QuestCollection.Add(q); } catch (Exception) { continue; } } }
/// <summary> /// Reads the configuration information from the provided configuration object into /// the provided quests collection wrapper. /// </summary> /// <param name="configs">The list of configuration objects to attempt to read.</param> /// <param name="questsWrapper">The quests wrapper to store data in.</param> private static void ReadConfigInformation(List <Configuration> configs, QuestCollectionWrapper questsWrapper) { if (configs.Count == 0) { return; } ConfigurationException failure = null; ConfigPrefs.Strict = true; while (true) { foreach (var config in configs) { try { if (config.Sections[QuestsSection.SectionName] is QuestsSection questsSection) { questsSection.Load(questsWrapper); } // End as soon as done successfully return; } catch (ConfigurationException e) { failure = e; } } ConfigPrefs.Strict = !ConfigPrefs.Strict; if (ConfigPrefs.Strict) { break; } } // If all config files generated an error, throw the last one we got. if (failure != null) { throw failure; } }
/// <summary> /// Writes the data from the provided quests wrapper object into the specified configuration file. /// </summary> /// <param name="questsWrapper">The quests wrapper with program data.</param> /// <param name="config">The configuration file to save to.</param> private static void WriteConfigInformation(QuestCollectionWrapper questsWrapper, Configuration config) { try { ConfigPrefs.Strict = false; if (config.Sections[QuestsSection.SectionName] is QuestsSection questsSection) { questsSection.Save(questsWrapper); } config.Save(ConfigurationSaveMode.Minimal); } catch (ConfigurationErrorsException) { // May not have permission to write, or the original config may have errors. } }
/// <summary> /// Saves the data from the specified quests wrapper into the config file. /// Tries to save in both the portable location (same directory as the executable), /// and to the roaming location (AppData). /// The portable location is transferable between computers without needing /// a corresponding user account, while the roaming location keeps data from /// being lost if you unzip a new version of the program to a differently-named /// folder. /// </summary> /// <param name="questsWrapper">The quests wrapper.</param> public static void Save(QuestCollectionWrapper questsWrapper) { // If there's nothing to save, don't do anything. if (questsWrapper == null) { return; } if (questsWrapper.QuestCollection == null) { return; } // Write to each config location (portable and roaming) List <Configuration> configs = NetTallyConfigHelper.GetConfigsToWriteTo(); foreach (var config in configs) { WriteConfigInformation(questsWrapper, config); } }
/// <summary> /// When the program closes, save the current list of quests. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Window_Closing(object sender, CancelEventArgs e) { try { if (ViewModelService.MainViewModel == null) { return; } string selectedQuest = ViewModelService.MainViewModel.SelectedQuest?.ThreadName ?? ""; QuestCollectionWrapper wrapper = new QuestCollectionWrapper(ViewModelService.MainViewModel.QuestList, selectedQuest); NetTallyConfig.Save(wrapper); } catch (Exception ex) { string file = ErrorLog.Log(ex); MessageBox.Show($"Error log saved to:\n{file ?? "(unable to write log file)"}", "Error in shutdown", MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Set up the program with various platform-specific configurations. /// </summary> /// <param name="config">The program's config data.</param> private void PlatformSetup(QuestCollectionWrapper config) { try { System.Net.ServicePointManager.DefaultConnectionLimit = 4; ViewModelService.Instance.Configure(config) .LogErrorsUsing(new WindowsErrorLog()) .HashAgnosticStringsUsing(UnicodeHashFunction.HashFunction) .Build(); DataContext = ViewModelService.MainViewModel; ViewModelService.MainViewModel.PropertyChanged += MainViewModel_PropertyChanged; ViewModelService.MainViewModel.ExceptionRaised += MainViewModel_ExceptionRaised; ViewModelService.MainViewModel.CheckForNewRelease(); } catch (InvalidOperationException e) { ErrorLog.Log(e); } }
public ViewModelService Configure(QuestCollectionWrapper config) { this.config = config; return(this); }