using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; namespace gehGassi.Web.Services { /// /// Schnittstellenbeschreibung für einen Service der für alle Dateien in einem Orndern einen gemeinsamen Hash errechnet. /// public interface IScriptVersionCalculator { /// /// Gibt eine Versionsnummer (hash) für alle Dateien in einem Ordner zurück /// /// Absoluter Pfad des Ordners /// Datei-Pattern /// Errechnete Versionsnummer oder string.empty string GetVersion(string absolutePath, string filePattern); /// /// Entfernt eine Kombination aus dem Versions-Cache, wenn vorhanden /// /// Absoluter Pfad des Ordners /// Datei-Pattern void Clear(string absolutePath, string filePattern); /// /// Löscht alle Kombinationen aus dem Versions-Cache /// void ClearAll(); } /// /// Service der für alle Dateien in einem Orndern einen gemeinsamen Hash errechnet. /// public class ScriptVersionCalculator : IScriptVersionCalculator { private Dictionary _versions; /// /// Erstellt eine Instanz /// public ScriptVersionCalculator() { _versions = new Dictionary(); } /// /// Gibt eine Versionsnummer (hash) für alle Dateien in einem Ordner zurück /// /// Absoluter Pfad des Ordners /// Datei-Pattern /// Errechnete Versionsnummer oder string.empty public string GetVersion(string absolutePath, string filePattern) { var result = string.Empty; if (_versions.ContainsKey($"{absolutePath}/{filePattern}")) return _versions[$"{absolutePath}/{filePattern}"]; if (Directory.Exists(absolutePath)) { using (var md5 = MD5.Create()) { byte[] totalBytes = { }; foreach (var file in Directory.EnumerateFiles(absolutePath, filePattern, SearchOption.AllDirectories)) { using (var stream = File.OpenRead(file)) { var hash = md5.ComputeHash(stream); totalBytes = totalBytes.Concat(hash).ToArray(); } } if (totalBytes.Length > 0) { var finalHash = md5.ComputeHash(totalBytes); result = Convert.ToBase64String(finalHash); _versions.Add($"{absolutePath}/{filePattern}", result); } } } return result; } /// /// Entfernt eine Kombination aus dem Versions-Cache, wenn vorhanden /// /// Absoluter Pfad des Ordners /// Datei-Pattern public void Clear(string absolutePath, string filePattern) { if (_versions.ContainsKey($"{absolutePath}/{filePattern}")) _versions.Remove($"{absolutePath}/{filePattern}"); } /// /// Löscht alle Kombinationen aus dem Versions-Cache /// public void ClearAll() { _versions.Clear(); } } }