120 lines
4.6 KiB
C#
120 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
public class RenameHandler : IActionHandler
|
|
{
|
|
public string? Prefix => "rename";
|
|
|
|
public PluginMetadata Metadata => new PluginMetadata("Rename", "파일 일괄 이름변경 — rename", "1.0", "AX");
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
string text = query.Trim();
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlyArray<LauncherItem>(new LauncherItem[3]
|
|
{
|
|
new LauncherItem("파일 일괄 이름변경", "rename [폴더\\패턴] [새이름 템플릿]", null, null, null, "\ue8ac"),
|
|
new LauncherItem("사용 예시", "rename C:\\work\\*.xlsx 보고서_{n} → 보고서_1.xlsx, 보고서_2.xlsx ...", null, null, null, "\ue946"),
|
|
new LauncherItem("변수: {n} 순번, {date} 날짜, {orig} 원본명", "rename D:\\photos\\*.jpg {date}_{n} → 2026-03-27_1.jpg ...", null, null, null, "\ue946")
|
|
}));
|
|
}
|
|
string[] array = text.Split(' ', 2, StringSplitOptions.TrimEntries);
|
|
string path = array[0];
|
|
string text2 = ((array.Length > 1) ? array[1] : null);
|
|
string dir = Path.GetDirectoryName(path);
|
|
string fileName = Path.GetFileName(path);
|
|
if (string.IsNullOrWhiteSpace(dir) || !Directory.Exists(dir))
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("폴더를 찾을 수 없습니다", "경로: " + (dir ?? "(비어 있음)"), null, null, null, "\ue7ba")));
|
|
}
|
|
string[] array2;
|
|
try
|
|
{
|
|
array2 = Directory.GetFiles(dir, fileName);
|
|
}
|
|
catch
|
|
{
|
|
array2 = Array.Empty<string>();
|
|
}
|
|
if (array2.Length == 0)
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("일치하는 파일이 없습니다", "패턴: " + fileName + " · 폴더: " + dir, null, null, null, "\ue7ba")));
|
|
}
|
|
Array.Sort(array2);
|
|
if (string.IsNullOrWhiteSpace(text2))
|
|
{
|
|
List<LauncherItem> list = array2.Take(10).Select((string f, int i) => new LauncherItem(Path.GetFileName(f), dir, null, null, null, "\ue8a5")).ToList();
|
|
list.Insert(0, new LauncherItem($"총 {array2.Length}개 파일 발견", "뒤에 새 이름 템플릿을 추가하세요 (예: 보고서_{n})", null, null, null, "\ue946"));
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
string newValue = DateTime.Today.ToString("yyyy-MM-dd");
|
|
List<(string, string)> list2 = new List<(string, string)>();
|
|
for (int num = 0; num < array2.Length; num++)
|
|
{
|
|
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(array2[num]);
|
|
string extension = Path.GetExtension(array2[num]);
|
|
string text3 = text2.Replace("{n}", (num + 1).ToString()).Replace("{date}", newValue).Replace("{orig}", fileNameWithoutExtension);
|
|
if (!Path.HasExtension(text3))
|
|
{
|
|
text3 += extension;
|
|
}
|
|
list2.Add((Path.GetFileName(array2[num]), text3));
|
|
}
|
|
List<LauncherItem> list3 = new List<LauncherItem>();
|
|
list3.Add(new LauncherItem($"총 {array2.Length}개 파일 이름변경 실행", $"Enter로 실행 · {list2[0].Item1} → {list2[0].Item2} ...", null, ValueTuple.Create(dir, array2, list2.Select<(string, string), string>(((string From, string To) p) => p.To).ToArray()), null, "\ue8ac"));
|
|
foreach (var (text4, text5) in list2.Take(8))
|
|
{
|
|
list3.Add(new LauncherItem(text4 + " → " + text5, "미리보기", null, null, null, "\ue8a5"));
|
|
}
|
|
if (array2.Length > 8)
|
|
{
|
|
list3.Add(new LauncherItem($"... 외 {array2.Length - 8}개", "", null, null, null, "\ue946"));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list3);
|
|
}
|
|
|
|
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
if (!(item.Data is (string, string[], string[]) tuple) || 1 == 0)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
(string, string[], string[]) tuple2 = tuple;
|
|
string item2 = tuple2.Item1;
|
|
string[] item3 = tuple2.Item2;
|
|
string[] item4 = tuple2.Item3;
|
|
int num = 0;
|
|
int num2 = 0;
|
|
for (int i = 0; i < item3.Length && i < item4.Length; i++)
|
|
{
|
|
try
|
|
{
|
|
string text = Path.Combine(item2, item4[i]);
|
|
if (File.Exists(text))
|
|
{
|
|
num2++;
|
|
continue;
|
|
}
|
|
File.Move(item3[i], text);
|
|
num++;
|
|
}
|
|
catch
|
|
{
|
|
num2++;
|
|
}
|
|
}
|
|
string message = ((num2 > 0) ? $"{num}개 이름변경 완료, {num2}개 실패 (이미 존재하거나 접근 불가)" : $"{num}개 파일 이름변경 완료");
|
|
NotificationService.Notify("AX Copilot", message);
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|