1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-11 21:15:44 +02:00

Refactor and optimize the plugin configuration file

This commit is contained in:
chylex 2018-08-17 11:09:07 +02:00
parent d9a80d1085
commit 898437720b
11 changed files with 154 additions and 94 deletions

View File

@ -10,21 +10,25 @@ namespace TweetDuck.Configuration{
sealed class ConfigManager{
public UserConfig User { get; }
public SystemConfig System { get; }
public PluginConfig Plugins { get; }
public event EventHandler ProgramRestartRequested;
private readonly FileConfigInstance<UserConfig> infoUser;
private readonly FileConfigInstance<SystemConfig> infoSystem;
private readonly PluginConfigInstance infoPlugins;
private readonly IConfigInstance<BaseConfig>[] infoList;
public ConfigManager(){
User = new UserConfig(this);
System = new SystemConfig(this);
Plugins = new PluginConfig(this);
infoList = new IConfigInstance<BaseConfig>[]{
infoUser = new FileConfigInstance<UserConfig>(Program.UserConfigFilePath, User, "program options"),
infoSystem = new FileConfigInstance<SystemConfig>(Program.SystemConfigFilePath, System, "system options")
infoSystem = new FileConfigInstance<SystemConfig>(Program.SystemConfigFilePath, System, "system options"),
infoPlugins = new PluginConfigInstance(Program.PluginConfigFilePath, Plugins)
};
// TODO refactor further
@ -51,16 +55,19 @@ public ConfigManager(){
public void LoadAll(){
infoUser.Load();
infoSystem.Load();
infoPlugins.Load();
}
public void SaveAll(){
infoUser.Save();
infoSystem.Save();
infoPlugins.Save();
}
public void ReloadAll(){
infoUser.Reload();
infoSystem.Reload();
infoPlugins.Reload();
}
private void TriggerProgramRestartRequested(){

View File

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace TweetDuck.Configuration.Instance{
class PluginConfigInstance : IConfigInstance<PluginConfig>{
public PluginConfig Instance { get; }
private readonly string filename;
public PluginConfigInstance(string filename, PluginConfig instance){
this.filename = filename;
this.Instance = instance;
}
public void Load(){
try{
using(StreamReader reader = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read), Encoding.UTF8)){
string line = reader.ReadLine();
if (line == "#Disabled"){
HashSet<string> newDisabled = new HashSet<string>();
while((line = reader.ReadLine()) != null){
newDisabled.Add(line);
}
Instance.ReloadSilently(newDisabled);
}
}
}catch(FileNotFoundException){
}catch(DirectoryNotFoundException){
}catch(Exception e){
Program.Reporter.HandleException("Plugin Configuration Error", "Could not read the plugin configuration file. If you continue, the list of disabled plugins will be reset to default.", true, e);
}
}
public void Save(){
try{
using(StreamWriter writer = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), Encoding.UTF8)){
writer.WriteLine("#Disabled");
foreach(string identifier in Instance.DisabledPlugins){
writer.WriteLine(identifier);
}
}
}catch(Exception e){
Program.Reporter.HandleException("Plugin Configuration Error", "Could not save the plugin configuration file.", true, e);
}
}
public void Reload(){
Load();
}
public void Reset(){
try{
File.Delete(filename);
Instance.ReloadSilently(Instance.ConstructWithDefaults<PluginConfig>().DisabledPlugins);
}catch(Exception e){
Program.Reporter.HandleException("Plugin Configuration Error", "Could not delete the plugin configuration file.", true, e);
return;
}
Reload();
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using TweetDuck.Plugins;
using TweetDuck.Plugins.Events;
namespace TweetDuck.Configuration{
sealed class PluginConfig : ConfigManager.BaseConfig, IPluginConfig{
private static readonly string[] DefaultDisabled = {
"official/clear-columns",
"official/reply-account"
};
// CONFIGURATION
public IEnumerable<string> DisabledPlugins => disabled;
public event EventHandler<PluginChangedStateEventArgs> PluginChangedState;
public void SetEnabled(Plugin plugin, bool enabled){
if ((enabled && disabled.Remove(plugin.Identifier)) || (!enabled && disabled.Add(plugin.Identifier))){
PluginChangedState?.Invoke(this, new PluginChangedStateEventArgs(plugin, enabled));
Save();
}
}
public bool IsEnabled(Plugin plugin){
return !disabled.Contains(plugin.Identifier);
}
public void ReloadSilently(IEnumerable<string> newDisabled){
disabled.Clear();
disabled.UnionWith(newDisabled);
}
private readonly HashSet<string> disabled = new HashSet<string>(DefaultDisabled);
// END OF CONFIG
public PluginConfig(ConfigManager configManager) : base(configManager){}
protected override ConfigManager.BaseConfig ConstructWithDefaults(ConfigManager configManager){
return new PluginConfig(configManager);
}
}
}

View File

@ -62,7 +62,7 @@ public FormBrowser(){
Text = Program.BrandName;
this.plugins = new PluginManager(Program.PluginPath, Program.PluginConfigFilePath);
this.plugins = new PluginManager(Program.Config.Plugins, Program.PluginPath);
this.plugins.Reloaded += plugins_Reloaded;
this.plugins.Executed += plugins_Executed;
this.plugins.Reload();

View File

@ -135,8 +135,9 @@ private void btnContinue_Click(object sender, EventArgs e){
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
if (SelectedItems.HasFlag(ProfileManager.Items.PluginData)){
Program.Config.Plugins.Reset();
try{
File.Delete(Program.PluginConfigFilePath);
Directory.Delete(Program.PluginDataPath, true);
}catch(Exception ex){
Program.Reporter.HandleException("Profile Reset", "Could not delete plugin data.", true, ex);

View File

@ -89,7 +89,7 @@ private void btnConfigure_Click(object sender, EventArgs e){
}
private void btnToggleState_Click(object sender, EventArgs e){
pluginManager.Config.ToggleEnabled(plugin);
pluginManager.Config.SetEnabled(plugin, !pluginManager.Config.IsEnabled(plugin));
UpdatePluginState();
}

14
Plugins/IPluginConfig.cs Normal file
View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using TweetDuck.Plugins.Events;
namespace TweetDuck.Plugins{
interface IPluginConfig{
IEnumerable<string> DisabledPlugins { get; }
event EventHandler<PluginChangedStateEventArgs> PluginChangedState;
void SetEnabled(Plugin plugin, bool enabled);
bool IsEnabled(Plugin plugin);
}
}

View File

@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using TweetDuck.Plugins.Events;
namespace TweetDuck.Plugins{
sealed class PluginConfig{
public event EventHandler<PluginChangedStateEventArgs> PluginChangedState;
public IEnumerable<string> DisabledPlugins => disabled;
public bool AnyDisabled => disabled.Count > 0;
private static readonly string[] DefaultDisabled = {
"official/clear-columns",
"official/reply-account"
};
private readonly HashSet<string> disabled = new HashSet<string>();
public void SetEnabled(Plugin plugin, bool enabled){
if ((enabled && disabled.Remove(plugin.Identifier)) || (!enabled && disabled.Add(plugin.Identifier))){
PluginChangedState?.Invoke(this, new PluginChangedStateEventArgs(plugin, enabled));
}
}
public void ToggleEnabled(Plugin plugin){
SetEnabled(plugin, !IsEnabled(plugin));
}
public bool IsEnabled(Plugin plugin){
return !disabled.Contains(plugin.Identifier);
}
public void Save(string file){
try{
using(StreamWriter writer = new StreamWriter(new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None), Encoding.UTF8)){
writer.WriteLine("#Disabled");
foreach(string identifier in disabled){
writer.WriteLine(identifier);
}
}
}catch(Exception e){
Program.Reporter.HandleException("Plugin Configuration Error", "Could not save the plugin configuration file.", true, e);
}
}
public void Load(string file){
try{
using(StreamReader reader = new StreamReader(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read), Encoding.UTF8)){
string line = reader.ReadLine();
if (line == "#Disabled"){
disabled.Clear();
while((line = reader.ReadLine()) != null){
disabled.Add(line);
}
}
}
}catch(FileNotFoundException){
disabled.Clear();
disabled.UnionWith(DefaultDisabled);
Save(file);
}catch(DirectoryNotFoundException){
}catch(Exception e){
Program.Reporter.HandleException("Plugin Configuration Error", "Could not read the plugin configuration file. If you continue, the list of disabled plugins will be reset to default.", true, e);
}
}
}
}

View File

@ -21,13 +21,12 @@ sealed class PluginManager{
public IEnumerable<Plugin> Plugins => plugins;
public IEnumerable<InjectedHTML> NotificationInjections => bridge.NotificationInjections;
public PluginConfig Config { get; }
public IPluginConfig Config { get; }
public event EventHandler<PluginErrorEventArgs> Reloaded;
public event EventHandler<PluginErrorEventArgs> Executed;
private readonly string rootPath;
private readonly string configPath;
private readonly PluginBridge bridge;
private readonly HashSet<Plugin> plugins = new HashSet<Plugin>();
@ -36,15 +35,12 @@ sealed class PluginManager{
private IWebBrowser mainBrowser;
public PluginManager(string rootPath, string configPath){
public PluginManager(IPluginConfig config, string rootPath){
this.Config = config;
this.Config.PluginChangedState += Config_PluginChangedState;
this.rootPath = rootPath;
this.configPath = configPath;
this.Config = new PluginConfig();
this.bridge = new PluginBridge(this);
Config.Load(configPath);
Config.PluginChangedState += Config_PluginChangedState;
}
public void Register(IWebBrowser browser, PluginEnvironment environment, Control sync, bool asMainBrowser = false){
@ -65,7 +61,6 @@ public void Register(IWebBrowser browser, PluginEnvironment environment, Control
private void Config_PluginChangedState(object sender, PluginChangedStateEventArgs e){
mainBrowser?.ExecuteScriptAsync("TDPF_setPluginState", e.Plugin, e.IsEnabled);
Config.Save(configPath);
}
public bool IsPluginInstalled(string identifier){
@ -120,8 +115,6 @@ public Plugin GetPluginFromToken(int token){
}
public void Reload(){
Config.Load(configPath);
plugins.Clear();
tokens.Clear();

View File

@ -1,9 +1,10 @@
using TweetDuck.Plugins.Enums;
using System.Linq;
using TweetDuck.Plugins.Enums;
namespace TweetDuck.Plugins{
static class PluginScriptGenerator{
public static string GenerateConfig(PluginConfig config){
return config.AnyDisabled ? "window.TD_PLUGINS.disabled = [\""+string.Join("\",\"", config.DisabledPlugins)+"\"];" : string.Empty;
public static string GenerateConfig(IPluginConfig config){
return "window.TD_PLUGINS.disabled = ["+string.Join(",", config.DisabledPlugins.Select(id => $"\"{id}\""))+"]";
}
public static string GeneratePlugin(string pluginIdentifier, string pluginContents, int pluginToken, PluginEnvironment environment){

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="packages\CefSharp.WinForms.67.0.0-pre01\build\CefSharp.WinForms.props" Condition="Exists('packages\CefSharp.WinForms.67.0.0-pre01\build\CefSharp.WinForms.props')" />
<Import Project="packages\CefSharp.Common.67.0.0-pre01\build\CefSharp.Common.props" Condition="Exists('packages\CefSharp.Common.67.0.0-pre01\build\CefSharp.Common.props')" />
@ -57,6 +57,7 @@
<Compile Include="Configuration\Instance\FileConfigInstance.cs" />
<Compile Include="Configuration\ConfigManager.cs" />
<Compile Include="Configuration\Instance\IConfigInstance.cs" />
<Compile Include="Configuration\Instance\PluginConfigInstance.cs" />
<Compile Include="Configuration\LockManager.cs" />
<Compile Include="Configuration\SystemConfig.cs" />
<Compile Include="Configuration\UserConfig.cs" />
@ -259,10 +260,11 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="Plugins\Enums\PluginFolder.cs" />
<Compile Include="Plugins\IPluginConfig.cs" />
<Compile Include="Plugins\Plugin.cs" />
<Compile Include="Plugins\Events\PluginChangedStateEventArgs.cs" />
<Compile Include="Plugins\PluginBridge.cs" />
<Compile Include="Plugins\PluginConfig.cs" />
<Compile Include="Configuration\PluginConfig.cs" />
<Compile Include="Plugins\Enums\PluginEnvironment.cs" />
<Compile Include="Plugins\Enums\PluginGroup.cs" />
<Compile Include="Plugins\Events\PluginErrorEventArgs.cs" />