Created
June 30, 2017 00:38
-
-
Save Biendeo/8577831c857ae1a74b68c92500c1d43e to your computer and use it in GitHub Desktop.
Auto Directory Archiver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using IniParser; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Diagnostics; | |
| using System.Globalization; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Text; | |
| using System.Threading; | |
| using System.Threading.Tasks; | |
| using System.Timers; | |
| namespace Auto_Directory_Archiver { | |
| class Program { | |
| private const string configPath = "config.ini"; | |
| private static bool recursive; | |
| private static string watchFolderPath; | |
| private static string archiveFolderPath; | |
| private static string sevenZipPath; | |
| private static string sevenZipArchiveArguments; | |
| private static string sevenZipExtractArguments; | |
| private static int updateFrequency; | |
| private static bool outputLog = true; | |
| private static string logPath; | |
| private static DateTime lastUpdated; | |
| private const string fmt = "yyyy-MM-dd-HH-mm-ss"; | |
| private const int minimumUpdateFrequency = 30; | |
| static void Main(string[] args) { | |
| Log(TraceLevel.Info, "Program starting up"); | |
| LoadConfig(); | |
| if (updateFrequency < minimumUpdateFrequency) { | |
| updateFrequency = minimumUpdateFrequency; | |
| } | |
| System.Timers.Timer timer = new System.Timers.Timer(SecondsToNextHour() * 1000); | |
| timer.Elapsed += ((object src, ElapsedEventArgs e) => { | |
| timer.Enabled = false; | |
| RecursiveArchiveChangedFiles(watchFolderPath); | |
| lastUpdated = DateTime.Now; | |
| Log(TraceLevel.Info, $"Next update will check at {lastUpdated.AddSeconds(updateFrequency).ToString(fmt)}"); | |
| SaveConfig(); | |
| timer.Enabled = true; | |
| }); | |
| timer.Enabled = true; | |
| Log(TraceLevel.Info, $"Program all set up, next update at {lastUpdated.AddSeconds(updateFrequency).ToString(fmt)}"); | |
| while (true) { | |
| Thread.Sleep(int.MaxValue); | |
| } | |
| } | |
| private static int SecondsToNextHour() { | |
| if (lastUpdated.AddSeconds(updateFrequency) < DateTime.Now) { | |
| return minimumUpdateFrequency; // This buys time to archive everything. | |
| } else { | |
| return (int)(lastUpdated.AddSeconds(updateFrequency) - DateTime.Now).TotalSeconds; | |
| } | |
| } | |
| private static bool HasFolderBeenUpdated(string folderPath) { | |
| DateTime lastModified = Directory.GetLastWriteTime(watchFolderPath); | |
| if (lastModified >= lastUpdated) { | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| private static void RecursiveArchiveChangedFiles(string folderPath) { | |
| foreach (var file in Directory.EnumerateFiles(folderPath)) { | |
| // Console.WriteLine(Path.GetDirectoryName(GetArchiveFilePath(file))); | |
| // Console.WriteLine($"{file} matches {(new DirectoryInfo(Path.GetDirectoryName(GetArchiveFilePath(file))).GetFiles($"{Path.GetFileName(file)}*").Count())} times"); | |
| int numberOfArchives = 0; | |
| try { | |
| numberOfArchives = new DirectoryInfo(Path.GetDirectoryName(GetArchiveFilePath(file))).GetFiles($"{Path.GetFileName(file)}*").Count(); | |
| } catch { | |
| Console.WriteLine($"Exception thrown at {file}"); | |
| } | |
| if (File.GetLastWriteTime(file) >= lastUpdated ||numberOfArchives == 0) { | |
| SevenZipArchive(file, Path.GetDirectoryName(GetArchiveFilePath(file)), $"{Path.GetFileName(file)} {DateTime.Now.ToString(fmt)}.7z"); | |
| Log(TraceLevel.Info, $"Archived {file} to {Path.GetFileName(file)} {DateTime.Now.ToString(fmt)}.7z"); | |
| } | |
| } | |
| if (recursive) { | |
| foreach (var dir in Directory.EnumerateDirectories(folderPath)) { | |
| RecursiveArchiveChangedFiles(dir); | |
| } | |
| } | |
| } | |
| private static string GetArchiveFilePath(string watchFolderFilePath) { | |
| return Path.GetFullPath(archiveFolderPath) + GetCommonFilePath(watchFolderFilePath); | |
| } | |
| private static string GetCommonFilePath(string filePath) { | |
| return Path.GetFullPath(filePath).Remove(0, Path.GetFullPath(watchFolderPath).Length); | |
| } | |
| private static string GetArchiveEquivalentFilePath(string originalFilePath) { | |
| return Path.GetFullPath(archiveFolderPath) + originalFilePath.Remove(0, Path.GetFullPath(watchFolderPath).Length); | |
| } | |
| private static void SevenZipArchive(string itemPath, string archiveFolder, string archiveName) { | |
| var processStartInfo = new ProcessStartInfo(sevenZipPath, $"a -t7z \"{archiveFolder}/{archiveName}\" {sevenZipArchiveArguments} \"{itemPath}\"") { | |
| CreateNoWindow = true, | |
| UseShellExecute = false | |
| }; | |
| var proc = Process.Start(processStartInfo); | |
| proc.WaitForExit(); | |
| } | |
| private static void DefaultConfig() { | |
| watchFolderPath = "./"; | |
| archiveFolderPath = "./Archive/"; | |
| recursive = true; | |
| sevenZipPath = "C:/Program Files/7-Zip/7z.exe"; | |
| sevenZipArchiveArguments = ""; | |
| sevenZipExtractArguments = ""; | |
| outputLog = true; | |
| logPath = "log.txt"; | |
| lastUpdated = DateTime.Now.AddHours(-1); | |
| updateFrequency = 3600; | |
| } | |
| private static void LoadConfig() { | |
| DefaultConfig(); | |
| if (File.Exists(configPath)) { | |
| var iniParser = new FileIniDataParser(); | |
| var data = iniParser.ReadFile(configPath); | |
| recursive = data["settings"]["recursive"] == "true" ? true : false; | |
| int.TryParse(data["settings"]["updateFrequency"], out updateFrequency); | |
| watchFolderPath = data["settings"]["watchFolderPath"]; | |
| archiveFolderPath = data["settings"]["archiveFolderPath"]; | |
| sevenZipPath = data["settings"]["sevenZipPath"]; | |
| sevenZipArchiveArguments = data["settings"]["sevenZipArchiveArguments"]; | |
| sevenZipExtractArguments = data["settings"]["sevenZipExtractArguments"]; | |
| outputLog = data["debug"]["outputLog"] == "true" ? true : false; | |
| logPath = data["debug"]["logPath"]; | |
| try { | |
| lastUpdated = DateTime.ParseExact(data["sensitive"]["lastUpdate"], fmt, CultureInfo.InvariantCulture); | |
| } catch { | |
| lastUpdated = DateTime.Now.AddHours(-1); | |
| } | |
| Log(TraceLevel.Info, "Loaded config"); | |
| } else { | |
| Log(TraceLevel.Info, "No config found, default config assumed"); | |
| SaveConfig(); | |
| } | |
| } | |
| private static void SaveConfig() { | |
| var iniParser = new FileIniDataParser(); | |
| var data = new IniParser.Model.IniData(); | |
| data["settings"]["recursive"] = recursive ? "true" : "false"; | |
| data["settings"]["updateFrequency"] = updateFrequency.ToString(); | |
| data["settings"]["watchFolderPath"] = watchFolderPath; | |
| data["settings"]["archiveFolderPath"] = archiveFolderPath; | |
| data["settings"]["sevenZipPath"] = sevenZipPath; | |
| data["settings"]["sevenZipArchiveArguments"] = sevenZipArchiveArguments; | |
| data["settings"]["sevenZipExtractArguments"] = sevenZipExtractArguments; | |
| data["debug"]["outputLog"] = outputLog ? "true" : "false"; | |
| data["debug"]["logPath"] = logPath; | |
| data["sensitive"]["lastUpdate"] = lastUpdated.ToString(fmt); | |
| iniParser.WriteFile(configPath, data); | |
| Log(TraceLevel.Info, "Saved config"); | |
| } | |
| private static void Log(TraceLevel level, string message) { | |
| string outputString = $"{DateTime.Now.ToString("dd/MM/yy hh:mm:ss")} [{level}] - {message}"; | |
| Console.WriteLine(outputString); | |
| if (!outputLog) { | |
| return; | |
| } | |
| try { | |
| using (var log = File.AppendText(logPath)) { | |
| log.WriteLine(outputString); | |
| } | |
| } catch (Exception e) { | |
| if (e is UnauthorizedAccessException) { | |
| Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yy hh:mm:ss")} [ERROR] - Log file encountered an UnauthorizedAccessException"); | |
| } else if (e is PathTooLongException) { | |
| Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yy hh:mm:ss")} [ERROR] - Log file encountered a PathTooLongException"); | |
| } else if (e is DirectoryNotFoundException) { | |
| Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yy hh:mm:ss")} [ERROR] - Log file encountered a DirectoryNotFoundException"); | |
| } else if (e is NotSupportedException) { | |
| Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yy hh:mm:ss")} [ERROR] - Log file encountered a NotSupportedException"); | |
| } else { | |
| Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yy hh:mm:ss")} [ERROR] - Log file encountered an error"); | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment