Skip to content

Commit 534b4ca

Browse files
committed
Rename action.
1 parent 66f66a8 commit 534b4ca

20 files changed

Lines changed: 803 additions & 443 deletions

SubRenamer/Action.cs

Lines changed: 89 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
using System.Drawing;
99
using System.IO;
1010
using System.Linq;
11+
using System.Reflection;
1112
using System.Text;
1213
using System.Text.RegularExpressions;
14+
using System.Threading;
1315
using System.Threading.Tasks;
1416
using System.Windows.Forms;
1517
using static SubRenamer.Global;
@@ -21,9 +23,6 @@ public partial class MainForm
2123
private List<VsItem> VsList = new List<VsItem> { };
2224
public MatchMode CurtMatchMode = MatchMode.Auto;
2325

24-
public static readonly List<string> VideoExts = new List<string> { ".mkv", ".mp4", "flv", ".avi", ".mov", ".rmvb", ".wmv", ".mpg", ".avs" };
25-
public static readonly List<string> SubExts = new List<string> { ".srt", ".ass", ".ssa", ".sub", ".idx" };
26-
2726
// 匹配模式
2827
public enum MatchMode
2928
{
@@ -210,21 +209,30 @@ private string GetMatchKeyByFileName(string fileName, AppFileType fileType, List
210209
else if (CurtMatchMode == MatchMode.Regex)
211210
{
212211
if (fileType == AppFileType.Video && M_Regx_V != null)
213-
matchKey = M_Regx_V.Match(fileName).Groups[1].Value;
212+
matchKey = GetMatchKeyByRegex(fileName, M_Regx_V);
214213
else if (fileType == AppFileType.Sub && M_Regx_S != null)
215-
matchKey = M_Regx_S.Match(fileName).Groups[1].Value;
214+
matchKey = GetMatchKeyByRegex(fileName, M_Regx_S);
216215
}
217216

218217
if (string.IsNullOrWhiteSpace(matchKey)) matchKey = null;
219218
return matchKey;
220219
}
221220

221+
public static string GetMatchKeyByRegex(string fileName, Regex regex)
222+
{
223+
if (regex == null || string.IsNullOrWhiteSpace(fileName)) return null;
224+
if (regex.Match(fileName).Groups.Count < 2) return null;
225+
return regex.Match(fileName).Groups[1].Value;
226+
}
227+
222228
public static string GetMatchKeyByBeginEndStr(string fileName, string start, string end)
223229
{
224-
if (string.IsNullOrWhiteSpace(fileName)
225-
|| string.IsNullOrWhiteSpace(start)
226-
|| string.IsNullOrWhiteSpace(end))
230+
if (string.IsNullOrWhiteSpace(fileName))
227231
return null;
232+
if (string.IsNullOrWhiteSpace(start) && string.IsNullOrWhiteSpace(end))
233+
return null; // 前后字符都没有,直接返回 null
234+
if (start == null) start = "";
235+
if (end == null) end = "";
228236

229237
fileName = fileName.Trim();
230238

@@ -249,6 +257,7 @@ private string GetEpisByFileName(string fileName, int beginPos, string endStr)
249257
{
250258
if (string.IsNullOrWhiteSpace(fileName)) return null;
251259
if (beginPos <= -1) return null;
260+
if (beginPos >= fileName.Length) return null;
252261
var str = fileName.Substring(beginPos);
253262

254263
var result = "";
@@ -343,14 +352,23 @@ private string GetEndStrByList(List<FileInfo> list, int beginPos)
343352

344353
protected void StartRename()
345354
{
346-
if (GetSubRenameDict().Count() <= 0) return;
347-
Task.Factory.StartNew(() => _StartRename());
355+
var subRenameDict = GetSubRenameDict();
356+
if (subRenameDict.Count() <= 0) return;
357+
SwitchPreview(true);
358+
Task.Factory.StartNew(() => _StartRename(subRenameDict));
348359
}
349360

350361
/// 执行改名操作
351-
private void _StartRename()
362+
private void _StartRename(Dictionary<string, string> subRenameDict)
352363
{
353-
var subRenameDict = GetSubRenameDict();
364+
Program.Log($"[=============== 开始执行改名操作 ===============]");
365+
366+
string btnRawText = "";
367+
Invoke((MethodInvoker)delegate {
368+
StartBtn.Enabled = false;
369+
btnRawText = StartBtn.Text;
370+
StartBtn.Text = "改名中...";
371+
});
354372
int renTotal = subRenameDict.Count();
355373
int errTotal = 0;
356374
void SetCurrentProgress(KeyValuePair<string, string> subRename, int index)
@@ -364,7 +382,7 @@ void SetCurrentProgress(KeyValuePair<string, string> subRename, int index)
364382
double percentage = (index / (double)renTotal) * 100;
365383
//td.Text = $"执行一键改名操作中,请稍后... ({index}/{renTotal})" + Environment.NewLine;
366384
//td.Text += $"\"{Path.GetFileName(subRename.Key)}\"{Environment.NewLine}=> \"{Path.GetFileName(subRename.Value)}\"";
367-
// td.ProgressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
385+
//td.ProgressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
368386
}
369387

370388
int i = 0;
@@ -373,28 +391,36 @@ void SetCurrentProgress(KeyValuePair<string, string> subRename, int index)
373391
try
374392
{
375393
_RenameOnce(subRename);
376-
// td.DetailsExpandedText += $"[成功] [\"{subRename.Key}\"=>\"{subRename.Value}\"]{Environment.NewLine}";
394+
Program.Log("[成功]", $"[\"{subRename.Key}\"=>\"{subRename.Value}\"]");
395+
Invoke((MethodInvoker)delegate { RefreshFileListUi(); });
377396
}
378397
catch (Exception e)
379398
{
380-
// td.DetailsExpandedText += $"[失败] [\"{subRename.Key}\"=>\"{subRename.Value}\"] {e.Message}{Environment.NewLine}";
399+
Program.Log("[错误]", $"[\"{subRename.Key}\"=>\"{subRename.Value}\"]{Environment.NewLine} ==> {e.Message}");
381400
errTotal++;
382401
}
383402
finally
384403
{
385404
i++;
386-
SetCurrentProgress(subRename, i);
405+
// SetCurrentProgress(subRename, i);
387406
}
388407
}
389408

390-
RefreshFileListUi();
409+
if (errTotal > 0)
410+
Process.Start(LOG_FILENAME);
411+
412+
Invoke((MethodInvoker)delegate {
413+
StartBtn.Text = btnRawText;
414+
StartBtn.Enabled = true;
415+
});
391416
}
392417

393418
private void _RenameOnce(KeyValuePair<string, string> subRename)
394419
{
395420
var vsFile = VsList.Find(o => o.Sub == subRename.Key);
396421
if (vsFile == null) throw new Exception("找不到修改项");
397-
if (vsFile.Status != VsStatus.Ready) throw new Exception("当然状态无法修改");
422+
if (vsFile.Status == VsStatus.Done) return; // 无需再改名了
423+
if (vsFile.Status != VsStatus.Ready && vsFile.Status != VsStatus.Fatal) throw new Exception("当然状态无法修改");
398424
if (vsFile.Video == null || vsFile.Sub == null) throw new Exception("字幕/视频文件不完整");
399425

400426
var before = new FileInfo(subRename.Key);
@@ -404,7 +430,7 @@ private void _RenameOnce(KeyValuePair<string, string> subRename)
404430
if (before.FullName.Equals(after.FullName))
405431
{
406432
vsFile.Status = VsStatus.Done;
407-
throw new Exception("字幕文件名无需修改");
433+
throw new Exception($"文件名名未修改,因为改名后的文件已存在,无需改名");
408434
}
409435

410436
// 若原文件不存在
@@ -414,10 +440,37 @@ private void _RenameOnce(KeyValuePair<string, string> subRename)
414440
throw new Exception($"字幕源文件不存在");
415441
}
416442

443+
// 执行备份
444+
if (AppSettings.RawSubtitleBuckup)
445+
{
446+
try
447+
{
448+
// 前字幕文件 和 后字幕文件 若是在同一个目录下
449+
if (before.DirectoryName == after.DirectoryName && File.Exists(before.FullName))
450+
BackupFile(before.FullName);
451+
452+
if (File.Exists(after.FullName))
453+
BackupFile(after.FullName);
454+
}
455+
catch (Exception e)
456+
{
457+
throw new Exception($"改名前备份发生错误 {e.GetType().FullName} {e.ToString()}");
458+
}
459+
}
460+
417461
// 执行更名
418462
try
419463
{
420-
File.Move(before.FullName, after.FullName);
464+
if (before.DirectoryName == after.DirectoryName)
465+
{
466+
if (File.Exists(after.FullName)) File.Delete(after.FullName); // 若后文件存在,则先删除 (上面有备份的)
467+
File.Move(before.FullName, after.FullName); // 前后字幕相同目录,执行改名
468+
}
469+
else
470+
{
471+
File.Copy(before.FullName, after.FullName, true); // 前后字幕不同文件,执行复制
472+
}
473+
421474
vsFile.Status = VsStatus.Done;
422475
}
423476
catch (Exception e)
@@ -428,6 +481,21 @@ private void _RenameOnce(KeyValuePair<string, string> subRename)
428481
}
429482
}
430483

484+
private void BackupFile(string filename)
485+
{
486+
if (!File.Exists(filename)) return;
487+
var bkFolder = Path.Combine(Path.GetDirectoryName(filename), "SubBackup/");
488+
if (!Directory.Exists(bkFolder)) Directory.CreateDirectory(bkFolder);
489+
490+
string bkDistFile = Path.Combine(bkFolder, Path.GetFileName(filename));
491+
if (File.Exists(bkDistFile)) // 解决文件重名问题
492+
bkDistFile = Path.Combine(
493+
bkFolder, Path.GetFileNameWithoutExtension(filename) + $".{Program.GetNowDatetime()}{Path.GetExtension(filename)}"
494+
);
495+
496+
File.Copy(filename, bkDistFile, true);
497+
}
498+
431499
// 获取修改的字幕文件名 (原始完整路径->修改后完整路径)
432500
private Dictionary<string, string> GetSubRenameDict()
433501
{
@@ -440,7 +508,7 @@ private Dictionary<string, string> GetSubRenameDict()
440508
if (item.Video == null || item.Sub == null) continue;
441509
string videoName = Path.GetFileNameWithoutExtension(item.VideoFileInfo.Name); // 去掉后缀的视频文件名
442510
string subAfterFilename = videoName + item.SubFileInfo.Extension; // 修改的字幕文件名
443-
dict[item.SubFileInfo.FullName] = Path.Combine(item.SubFileInfo.DirectoryName, subAfterFilename);
511+
dict[item.SubFileInfo.FullName] = Path.Combine(item.VideoFileInfo.DirectoryName, subAfterFilename);
444512
}
445513

446514
return dict;

SubRenamer/AppSettings.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,48 @@
1-
using SubRenamer.Utils;
1+
using SubRenamer.Lib;
22
using System;
33
using System.Collections.Generic;
44
using System.Linq;
5+
using System.Runtime.CompilerServices;
56
using System.Text;
67
using System.Threading.Tasks;
78

89
namespace SubRenamer
910
{
1011
public class AppSettings
1112
{
12-
public static IniFile IniFile = new IniFile();
1313
public static bool RawSubtitleBuckup
1414
{
15-
get { return IniFile.Read("RawSubtitleBuckup", "1").Equals("1"); }
16-
set { RawSubtitleBuckup = value; IniFile.Write("RawSubtitleBuckup", value ? "1" : "0"); }
15+
get { return GetBoolVal(defaultVal: true); }
16+
set { WriteBoolVal(value); }
1717
}
1818

19-
public static bool OpenFolderFinished
19+
public static bool ListItemRemovePrompt
2020
{
21-
get { return IniFile.Read("OpenFolderFinished", "0").Equals("1"); }
22-
set { OpenFolderFinished = value; IniFile.Write("OpenFolderFinished", value ? "1" : "0"); }
21+
get { return GetBoolVal(defaultVal: true); }
22+
set { WriteBoolVal(value); }
2323
}
2424

25-
public static bool ListItemRemovePrompt
25+
public static bool ListShowFileFullName
2626
{
27-
get { return IniFile.Read("ListItemRemovePrompt", "1").Equals("1"); }
28-
set { ListItemRemovePrompt = value; IniFile.Write("ListItemRemovePrompt", value ? "1" : "0"); }
27+
get { return GetBoolVal(defaultVal: false); }
28+
set { WriteBoolVal(value); }
2929
}
3030

31-
public static bool ListShowFileFullName
31+
#region Utils
32+
public static IniFile IniFile = new IniFile();
33+
34+
private static bool GetBoolVal(bool defaultVal = false, [CallerMemberName]string key = null)
35+
{
36+
if (string.IsNullOrWhiteSpace(key)) return defaultVal;
37+
string defaultValStr = defaultVal ? "1" : "0";
38+
return IniFile.Read(key, defaultValStr).Equals("1");
39+
}
40+
41+
private static void WriteBoolVal(bool val, [CallerMemberName]string key = null)
3242
{
33-
get { return IniFile.Read("ListShowFileFullName", "0").Equals("1"); }
34-
set { ListShowFileFullName = value; IniFile.Write("ListShowFileFullName", value ? "1" : "0"); }
43+
if (string.IsNullOrWhiteSpace(key)) return;
44+
IniFile.Write(key, val ? "1" : "0");
3545
}
46+
#endregion
3647
}
3748
}

SubRenamer/Global.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Linq;
45
using System.Text;
56
using System.Threading.Tasks;
7+
using System.Windows.Forms;
68

79
namespace SubRenamer
810
{
911
public class Global
1012
{
1113
#region 常量
14+
public static readonly string LOG_FILENAME = Path.Combine(Application.StartupPath, $"{Program.GetAppName()}.log");
15+
public static readonly List<string> VideoExts = new List<string> { ".mkv", ".mp4", "flv", ".avi", ".mov", ".rmvb", ".wmv", ".mpg", ".avs" };
16+
public static readonly List<string> SubExts = new List<string> { ".srt", ".ass", ".ssa", ".sub", ".idx" };
1217
#endregion
1318

1419
/// <summary>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using System.Text;
88
using System.Threading.Tasks;
99

10-
namespace SubRenamer.Utils
10+
namespace SubRenamer.Lib
1111
{
1212
public class IniFile
1313
{

SubRenamer/Lib/Ui.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows.Forms;
7+
8+
namespace SubRenamer.Lib
9+
{
10+
public static class Ui
11+
{
12+
13+
}
14+
}
Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
using System;
1+
using Microsoft.WindowsAPICodePack.Dialogs;
2+
using System;
23
using System.Collections.Generic;
4+
using System.IO;
35
using System.Linq;
46
using System.Text;
57
using System.Threading.Tasks;
68
using System.Windows.Forms;
9+
using static SubRenamer.Global;
710

8-
namespace SubRenamer.Utils
11+
namespace SubRenamer.Lib
912
{
10-
public static class Ui
13+
class Utils
1114
{
1215
/// <summary>
1316
/// 输入对话框
@@ -37,5 +40,26 @@ public static string InputDialog(string text, string caption)
3740

3841
return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : "";
3942
}
43+
44+
public static void OpenFile(AppFileType FileType, Action<string, AppFileType> opened)
45+
{
46+
using (var fbd = new CommonOpenFileDialog())
47+
{
48+
if (FileType == AppFileType.Video)
49+
fbd.Filters.Add(new CommonFileDialogFilter("视频文件", string.Join(";", VideoExts.ToList())));
50+
else if (FileType == AppFileType.Sub)
51+
fbd.Filters.Add(new CommonFileDialogFilter("字幕文件", string.Join(";", SubExts.ToList())));
52+
53+
fbd.Filters.Add(new CommonFileDialogFilter("视频或字幕文件", string.Join(";", VideoExts.Concat(SubExts).ToList())));
54+
fbd.Filters.Add(new CommonFileDialogFilter("任何类型", "*.*"));
55+
var result = fbd.ShowDialog();
56+
57+
if (result == CommonFileDialogResult.Ok && !string.IsNullOrWhiteSpace(fbd.FileName))
58+
{
59+
var fileName = Path.GetFileName(fbd.FileName.Trim());
60+
opened(fileName, FileType);
61+
}
62+
}
63+
}
4064
}
4165
}

0 commit comments

Comments
 (0)