調整 video 開啓先比對

新增 env 多個遠端路徑
新増 env 能比對檔案路徑
20250704
This commit is contained in:
jasonchenwork 2025-07-04 14:45:39 +08:00
parent d041ff1f80
commit 8f456c347d
6 changed files with 175 additions and 193 deletions

80
DataCheck.cs Normal file
View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace DataCheck
{
public class DataChecker
{
public DataChecker()
{
// 加入你要同步的資料夾
SyncFolder(Utils.Env.GetPath("video", ""), @"D:\video", "video", new[] { ".mpg" });
}
private void SyncFolder(string serverPath, string localPath, string label, string[] extensions)
{
if (!Directory.Exists(localPath))
{
Directory.CreateDirectory(localPath);
}
if (!Directory.Exists(serverPath))
{
Console.WriteLine($"找不到伺服器資料夾:{serverPath}");
return;
}
var serverFiles = Directory.GetFiles(serverPath)
.Where(f => extensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase))
.Select(f => new FileInfo(f))
.ToDictionary(f => f.Name, f => f);
var localFiles = Directory.GetFiles(localPath)
.Where(f => extensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase))
.Select(f => new FileInfo(f))
.ToDictionary(f => f.Name, f => f);
// 1. 複製或更新檔案
foreach (var serverFile in serverFiles)
{
bool needsCopy = !localFiles.ContainsKey(serverFile.Key) ||
serverFile.Value.LastWriteTime > localFiles[serverFile.Key].LastWriteTime;
if (needsCopy)
{
try
{
string dest = Path.Combine(localPath, serverFile.Key);
File.Copy(serverFile.Value.FullName, dest, true);
Console.WriteLine($"更新{label}: {serverFile.Key}");
}
catch (Exception ex)
{
Console.WriteLine($"複製{label}失敗 {serverFile.Key}: {ex.Message}");
}
}
}
// 2. 刪除多餘的本地檔案
foreach (var localFile in localFiles)
{
if (!serverFiles.ContainsKey(localFile.Key))
{
try
{
File.Delete(localFile.Value.FullName);
Console.WriteLine($"刪除多餘{label}: {localFile.Key}");
}
catch (Exception ex)
{
Console.WriteLine($"刪除{label}失敗 {localFile.Key}: {ex.Message}");
}
}
}
}
}
}

79
Env.cs
View File

@ -6,20 +6,27 @@ namespace Utils
{
public static class Env
{
public static readonly string KtvPath = @"\\pc101\KTVData";
private static readonly Dictionary<string, string> _values;
private static string KtvPath = "";
private static readonly List<string> KtvPaths = new()
{
@"\\sshost\KTVSuperstar",
@"\\pc101\KTVSuperstar"
};
private static readonly Dictionary<string, string> _values = new(StringComparer.OrdinalIgnoreCase);
static Env()
{
var path = Path.Combine(KtvPath, "config.ini");
_values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (!File.Exists(path))
foreach (var path in KtvPaths)
{
Console.WriteLine($"❌ 找不到環境檔案:{path}");
return;
}
var configPath = Path.Combine(path, "config.ini");
foreach (var line in File.ReadAllLines(path))
if (File.Exists(configPath))
{
KtvPath = path;
Console.WriteLine("✅ 找到設定檔:" + configPath);
foreach (var line in File.ReadAllLines(configPath))
{
var trimmed = line.Trim();
if (string.IsNullOrWhiteSpace(trimmed) || trimmed.StartsWith("#")) continue;
@ -31,31 +38,55 @@ namespace Utils
var value = trimmed[(index + 1)..].Trim();
if (value.StartsWith("\"") && value.EndsWith("\""))
value = value[1..^1]; // 去除引號
value = value[1..^1];
_values[key] = value;
}
return; // 找到一份 config 就跳出
}
}
public static string Get(string key, string fallback = "")
Console.WriteLine("❌ 所有指定目錄都找不到 config.ini");
}
public static string Get(string key, string fallback = "") =>
_values.TryGetValue(key, out var value) ? value : fallback;
public static bool GetBool(string key, bool fallback = false) =>
_values.TryGetValue(key, out var value) && bool.TryParse(value, out var result)
? result : fallback;
public static int GetInt(string key, int fallback = 0) =>
_values.TryGetValue(key, out var value) && int.TryParse(value, out var result)
? result : fallback;
public static string GetPath(string key, string fallback = "")
{
return _values.TryGetValue(key, out var value) ? value : fallback;
}
public static bool GetBool(string key, bool fallback = false)
if (string.IsNullOrWhiteSpace(KtvPath))
{
return _values.TryGetValue(key, out var value) && bool.TryParse(value, out var result)
? result
: fallback;
Console.WriteLine("⚠️ KtvPath 尚未設定,將使用 fallback。");
return fallback;
}
public static int GetInt(string key, int fallback = 0)
var path = Path.Combine(KtvPath, key);
if (Directory.Exists(path))
{
return _values.TryGetValue(key, out var value) && int.TryParse(value, out var result)
? result
: fallback;
return path;
}
else
{
Console.WriteLine($"⚠️ 找不到目錄:{path},使用 fallback{fallback}");
return fallback;
}
}
public static string GetDBConnection()
{
return $"Server={Get("DBServer", "localhost")};Port={Get("DBPort", "3306")};Database={Get("Database", "test")};User={Get("DBUser", "root")};Password={Get("DBPassword", "")};";
}
// 可加上 GetFloat、GetDouble、GetTimeSpan ... 視需要
// 如需支援更多型別可自行擴充GetFloat, GetDouble, GetDateTime 等
}
}

View File

@ -23,13 +23,9 @@ namespace DualScreenDemo
private List<Image> LoadImagesFromFolder(string folderName)
{
List<Image> images = new();
string folderPath = Path.Combine(Utils.Env.KtvPath, folderName);
string folderPath = Utils.Env.GetPath(folderName, "");
if (!Directory.Exists(folderPath))
{
Console.WriteLine($" 找不到遠端資料夾:{folderPath}");
return images;
}
if (folderPath.Equals("")) return images;
string[] imageFiles = Directory.GetFiles(folderPath, "*.jpg");

View File

@ -9,7 +9,7 @@ namespace DualScreenDemo{
private static string GetConnectionString()
{
return $"Server={Utils.Env.Get("DBServer", "localhost")};Port={Utils.Env.Get("DBPort", "3306")};Database={Utils.Env.Get("Database", "test")};User={Utils.Env.Get("DBUser", "root")};Password={Utils.Env.Get("DBPassword", "")};";
return Utils.Env.GetDBConnection();
}
public bool isLoggedIn = false;

View File

@ -1549,92 +1549,7 @@ namespace DualScreenDemo
publicSongList = new List<SongData>();
playedSongsHistory = new List<SongData>();
playStates = new List<PlayState>();
try
{
// 1. 檢查是否能連接到 SVR01
string serverVideoPath = Path.Combine(Utils.Env.KtvPath, "video");
string localVideoPath = @"D:\video";
if (!Directory.Exists(serverVideoPath))
{
Console.WriteLine("未連接到 SVR使用本地影片");
LoadLocalVideoFiles();
return;
}
// 2. 確認本地文件夾是否存在(不存在則創立)
if (!Directory.Exists(localVideoPath))
{
Directory.CreateDirectory(localVideoPath);
}
// 獲取服務器和本地的所有文件
var serverFiles = Directory.GetFiles(serverVideoPath, "*.mpg")
.Select(f => new FileInfo(f))
.ToDictionary(f => f.Name, f => f);
var localFiles = Directory.GetFiles(localVideoPath, "*.mpg")
.Select(f => new FileInfo(f))
.ToDictionary(f => f.Name, f => f);
// 3-1. 檢查並更新文件
foreach (var serverFile in serverFiles)
{
bool needsCopy = false;
string localFilePath = Path.Combine(localVideoPath, serverFile.Key);
if (!localFiles.ContainsKey(serverFile.Key))
{
needsCopy = true;
}
else
{
var localFile = localFiles[serverFile.Key];
if (serverFile.Value.LastWriteTime > localFile.LastWriteTime)
{
needsCopy = true;
}
}
if (needsCopy)
{
try
{
File.Copy(serverFile.Value.FullName, localFilePath, true);
Console.WriteLine($"更新影片: {serverFile.Key}");
}
catch (Exception ex)
{
Console.WriteLine($"複製影片失敗 {serverFile.Key}: {ex.Message}");
}
}
}
// 3-2. 清除本地有但伺服器已經沒有的檔案
foreach (var localFile in localFiles)
{
if (!serverFiles.ContainsKey(localFile.Key))
{
try
{
File.Delete(localFile.Value.FullName);
Console.WriteLine($"刪除本地多餘影片: {localFile.Key}");
}
catch (Exception ex)
{
Console.WriteLine($"刪除影片失敗 {localFile.Key}: {ex.Message}");
}
}
}
// 4. 載入更新後的本地文件
LoadLocalVideoFiles();
}
catch (Exception ex)
{
Console.WriteLine($"更新影片失敗:{ex.Message}");
LoadLocalVideoFiles(); // 出錯時使用本地文件
}
}
// 將原本的本地文件載入邏輯抽取為單獨的方法
@ -1642,75 +1557,34 @@ namespace DualScreenDemo
{
try
{
string videoDirectory = @"D:\video\";
string[] videoFiles = Directory.GetFiles(videoDirectory, "*.mpg");
string[] videoFiles = Directory.GetFiles(@"D:\video\", "*.mpg");
string pattern = @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-";
foreach (var songPath in videoFiles)
{
string fileName = Path.GetFileNameWithoutExtension(songPath);
Match match = Regex.Match(fileName, pattern);
if (match.Success)
{
string songNumber = match.Groups["songNumber"].Value;
string songName = match.Groups["songName"].Value;
string songNumber = "";
string songName = "";
if (match.Success){
songNumber = match.Groups["songNumber"].Value;
songName = match.Groups["songName"].Value;
}
SongData song = new SongData(
songNumber, // songNumber
//"", // songNumberB
songName, // song
//0, // songLength
"", // artistA
"", // artistB
"", // filename
//"", // category
//DateTime.Now, // dateAdded
songPath, // songFilePathHost1
"", // songFilePathHost2
"", // songFilePathHost3
"", // songFilePathHost4
"", // songFilePathHost5
//"", // songFilePathHost6
//"", // songFilePathHost7
//"", // songFilePathHost8
//"", // songFilePathHost9
//"", // songFilePathHost10
//"", // humanVoice
//"", // songType
1 // priority
);
publicSongList.Add(song);
}
else
{
SongData song = new SongData(
"", // songNumber
//"", // songNumberB
"", // song
//0, // songLength
"", // artistA
"", // artistB
"", // filename
//"", // category
//DateTime.Now, // dateAdded
songPath, // songFilePathHost1
"", // songFilePathHost2
"", // songFilePathHost3
"", // songFilePathHost4
"", // songFilePathHost5
//"", // songFilePathHost6
//"", // songFilePathHost7
//"", // songFilePathHost8
//"", // songFilePathHost9
//"", // songFilePathHost10
//"", // humanVoice
//"", // songType
1 // priority
);
publicSongList.Add(song);
}
}
}
catch (Exception ex)
{

View File

@ -36,6 +36,7 @@ namespace DualScreenDemo
//Console.WriteLine("正在與中控取得聯繫...");
var sender = new heartbeatSender();
var cherker =new DataCheck.DataChecker();
try
{