将utils替换为包
This commit is contained in:
parent
877d4d941f
commit
1c1f30a297
@ -16,12 +16,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LLCSharpUtils" Version="1.0.2" />
|
||||
<PackageReference Include="NativeFileDialogSharp" Version="0.5.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="TMDbLib" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using BangumiRenamer.Utils;
|
||||
using LLCSharpUtils;
|
||||
|
||||
namespace BangumiRenamer.ConfigSchema;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using BangumiRenamer.Utils;
|
||||
using LLCSharpUtils;
|
||||
|
||||
namespace BangumiRenamer.Config;
|
||||
|
||||
|
||||
15
Src/Tools/Config.cs
Normal file
15
Src/Tools/Config.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace BangumiRenamer.Tools;
|
||||
|
||||
public class Config
|
||||
{
|
||||
private static readonly Lazy<LLCSharpUtils.Config> _lazyConfig = new (() =>
|
||||
{
|
||||
var config = new LLCSharpUtils.Config
|
||||
{
|
||||
ConfigPath = "config.json"
|
||||
};
|
||||
if (!config.Load(true)) throw new Exception("Failed to load config.json");
|
||||
return config;
|
||||
});
|
||||
public static LLCSharpUtils.Config G => _lazyConfig.Value;
|
||||
}
|
||||
@ -1,23 +1,16 @@
|
||||
using BangumiRenamer.Utils;
|
||||
using LLCSharpUtils;
|
||||
|
||||
namespace BangumiRenamer.Tools;
|
||||
|
||||
public class EmbededResourceViewer
|
||||
{
|
||||
private static readonly Lazy<Log> _lazy = new (() =>
|
||||
{
|
||||
var log = new Log(new Log.LogConfig());
|
||||
if (!log.Init()) return null;
|
||||
return log;
|
||||
});
|
||||
static ILog Log => _lazy.Value;
|
||||
|
||||
public static void PrintResourceNames()
|
||||
{
|
||||
var names = ResourceLoader.GetAllResNames();
|
||||
var loader = new EmbeddedResourceLoader();
|
||||
var names = loader.GetAllResNames();
|
||||
foreach (var name in names)
|
||||
{
|
||||
Log.Info(name);
|
||||
Logger.G.Info(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,10 @@
|
||||
using System.Diagnostics;
|
||||
using BangumiRenamer.Utils;
|
||||
using NativeFileDialogSharp;
|
||||
|
||||
namespace BangumiRenamer.Tools;
|
||||
|
||||
public static class FolderCloner
|
||||
{
|
||||
private static readonly Lazy<Log> _lazy = new (() =>
|
||||
{
|
||||
var log = new Log(new Log.LogConfig());
|
||||
if (!log.Init()) return null;
|
||||
return log;
|
||||
});
|
||||
static ILog Log => _lazy.Value;
|
||||
|
||||
public static void Run()
|
||||
{
|
||||
var result = Dialog.FolderPicker();
|
||||
@ -73,7 +64,7 @@ public static class FolderCloner
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Clone");
|
||||
Logger.G.Error(ex, "Clone");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
Src/Tools/Logger.cs
Normal file
15
Src/Tools/Logger.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using LLCSharpUtils;
|
||||
|
||||
namespace BangumiRenamer.Tools;
|
||||
|
||||
public class Logger
|
||||
{
|
||||
private static readonly Lazy<Log> _lazy = new (() =>
|
||||
{
|
||||
var log = new Log(new LogConfig());
|
||||
if (!log.Init()) throw new Exception("Failed to initialize log");
|
||||
return log;
|
||||
});
|
||||
|
||||
public static Log G => _lazy.Value;
|
||||
}
|
||||
@ -1,34 +1,16 @@
|
||||
using BangumiRenamer.Config;
|
||||
using BangumiRenamer.ConfigSchema;
|
||||
|
||||
namespace BangumiRenamer.Tools;
|
||||
|
||||
using Utils;
|
||||
using TMDbLib.Client;
|
||||
using Data;
|
||||
using NativeFileDialogSharp;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using BangumiRenamer.Data;
|
||||
|
||||
namespace BangumiRenamer.Tools;
|
||||
|
||||
public static class ShowCompletionChecker
|
||||
{
|
||||
private static readonly Lazy<Log> _lazyLog = new (() =>
|
||||
{
|
||||
var log = new Log(new Log.LogConfig());
|
||||
if (!log.Init()) return null;
|
||||
return log;
|
||||
});
|
||||
static ILog Log => _lazyLog.Value;
|
||||
|
||||
private static readonly Lazy<Config> _lazyConfig = new (() =>
|
||||
{
|
||||
var config = new Config("config.json");
|
||||
if (!config.Load()) return null;
|
||||
return config;
|
||||
});
|
||||
static IConfig Config => _lazyConfig.Value;
|
||||
|
||||
static List<Show> FindShows(string checkPath)
|
||||
{
|
||||
var shows = new List<Show>();
|
||||
@ -72,11 +54,11 @@ public static class ShowCompletionChecker
|
||||
var checkPath = dir.Path;
|
||||
|
||||
var shows = FindShows(checkPath);
|
||||
Log.Info($"Total Shows: {shows.Count}");
|
||||
Logger.G.Info($"Total Shows: {shows.Count}");
|
||||
|
||||
var client = new TMDbClient(
|
||||
apiKey: Config.Get<TMDBConfig>().ApiKey ,
|
||||
proxy: new WebProxy(Config.Get<ProxyConfig>().HttpProxy));
|
||||
apiKey: Config.G.Get<TMDBConfig>().ApiKey ,
|
||||
proxy: new WebProxy(Config.G.Get<ProxyConfig>().HttpProxy));
|
||||
|
||||
var output = new StringBuilder();
|
||||
foreach (var t in shows)
|
||||
@ -88,7 +70,7 @@ public static class ShowCompletionChecker
|
||||
var info = result.Results.FirstOrDefault();
|
||||
if (info == null)
|
||||
{
|
||||
Log.Error($"找不到对应的TV:{t.title}");
|
||||
Logger.G.Error($"找不到对应的TV:{t.title}");
|
||||
continue;
|
||||
}
|
||||
foreach (var session in t.sessions)
|
||||
@ -96,7 +78,7 @@ public static class ShowCompletionChecker
|
||||
var sessionInfo = client.GetTvSeasonAsync(info.Id, session.id).Result;
|
||||
if (sessionInfo == null)
|
||||
{
|
||||
Log.Error($"季度对不上,可能找错了:{t.title} -> {info.OriginalName}");
|
||||
Logger.G.Error($"季度对不上,可能找错了:{t.title} -> {info.OriginalName}");
|
||||
break;
|
||||
}
|
||||
foreach (var episode in sessionInfo.Episodes)
|
||||
@ -109,6 +91,6 @@ public static class ShowCompletionChecker
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.Info(output.ToString());
|
||||
Logger.G.Info(output.ToString());
|
||||
}
|
||||
}
|
||||
@ -1,161 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BangumiRenamer.Utils;
|
||||
|
||||
public class ConfigItemAttribute(string name) : Attribute
|
||||
{
|
||||
public readonly string Name = name;
|
||||
}
|
||||
|
||||
public interface IConfigItem
|
||||
{
|
||||
public void BeforeSave()
|
||||
{
|
||||
}
|
||||
|
||||
public void AfterLoad()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public interface IConfig
|
||||
{
|
||||
public T Get<T>() where T : class, IConfigItem, new();
|
||||
|
||||
public void Reset<T>() where T : class, IConfigItem, new();
|
||||
|
||||
public bool Save();
|
||||
}
|
||||
|
||||
public sealed class Config(string configPath) : IConfig
|
||||
{
|
||||
public static IConfig G => _G;
|
||||
public static Config _G { private get; set; }
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, string> Cache = new();
|
||||
private readonly ConcurrentDictionary<string, IConfigItem> _configObjects = new();
|
||||
private readonly ConcurrentDictionary<string, JObject> _configs = new();
|
||||
|
||||
private static string GetConfigItemName(Type type)
|
||||
{
|
||||
if (Cache.TryGetValue(type, out var name)) return name;
|
||||
name = type.Name;
|
||||
if(type.GetCustomAttribute(typeof(ConfigItemAttribute)) is ConfigItemAttribute info)
|
||||
{
|
||||
name = string.IsNullOrEmpty(info.Name) ? type.Name : info.Name;
|
||||
}
|
||||
Cache[type] = name;
|
||||
return name;
|
||||
}
|
||||
|
||||
public T Get<T>() where T : class, IConfigItem, new()
|
||||
{
|
||||
var name = GetConfigItemName(typeof(T));
|
||||
if (_configObjects.TryGetValue(name, out var value))
|
||||
{
|
||||
return (T) value;
|
||||
}
|
||||
T result;
|
||||
if (_configs.TryGetValue(name, out var jObject))
|
||||
{
|
||||
result = jObject.ToObject<T>();
|
||||
result.AfterLoad();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new T();
|
||||
}
|
||||
_configObjects[name] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Reset<T>() where T : class, IConfigItem, new()
|
||||
{
|
||||
var name = GetConfigItemName(typeof(T));
|
||||
_configs.TryRemove(name, out _);
|
||||
_configObjects.Remove(name, out _);
|
||||
}
|
||||
|
||||
public bool Load()
|
||||
{
|
||||
_configs.Clear();
|
||||
_configObjects.Clear();
|
||||
if (!File.Exists(configPath)) return false;
|
||||
try
|
||||
{
|
||||
var configJson = File.ReadAllText(configPath);
|
||||
var config = JObject.Parse(configJson);
|
||||
foreach (var kv in config)
|
||||
{
|
||||
_configs[kv.Key] = kv.Value.ToObject<JObject>();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Save()
|
||||
{
|
||||
if (string.IsNullOrEmpty(configPath)) return false;
|
||||
try
|
||||
{
|
||||
foreach (var config in _configObjects)
|
||||
{
|
||||
config.Value.BeforeSave();
|
||||
_configs[config.Key] = JObject.FromObject(config.Value);
|
||||
}
|
||||
|
||||
File.WriteAllText(configPath, JsonConvert.SerializeObject(_configs, Formatting.Indented));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void CreateEmptyConfig()
|
||||
{
|
||||
var configItemTypes = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(assembly =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException)
|
||||
{
|
||||
return Array.Empty<Type>();
|
||||
}
|
||||
})
|
||||
.Where(type => type.IsClass &&
|
||||
!type.IsAbstract &&
|
||||
typeof(IConfigItem).IsAssignableFrom(type))
|
||||
.ToList();
|
||||
|
||||
var filePath = "config.json";
|
||||
var config = new Config(filePath);
|
||||
foreach (var type in configItemTypes)
|
||||
{
|
||||
var name = GetConfigItemName(type);
|
||||
config._configObjects[name] = (IConfigItem) Activator.CreateInstance(type);
|
||||
}
|
||||
config.Save();
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
// 使用 explorer.exe 的 /select 命令行参数
|
||||
string argument = $"/select,\"{filePath}\"";
|
||||
|
||||
// 启动 explorer.exe 进程
|
||||
Process.Start("explorer.exe", argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
169
Src/Utils/Log.cs
169
Src/Utils/Log.cs
@ -1,169 +0,0 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using Serilog.Context;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
|
||||
namespace BangumiRenamer.Utils;
|
||||
|
||||
public interface ILog
|
||||
{
|
||||
public void Debug(string message, [CallerFilePath] string callerFilePath = "",
|
||||
[CallerMemberName] string callerMemberName = "");
|
||||
|
||||
public void Info(string message, [CallerFilePath] string callerFilePath = "",
|
||||
[CallerMemberName] string callerMemberName = "");
|
||||
|
||||
public void Warn(string message, [CallerFilePath] string callerFilePath = "",
|
||||
[CallerMemberName] string callerMemberName = "");
|
||||
|
||||
public void Error(string message, [CallerFilePath] string callerFilePath = "",
|
||||
[CallerMemberName] string callerMemberName = "");
|
||||
|
||||
public void Error(Exception ex, string message);
|
||||
}
|
||||
|
||||
public sealed class Log : ILog
|
||||
{
|
||||
public enum LogLevel
|
||||
{
|
||||
Error,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
}
|
||||
|
||||
[ConfigItem("Log")]
|
||||
public class LogConfig : IConfigItem
|
||||
{
|
||||
[JsonIgnore] public LogLevel Level = LogLevel.Debug;
|
||||
[JsonProperty("Level")] private string _level;
|
||||
|
||||
public bool ToConsole = true;
|
||||
|
||||
public bool ToFile = false;
|
||||
public string LogFilePath;
|
||||
|
||||
public void AfterLoad()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_level)) LogLevel.TryParse(_level, out Level);
|
||||
}
|
||||
|
||||
public void BeforeSave()
|
||||
{
|
||||
_level = Level.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static ILog G => _G;
|
||||
public static Log _G { private get; set; }
|
||||
|
||||
private LogConfig _config;
|
||||
|
||||
private Logger _logger;
|
||||
|
||||
public Log(LogConfig config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public bool Init()
|
||||
{
|
||||
if (_config == null) return false;
|
||||
var config = new LoggerConfiguration();
|
||||
switch (_config.Level)
|
||||
{
|
||||
case LogLevel.Error:
|
||||
config.MinimumLevel.Error();
|
||||
break;
|
||||
case LogLevel.Warn:
|
||||
config.MinimumLevel.Warning();
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
config.MinimumLevel.Debug();
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
default:
|
||||
config.MinimumLevel.Information();
|
||||
break;
|
||||
}
|
||||
|
||||
var outputTemplate = "[{Timestamp:HH:mm:ss}][{CallerPlace}][{Level:u3}] {Message:lj}{NewLine}{Exception}";
|
||||
|
||||
if (_config.ToConsole)
|
||||
{
|
||||
config.WriteTo.Console(
|
||||
outputTemplate: outputTemplate,
|
||||
theme: AnsiConsoleTheme.Sixteen
|
||||
);
|
||||
}
|
||||
|
||||
if (_config.ToFile)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_config.LogFilePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
config.WriteTo.File(
|
||||
outputTemplate: outputTemplate,
|
||||
path: _config.LogFilePath
|
||||
);
|
||||
}
|
||||
|
||||
config.Enrich.FromLogContext()
|
||||
.Enrich.WithThreadId();
|
||||
try
|
||||
{
|
||||
_logger = config.CreateLogger();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 静态快捷方法 - 使用更简短的名称
|
||||
public void Debug(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
|
||||
{
|
||||
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
|
||||
{
|
||||
_logger.Write(LogEventLevel.Debug, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Info(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
|
||||
{
|
||||
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
|
||||
{
|
||||
_logger.Write(LogEventLevel.Information, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Warn(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
|
||||
{
|
||||
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
|
||||
{
|
||||
_logger.Write(LogEventLevel.Warning, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Error(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
|
||||
{
|
||||
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
|
||||
{
|
||||
_logger.Write(LogEventLevel.Error, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Error(Exception ex, string message)
|
||||
=> WriteLog(ex, message);
|
||||
|
||||
private void WriteLog(Exception ex, string message)
|
||||
{
|
||||
_logger.Error(ex, message);
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace BangumiRenamer.Utils;
|
||||
|
||||
public static class ResourceLoader
|
||||
{
|
||||
public static IEnumerable<string> GetAllResNames()
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
return assembly.GetManifestResourceNames();
|
||||
}
|
||||
|
||||
public static async Task<string> ReadText(string resPath)
|
||||
{
|
||||
var stream = GetResStream(resPath);
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Position = 0;
|
||||
}
|
||||
|
||||
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||||
return await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
public static Stream GetResStream(string resPath)
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var resourceName = resPath;
|
||||
if (assembly.GetManifestResourceInfo(resPath) == null)
|
||||
{
|
||||
resourceName = $"{assembly.GetName().Name}.{resourceName.Replace('\\', '.').Replace('/', '.')}";
|
||||
}
|
||||
var stream = assembly.GetManifestResourceStream(resourceName);
|
||||
if (stream == null)
|
||||
{
|
||||
throw new FileNotFoundException($"资源 {resourceName} 未找到");
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user