mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-02 20:34:07 +02:00
Refactor and optimize the plugin configuration file
This commit is contained in:
parent
d9a80d1085
commit
898437720b
@ -10,21 +10,25 @@ namespace TweetDuck.Configuration{
|
|||||||
sealed class ConfigManager{
|
sealed class ConfigManager{
|
||||||
public UserConfig User { get; }
|
public UserConfig User { get; }
|
||||||
public SystemConfig System { get; }
|
public SystemConfig System { get; }
|
||||||
|
public PluginConfig Plugins { get; }
|
||||||
|
|
||||||
public event EventHandler ProgramRestartRequested;
|
public event EventHandler ProgramRestartRequested;
|
||||||
|
|
||||||
private readonly FileConfigInstance<UserConfig> infoUser;
|
private readonly FileConfigInstance<UserConfig> infoUser;
|
||||||
private readonly FileConfigInstance<SystemConfig> infoSystem;
|
private readonly FileConfigInstance<SystemConfig> infoSystem;
|
||||||
|
private readonly PluginConfigInstance infoPlugins;
|
||||||
|
|
||||||
private readonly IConfigInstance<BaseConfig>[] infoList;
|
private readonly IConfigInstance<BaseConfig>[] infoList;
|
||||||
|
|
||||||
public ConfigManager(){
|
public ConfigManager(){
|
||||||
User = new UserConfig(this);
|
User = new UserConfig(this);
|
||||||
System = new SystemConfig(this);
|
System = new SystemConfig(this);
|
||||||
|
Plugins = new PluginConfig(this);
|
||||||
|
|
||||||
infoList = new IConfigInstance<BaseConfig>[]{
|
infoList = new IConfigInstance<BaseConfig>[]{
|
||||||
infoUser = new FileConfigInstance<UserConfig>(Program.UserConfigFilePath, User, "program options"),
|
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
|
// TODO refactor further
|
||||||
@ -51,16 +55,19 @@ public ConfigManager(){
|
|||||||
public void LoadAll(){
|
public void LoadAll(){
|
||||||
infoUser.Load();
|
infoUser.Load();
|
||||||
infoSystem.Load();
|
infoSystem.Load();
|
||||||
|
infoPlugins.Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveAll(){
|
public void SaveAll(){
|
||||||
infoUser.Save();
|
infoUser.Save();
|
||||||
infoSystem.Save();
|
infoSystem.Save();
|
||||||
|
infoPlugins.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadAll(){
|
public void ReloadAll(){
|
||||||
infoUser.Reload();
|
infoUser.Reload();
|
||||||
infoSystem.Reload();
|
infoSystem.Reload();
|
||||||
|
infoPlugins.Reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TriggerProgramRestartRequested(){
|
private void TriggerProgramRestartRequested(){
|
||||||
|
69
Configuration/Instance/PluginConfigInstance.cs
Normal file
69
Configuration/Instance/PluginConfigInstance.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
Configuration/PluginConfig.cs
Normal file
45
Configuration/PluginConfig.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,7 +62,7 @@ public FormBrowser(){
|
|||||||
|
|
||||||
Text = Program.BrandName;
|
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.Reloaded += plugins_Reloaded;
|
||||||
this.plugins.Executed += plugins_Executed;
|
this.plugins.Executed += plugins_Executed;
|
||||||
this.plugins.Reload();
|
this.plugins.Reload();
|
||||||
|
@ -135,8 +135,9 @@ private void btnContinue_Click(object sender, EventArgs e){
|
|||||||
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
|
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
|
||||||
|
|
||||||
if (SelectedItems.HasFlag(ProfileManager.Items.PluginData)){
|
if (SelectedItems.HasFlag(ProfileManager.Items.PluginData)){
|
||||||
|
Program.Config.Plugins.Reset();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
File.Delete(Program.PluginConfigFilePath);
|
|
||||||
Directory.Delete(Program.PluginDataPath, true);
|
Directory.Delete(Program.PluginDataPath, true);
|
||||||
}catch(Exception ex){
|
}catch(Exception ex){
|
||||||
Program.Reporter.HandleException("Profile Reset", "Could not delete plugin data.", true, ex);
|
Program.Reporter.HandleException("Profile Reset", "Could not delete plugin data.", true, ex);
|
||||||
|
@ -89,7 +89,7 @@ private void btnConfigure_Click(object sender, EventArgs e){
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void btnToggleState_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();
|
UpdatePluginState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
Plugins/IPluginConfig.cs
Normal file
14
Plugins/IPluginConfig.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,13 +21,12 @@ sealed class PluginManager{
|
|||||||
public IEnumerable<Plugin> Plugins => plugins;
|
public IEnumerable<Plugin> Plugins => plugins;
|
||||||
public IEnumerable<InjectedHTML> NotificationInjections => bridge.NotificationInjections;
|
public IEnumerable<InjectedHTML> NotificationInjections => bridge.NotificationInjections;
|
||||||
|
|
||||||
public PluginConfig Config { get; }
|
public IPluginConfig Config { get; }
|
||||||
|
|
||||||
public event EventHandler<PluginErrorEventArgs> Reloaded;
|
public event EventHandler<PluginErrorEventArgs> Reloaded;
|
||||||
public event EventHandler<PluginErrorEventArgs> Executed;
|
public event EventHandler<PluginErrorEventArgs> Executed;
|
||||||
|
|
||||||
private readonly string rootPath;
|
private readonly string rootPath;
|
||||||
private readonly string configPath;
|
|
||||||
private readonly PluginBridge bridge;
|
private readonly PluginBridge bridge;
|
||||||
|
|
||||||
private readonly HashSet<Plugin> plugins = new HashSet<Plugin>();
|
private readonly HashSet<Plugin> plugins = new HashSet<Plugin>();
|
||||||
@ -36,15 +35,12 @@ sealed class PluginManager{
|
|||||||
|
|
||||||
private IWebBrowser mainBrowser;
|
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.rootPath = rootPath;
|
||||||
this.configPath = configPath;
|
|
||||||
|
|
||||||
this.Config = new PluginConfig();
|
|
||||||
this.bridge = new PluginBridge(this);
|
this.bridge = new PluginBridge(this);
|
||||||
|
|
||||||
Config.Load(configPath);
|
|
||||||
Config.PluginChangedState += Config_PluginChangedState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Register(IWebBrowser browser, PluginEnvironment environment, Control sync, bool asMainBrowser = false){
|
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){
|
private void Config_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||||
mainBrowser?.ExecuteScriptAsync("TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
mainBrowser?.ExecuteScriptAsync("TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
||||||
Config.Save(configPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPluginInstalled(string identifier){
|
public bool IsPluginInstalled(string identifier){
|
||||||
@ -120,8 +115,6 @@ public Plugin GetPluginFromToken(int token){
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Reload(){
|
public void Reload(){
|
||||||
Config.Load(configPath);
|
|
||||||
|
|
||||||
plugins.Clear();
|
plugins.Clear();
|
||||||
tokens.Clear();
|
tokens.Clear();
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using TweetDuck.Plugins.Enums;
|
using System.Linq;
|
||||||
|
using TweetDuck.Plugins.Enums;
|
||||||
|
|
||||||
namespace TweetDuck.Plugins{
|
namespace TweetDuck.Plugins{
|
||||||
static class PluginScriptGenerator{
|
static class PluginScriptGenerator{
|
||||||
public static string GenerateConfig(PluginConfig config){
|
public static string GenerateConfig(IPluginConfig config){
|
||||||
return config.AnyDisabled ? "window.TD_PLUGINS.disabled = [\""+string.Join("\",\"", config.DisabledPlugins)+"\"];" : string.Empty;
|
return "window.TD_PLUGINS.disabled = ["+string.Join(",", config.DisabledPlugins.Select(id => $"\"{id}\""))+"]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GeneratePlugin(string pluginIdentifier, string pluginContents, int pluginToken, PluginEnvironment environment){
|
public static string GeneratePlugin(string pluginIdentifier, string pluginContents, int pluginToken, PluginEnvironment environment){
|
||||||
|
@ -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">
|
<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.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')" />
|
<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\Instance\FileConfigInstance.cs" />
|
||||||
<Compile Include="Configuration\ConfigManager.cs" />
|
<Compile Include="Configuration\ConfigManager.cs" />
|
||||||
<Compile Include="Configuration\Instance\IConfigInstance.cs" />
|
<Compile Include="Configuration\Instance\IConfigInstance.cs" />
|
||||||
|
<Compile Include="Configuration\Instance\PluginConfigInstance.cs" />
|
||||||
<Compile Include="Configuration\LockManager.cs" />
|
<Compile Include="Configuration\LockManager.cs" />
|
||||||
<Compile Include="Configuration\SystemConfig.cs" />
|
<Compile Include="Configuration\SystemConfig.cs" />
|
||||||
<Compile Include="Configuration\UserConfig.cs" />
|
<Compile Include="Configuration\UserConfig.cs" />
|
||||||
@ -259,10 +260,11 @@
|
|||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Plugins\Enums\PluginFolder.cs" />
|
<Compile Include="Plugins\Enums\PluginFolder.cs" />
|
||||||
|
<Compile Include="Plugins\IPluginConfig.cs" />
|
||||||
<Compile Include="Plugins\Plugin.cs" />
|
<Compile Include="Plugins\Plugin.cs" />
|
||||||
<Compile Include="Plugins\Events\PluginChangedStateEventArgs.cs" />
|
<Compile Include="Plugins\Events\PluginChangedStateEventArgs.cs" />
|
||||||
<Compile Include="Plugins\PluginBridge.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\PluginEnvironment.cs" />
|
||||||
<Compile Include="Plugins\Enums\PluginGroup.cs" />
|
<Compile Include="Plugins\Enums\PluginGroup.cs" />
|
||||||
<Compile Include="Plugins\Events\PluginErrorEventArgs.cs" />
|
<Compile Include="Plugins\Events\PluginErrorEventArgs.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user