BililiveRecorder/BililiveRecorder.Core/Config/ConfigParser.cs

179 lines
5.8 KiB
C#
Raw Normal View History

2018-11-01 23:40:50 +08:00
using System;
using System.IO;
2021-01-03 11:38:20 +08:00
using System.Linq;
2021-01-01 14:46:27 +08:00
using System.Text;
using Newtonsoft.Json;
2021-02-23 18:03:37 +08:00
using Serilog;
2018-11-01 23:40:50 +08:00
2021-01-01 14:46:27 +08:00
#nullable enable
2018-11-01 23:40:50 +08:00
namespace BililiveRecorder.Core.Config
{
2021-02-23 18:03:37 +08:00
public class ConfigParser
2018-11-01 23:40:50 +08:00
{
public const string CONFIG_FILE_NAME = "config.json";
2021-02-23 18:03:37 +08:00
private static readonly ILogger logger = Log.ForContext<ConfigParser>();
private static readonly JsonSerializerSettings settings = new JsonSerializerSettings()
{
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
};
2020-06-21 19:39:32 +08:00
public static V3.ConfigV3? LoadFromDirectory(string directory)
2018-11-01 23:40:50 +08:00
{
if (!Directory.Exists(directory))
2019-01-31 14:17:38 +08:00
{
logger.Warning("目标文件夹不存在");
return null;
}
2019-01-31 14:17:38 +08:00
var path = Path.Combine(directory, CONFIG_FILE_NAME);
2021-01-01 14:46:27 +08:00
return LoadFromFile(path);
}
public static V3.ConfigV3? LoadFromFile(string path)
{
try
{
if (!File.Exists(path))
2018-11-01 23:40:50 +08:00
{
logger.Information("初始化默认设置,因为配置文件不存在 {Path}", path);
2021-12-19 20:58:32 +08:00
return new V3.ConfigV3();
2018-11-01 23:40:50 +08:00
}
2021-01-01 14:46:27 +08:00
logger.Debug("Loading config from {Path}", path);
var json = File.ReadAllText(path, Encoding.UTF8);
2021-01-01 14:46:27 +08:00
return LoadJson(json);
}
catch (Exception ex)
{
logger.Error(ex, "从文件加载设置时出错");
return null;
}
}
2021-12-19 20:58:32 +08:00
public static V3.ConfigV3? LoadJson(string json)
2021-01-01 14:46:27 +08:00
{
try
{
2021-02-23 18:03:37 +08:00
logger.Debug("Config json: {Json}", json);
2021-01-01 14:46:27 +08:00
var configBase = JsonConvert.DeserializeObject<ConfigBase>(json);
switch (configBase)
2018-11-01 23:40:50 +08:00
{
2021-01-01 14:46:27 +08:00
case V1.ConfigV1Wrapper v1:
{
logger.Debug("读取到 config v1");
#pragma warning disable CS0612
2021-02-23 18:03:37 +08:00
var v1Data = JsonConvert.DeserializeObject<V1.ConfigV1>(v1.Data ?? string.Empty);
2021-01-01 14:46:27 +08:00
#pragma warning restore CS0612
2021-05-01 17:57:43 +08:00
if (v1Data is null)
2021-12-19 20:58:32 +08:00
return new V3.ConfigV3();
2021-01-01 14:46:27 +08:00
2021-12-19 20:58:32 +08:00
var newConfig = ConfigMapper.Map2To3(ConfigMapper.Map1To2(v1Data));
2021-01-01 14:46:27 +08:00
return newConfig;
}
2021-12-19 20:58:32 +08:00
#pragma warning disable CS0618 // Type or member is obsolete
2021-01-01 14:46:27 +08:00
case V2.ConfigV2 v2:
2021-12-19 20:58:32 +08:00
#pragma warning restore CS0618 // Type or member is obsolete
2021-01-01 14:46:27 +08:00
logger.Debug("读取到 config v2");
2021-12-19 20:58:32 +08:00
return ConfigMapper.Map2To3(v2);
case V3.ConfigV3 v3:
logger.Debug("读取到 config v3");
return v3;
2021-01-01 14:46:27 +08:00
default:
logger.Error("读取到不支持的设置版本");
return null;
2018-11-01 23:40:50 +08:00
}
}
2021-01-01 14:46:27 +08:00
catch (Exception ex)
2018-11-01 23:40:50 +08:00
{
2021-01-01 14:46:27 +08:00
logger.Error(ex, "解析设置时出错");
return null;
2018-11-01 23:40:50 +08:00
}
}
public static bool Save(V3.ConfigV3 config)
2018-11-01 23:40:50 +08:00
{
var directory = config.Global.WorkDirectory;
2021-01-04 16:24:36 +08:00
if (config.DisableConfigSave)
{
logger.Debug("Skipping write config because DisableConfigSave is true.");
return true;
}
2021-01-01 14:46:27 +08:00
var json = SaveJson(config);
try
{
if (!Directory.Exists(directory))
return false;
var filepath = Path.Combine(directory, CONFIG_FILE_NAME);
if (config.ConfigPathOverride is not null)
filepath = config.ConfigPathOverride;
2021-01-01 14:46:27 +08:00
if (json is not null)
2021-01-03 11:38:20 +08:00
WriteAllTextWithBackup(filepath, json);
2021-01-01 14:46:27 +08:00
return true;
}
catch (Exception ex)
2018-11-01 23:40:50 +08:00
{
2021-01-01 14:46:27 +08:00
logger.Error(ex, "保存设置时出错(写入文件)");
2018-11-01 23:40:50 +08:00
return false;
}
2021-01-01 14:46:27 +08:00
}
2021-12-19 20:58:32 +08:00
public static string? SaveJson(V3.ConfigV3 config)
2021-01-01 14:46:27 +08:00
{
2018-11-01 23:40:50 +08:00
try
{
2021-02-23 18:03:37 +08:00
var json = JsonConvert.SerializeObject(config, Formatting.None, settings);
2021-01-01 14:46:27 +08:00
return json;
2018-11-01 23:40:50 +08:00
}
2021-01-01 14:46:27 +08:00
catch (Exception ex)
2018-11-01 23:40:50 +08:00
{
2021-01-01 14:46:27 +08:00
logger.Error(ex, "保存设置时出错(序列化)");
return null;
2018-11-01 23:40:50 +08:00
}
}
2021-01-03 11:38:20 +08:00
// https://stackoverflow.com/q/25366534 with modification
public static void WriteAllTextWithBackup(string path, string contents)
2021-01-03 11:38:20 +08:00
{
2021-01-06 00:31:42 +08:00
if (!File.Exists(path))
{
File.WriteAllText(path, contents);
return;
}
2021-01-03 11:38:20 +08:00
var ext = Path.GetExtension(path);
2023-08-24 23:08:56 +08:00
var tempPath = Path.Combine(Path.GetDirectoryName(path)!, Path.ChangeExtension(path, RandomString(6) + ext));
2021-01-03 11:38:20 +08:00
var backupPath = Path.ChangeExtension(path, "backup" + ext);
// delete any existing backups
if (File.Exists(backupPath))
File.Delete(backupPath);
// get the bytes
var data = Encoding.UTF8.GetBytes(contents);
// write the data to a temp file
using (var tempFile = File.Create(tempPath, 4096, FileOptions.WriteThrough))
tempFile.Write(data, 0, data.Length);
// replace the contents
File.Replace(tempPath, path, backupPath);
}
private static readonly Random random = new Random();
private static string RandomString(int length) => new string(Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", length).Select(s => s[random.Next(s.Length)]).ToArray());
2018-11-01 23:40:50 +08:00
}
}