/ src / modules / launcher / PowerLauncher / Plugin / PluginConfig.cs
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  }