PluginConfig.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections.Generic; 7 using System.IO.Abstractions; 8 using System.Linq; 9 using System.Reflection; 10 using System.Text.Json; 11 12 using Wox.Plugin; 13 using Wox.Plugin.Logger; 14 15 namespace PowerLauncher.Plugin 16 { 17 internal abstract class PluginConfig 18 { 19 private static readonly IFileSystem FileSystem = new FileSystem(); 20 private static readonly IPath Path = FileSystem.Path; 21 private static readonly IFile File = FileSystem.File; 22 private static readonly IDirectory Directory = FileSystem.Directory; 23 24 private const string PluginConfigName = "plugin.json"; 25 private static readonly List<PluginMetadata> PluginMetadatas = new List<PluginMetadata>(); 26 27 /// <summary> 28 /// Parse plugin metadata in giving directories 29 /// </summary> 30 /// <param name="pluginDirectories">directories with plugins</param> 31 /// <returns>List with plugin meta data</returns> 32 public static List<PluginMetadata> Parse(string[] pluginDirectories) 33 { 34 PluginMetadatas.Clear(); 35 var directories = pluginDirectories.SelectMany(Directory.GetDirectories); 36 ParsePluginConfigs(directories); 37 38 return PluginMetadatas; 39 } 40 41 private static void ParsePluginConfigs(IEnumerable<string> directories) 42 { 43 // todo use linq when disable plugin is implemented since parallel.foreach + list is not thread saft 44 foreach (var directory in directories) 45 { 46 if (File.Exists(Path.Combine(directory, "NeedDelete.txt"))) 47 { 48 try 49 { 50 Directory.Delete(directory, true); 51 } 52 catch (Exception e) 53 { 54 Log.Exception($"Can't delete <{directory}>", e, MethodBase.GetCurrentMethod().DeclaringType); 55 } 56 } 57 else 58 { 59 PluginMetadata metadata = GetPluginMetadata(directory); 60 if (metadata != null) 61 { 62 PluginMetadatas.Add(metadata); 63 } 64 } 65 } 66 } 67 68 private static PluginMetadata GetPluginMetadata(string pluginDirectory) 69 { 70 string configPath = Path.Combine(pluginDirectory, PluginConfigName); 71 if (!File.Exists(configPath)) 72 { 73 Log.Error($"Didn't find config file <{configPath}>", MethodBase.GetCurrentMethod().DeclaringType); 74 75 return null; 76 } 77 78 PluginMetadata metadata; 79 try 80 { 81 metadata = JsonSerializer.Deserialize<PluginMetadata>(File.ReadAllText(configPath)); 82 metadata.PluginDirectory = pluginDirectory; 83 } 84 catch (Exception e) 85 { 86 Log.Exception($"|PluginConfig.GetPluginMetadata|invalid json for config <{configPath}>", e, MethodBase.GetCurrentMethod().DeclaringType); 87 return null; 88 } 89 90 if (!AllowedLanguage.IsAllowed(metadata.Language)) 91 { 92 Log.Error($"|PluginConfig.GetPluginMetadata|Invalid language <{metadata.Language}> for config <{configPath}>", MethodBase.GetCurrentMethod().DeclaringType); 93 return null; 94 } 95 96 if (string.IsNullOrEmpty(metadata.IcoPathDark) || string.IsNullOrEmpty(metadata.IcoPathLight)) 97 { 98 Log.Error($"|PluginConfig.GetPluginMetadata|couldn't get icon information for config <{configPath}>", MethodBase.GetCurrentMethod().DeclaringType); 99 return null; 100 } 101 102 if (!File.Exists(metadata.ExecuteFilePath)) 103 { 104 Log.Error($"|PluginConfig.GetPluginMetadata|execute file path didn't exist <{metadata.ExecuteFilePath}> for config <{configPath}", MethodBase.GetCurrentMethod().DeclaringType); 105 return null; 106 } 107 108 return metadata; 109 } 110 } 111 }