191203PX Worked on import/export and backupping. Starts to work but sometimes locks up without CPU load during backup generation.
This commit is contained in:
parent
20c32ab7a3
commit
4f9aeb743f
27
Program.cs
27
Program.cs
|
@ -32,7 +32,7 @@ namespace dezentrale
|
|||
{
|
||||
public class Program
|
||||
{
|
||||
public static uint VersionNumber { get; private set; } = 0x19120200;
|
||||
public static uint VersionNumber { get; private set; } = 0x19120300;
|
||||
public static string VersionString { get; private set; } = $"{VersionNumber:x}";
|
||||
|
||||
public static string AppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
|
@ -181,14 +181,28 @@ namespace dezentrale
|
|||
Cronjob.Run();
|
||||
break;
|
||||
case eMode.Export:
|
||||
if (!config.ImportExport.Export(config.DbDirectory, DmDirectory)) return 1;
|
||||
if (!config.ImportExport.VerifyExport(config.DbDirectory, DmDirectory)) return 1;
|
||||
break;
|
||||
{
|
||||
ExportProcess export = new ExportProcess()
|
||||
{
|
||||
ImportExportSettings = Program.config.ImportExport,
|
||||
MemberDir = Program.config.DbDirectory,
|
||||
OutputDir = Program.DmDirectory,
|
||||
};
|
||||
ConsoleLogger logger = new ConsoleLogger();
|
||||
System.Threading.Thread t = logger.StartRunProcess(export);
|
||||
if (t != null) t.Join();
|
||||
else return 1;
|
||||
//if (!config.ImportExport.Export(config.DbDirectory, DmDirectory)) return 1;
|
||||
//if (!config.ImportExport.VerifyExport(config.DbDirectory, DmDirectory)) return 1;
|
||||
|
||||
if(logger.DialogResult != DialogResult.OK) return 1;
|
||||
} break;
|
||||
|
||||
case eMode.Import:
|
||||
{
|
||||
ImportProcess import = new ImportProcess()
|
||||
{
|
||||
MemberImportSettings = Program.config.ImportExport,
|
||||
ImportExportSettings = Program.config.ImportExport,
|
||||
MemberDir = Program.config.DbDirectory,
|
||||
InputDir = Program.DmDirectory,
|
||||
};
|
||||
|
@ -201,7 +215,8 @@ namespace dezentrale
|
|||
//if (!config.ImportExport.Import(config.DbDirectory, DmDirectory))
|
||||
//return 1;
|
||||
if(logger.DialogResult != DialogResult.OK) return 1;
|
||||
} break;
|
||||
} break;
|
||||
|
||||
case eMode.BankImport:
|
||||
if (string.IsNullOrEmpty(csvInput))
|
||||
{
|
||||
|
|
|
@ -6,54 +6,76 @@ using dezentrale.model;
|
|||
|
||||
namespace dezentrale.core
|
||||
{
|
||||
/** \brief Export functionality for the database contents
|
||||
*/
|
||||
public class ExportProcess : ImportExportBase
|
||||
{
|
||||
public ExportProcess()
|
||||
{
|
||||
Caption = "Database export";
|
||||
Steps = 4;
|
||||
Steps = 6;
|
||||
}
|
||||
|
||||
protected override bool Run()
|
||||
{
|
||||
string tmpFile = Path.Combine(OutputDir, MemberImportSettings.ZipFile);
|
||||
Console.WriteLine($"Export: Packing {tmpFile}");
|
||||
LogTarget.StepStarted(0, "Preparing export");
|
||||
if (ImportExportSettings == null)
|
||||
{
|
||||
LogTarget.LogLine("MemberImportExport data class not set.", LogEvent.ELogLevel.Error, "ExportProcess");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(MemberDir))
|
||||
if (MemberDir == null)
|
||||
{
|
||||
Console.WriteLine($"Cannot find directory '{MemberDir}'");
|
||||
LogTarget.LogLine("Member directory not set.", LogEvent.ELogLevel.Error, "ExportProcess");
|
||||
return false;
|
||||
} else if (!Directory.Exists(MemberDir))
|
||||
{
|
||||
LogTarget.LogLine($"Cannot find directory '{MemberDir}'", LogEvent.ELogLevel.Error, "ExportProcess");
|
||||
return false;
|
||||
}
|
||||
if (!Directory.Exists(OutputDir))
|
||||
|
||||
if (OutputDir == null)
|
||||
{
|
||||
Console.WriteLine($"Cannot find directory '{OutputDir}'");
|
||||
LogTarget.LogLine("Input directory not set.", LogEvent.ELogLevel.Error, "ExportProcess");
|
||||
return false;
|
||||
} else if (!Directory.Exists(OutputDir))
|
||||
{
|
||||
LogTarget.LogLine($"Cannot find directory '{OutputDir}'", LogEvent.ELogLevel.Error, "ExportProcess");
|
||||
return false;
|
||||
}
|
||||
|
||||
//TBD: Check if newer version of database is online
|
||||
LogTarget.StepStarted(1, $"Fetching commits from remote location");
|
||||
|
||||
|
||||
string outFile = Path.Combine(OutputDir, ImportExportSettings.ZipFile);
|
||||
try
|
||||
{
|
||||
// Depending on the directory this could be very large and would require more attention
|
||||
// in a commercial package.
|
||||
string[] filenames = Directory.GetFiles(MemberDir, "*.xml");
|
||||
string outFile = Path.Combine(OutputDir, MemberImportSettings.ZipFile);
|
||||
|
||||
if (File.Exists(outFile))
|
||||
{
|
||||
string backupName = $"{outFile}.bak";
|
||||
if (File.Exists(backupName)) File.Delete(backupName);
|
||||
File.Move(outFile, backupName);
|
||||
LogTarget.LogLine($"Creating backup of old {outFile}", LogEvent.ELogLevel.Info, "ExportProcess");
|
||||
XmlData.CreateBackup(outFile, true, "ExportProcess", true);
|
||||
}
|
||||
LogTarget.StepStarted(2, $"Packing {ImportExportSettings.ZipFile} ({filenames.Length} files)");
|
||||
|
||||
// 'using' statements guarantee the stream is closed properly which is a big source
|
||||
// of problems otherwise. Its exception safe as well which is great.
|
||||
using (ZipOutputStream s = new ZipOutputStream(File.Create(outFile)))
|
||||
{
|
||||
s.SetLevel(9); // 0 - store only to 9 - means best compression
|
||||
s.Password = MemberImportSettings.ZipPassword; //null is a desired value for "no encryption"
|
||||
s.SetLevel(9); // 0 - store only ... 9 - best compression
|
||||
s.Password = ImportExportSettings.ZipPassword; //null is a desired value for "no encryption"
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
|
||||
foreach (string file in filenames)
|
||||
{
|
||||
Console.WriteLine(file);
|
||||
//LogTarget.LogLine($"Packing {file}", LogEvent.ELogLevel.Trace, "ExportProcess");
|
||||
|
||||
// Using GetFileName makes the result compatible with XP
|
||||
// as the resulting path is not absolute.
|
||||
var entry = new ZipEntry(Path.GetFileName(file));
|
||||
|
@ -93,35 +115,104 @@ namespace dezentrale.core
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception during export: {ex.Message}");
|
||||
LogTarget.LogLine($"Exception during packing: {ex.Message}", LogEvent.ELogLevel.Error, "ExportProcess");
|
||||
|
||||
// No need to rethrow the exception as for our purposes its handled.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (MemberImportSettings.GpgEnabled)
|
||||
if (ImportExportSettings.GpgEnabled)
|
||||
{
|
||||
Console.WriteLine($"Export: Using GPG to encrypt {Path.Combine(OutputDir, MemberImportSettings.GpgFile)}");
|
||||
if (!Gpg($"--output \"{Path.Combine(OutputDir, MemberImportSettings.GpgFile)}\" -c \"{tmpFile}\"", MemberImportSettings.GpgPassword)) return false;
|
||||
tmpFile = Path.Combine(OutputDir, MemberImportSettings.GpgFile);
|
||||
LogTarget.StepStarted(3, $"Encrypting {ImportExportSettings.GpgFile}");
|
||||
LogTarget.LogLine($"Using GPG to encrypt {Path.Combine(OutputDir, ImportExportSettings.GpgFile)}", LogEvent.ELogLevel.Info, "ExportProcess");
|
||||
if (!Gpg($"--output \"{Path.Combine(OutputDir, ImportExportSettings.GpgFile)}\" -c \"{outFile}\"", ImportExportSettings.GpgPassword, LogTarget)) return false;
|
||||
outFile = Path.Combine(OutputDir, ImportExportSettings.GpgFile);
|
||||
}
|
||||
if (MemberImportSettings.HgEnabled)
|
||||
|
||||
LogTarget.StepStarted(4, $"Committing and pushing");
|
||||
if (ImportExportSettings.HgEnabled)
|
||||
{
|
||||
Console.WriteLine($"Export: Using HG to commit / push {tmpFile}");
|
||||
LogTarget.LogLine($"Using HG to commit / push {outFile}", LogEvent.ELogLevel.Info, "ExportProcess");
|
||||
//this might fail as repo might be existing / file might be already in repo
|
||||
RunProcess("hg", "init", OutputDir);
|
||||
RunProcess("hg", $"add {tmpFile}", OutputDir);
|
||||
RunProcess("hg", "init", OutputDir, LogTarget);
|
||||
RunProcess("hg", $"add {outFile}", OutputDir, LogTarget);
|
||||
//now, committing is more interesting
|
||||
if (!RunProcess("hg",
|
||||
"commit"
|
||||
+ $" --message \"dezentrale-members.exe --mode=export\nProgram version={Program.VersionString}\""
|
||||
+ $" --user \"{MemberImportSettings.HgUserName}\"", OutputDir))
|
||||
+ $" --user \"{ImportExportSettings.HgUserName}\"", OutputDir, LogTarget))
|
||||
return false;
|
||||
if (!RunProcess("hg", $"--config auth.rc.prefix={MemberImportSettings.HgURL} --config auth.rc.username={MemberImportSettings.HgUserName} --config auth.rc.password={MemberImportSettings.HgPassword} push {MemberImportSettings.HgURL}", OutputDir))
|
||||
if (!RunProcess("hg", $"--config auth.rc.prefix={ImportExportSettings.HgURL} --config auth.rc.username={ImportExportSettings.HgUserName} --config auth.rc.password={ImportExportSettings.HgPassword} push {ImportExportSettings.HgURL}", OutputDir, LogTarget))
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//TBD: Validate
|
||||
LogTarget.StepStarted(5, $"Validating the exported data");
|
||||
|
||||
//extract all to
|
||||
/*string verifyDirectory = Path.Combine(memberDirectory, "verify");
|
||||
try { Directory.CreateDirectory(verifyDirectory); }
|
||||
catch (Exception ex) { Console.WriteLine($"Error while creating verify directory:\n{ex.Message}"); return false; }
|
||||
|
||||
//Move all *.xml to *.bak in verify directory
|
||||
string[] filenames = Directory.GetFiles(verifyDirectory, "*.xml");
|
||||
foreach (string f in filenames)
|
||||
{
|
||||
string fileName = Path.Combine(verifyDirectory, f);
|
||||
string backupName = $"{fileName}.bak";
|
||||
if (File.Exists(backupName)) File.Delete(backupName);
|
||||
File.Move(fileName, backupName);
|
||||
File.Delete(fileName);
|
||||
}
|
||||
|
||||
if (!Import(verifyDirectory, outputDir)) return false;
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Verify: Checking files");
|
||||
filenames = Directory.GetFiles(memberDirectory, "*.xml");
|
||||
foreach (string fileWithPath in filenames)
|
||||
{
|
||||
string fileName = Path.GetFileName(fileWithPath);
|
||||
Console.WriteLine($"Checking for {fileName}");
|
||||
string origFile = Path.Combine(memberDirectory, fileName);
|
||||
string compareFile = Path.Combine(verifyDirectory, fileName);
|
||||
if (!File.Exists(compareFile))
|
||||
{
|
||||
Console.WriteLine($"File doesn't exist: {compareFile}");
|
||||
return false;
|
||||
}
|
||||
if (!FilesCompare(origFile, compareFile))
|
||||
{
|
||||
Console.WriteLine($"File comparison failed between: \"{compareFile}\" and \"{compareFile}\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
filenames = Directory.GetFiles(verifyDirectory, "*.xml");
|
||||
foreach (string fileWithPath in filenames)
|
||||
{
|
||||
string fileName = Path.GetFileName(fileWithPath);
|
||||
string origFile = Path.Combine(memberDirectory, fileName);
|
||||
string compareFile = Path.Combine(verifyDirectory, fileName);
|
||||
if (!File.Exists(origFile))
|
||||
{
|
||||
Console.WriteLine($"Found extra xml in verify folder: {compareFile}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Verify: Done. All OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception during verify: {ex.Message}");
|
||||
|
||||
// No need to rethrow the exception as for our purposes its handled.
|
||||
return false;
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,15 @@ namespace dezentrale.core
|
|||
{
|
||||
public abstract class ImportExportBase : BackgroundProcess
|
||||
{
|
||||
public model.MemberImportExport MemberImportSettings { get; set; } = null;
|
||||
public model.MemberImportExport ImportExportSettings { get; set; } = null;
|
||||
public string MemberDir { get; set; } = null; //! Directory that holds the application settings
|
||||
public string InputDir { get; set; } = null; //! Import working directory
|
||||
public string OutputDir { get; set; } = null; //! Export working directory
|
||||
|
||||
public static bool Gpg(string args, string gpgPassword)
|
||||
public static bool Gpg(string args, string gpgPassword, core.ILogger log = null)
|
||||
{
|
||||
string argsFull = $"--batch --yes --passphrase \"{gpgPassword}\" {args}";
|
||||
return RunProcess("gpg", argsFull);
|
||||
return RunProcess("gpg", argsFull, ".", log);
|
||||
}
|
||||
|
||||
public static bool RunProcess(string cmd, string args, string workingDir = ".", core.ILogger log = null)
|
||||
|
@ -24,7 +24,7 @@ namespace dezentrale.core
|
|||
if (log != null)
|
||||
{
|
||||
log.LogLine($"Running {cmd}", model.LogEvent.ELogLevel.Info, "RunProcess");
|
||||
log.LogRaw($"args: {cmd} {args}");
|
||||
log.LogRaw($"args: {args}");
|
||||
log.LogRaw($"dir: {workingDir}");
|
||||
}
|
||||
else
|
||||
|
@ -41,10 +41,28 @@ namespace dezentrale.core
|
|||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
p.StartInfo.CreateNoWindow = true;
|
||||
p.Start();
|
||||
string stdout = p.StandardOutput.ReadToEnd();
|
||||
string stderr = p.StandardError.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
|
||||
string stdout;
|
||||
string stderr;
|
||||
bool toReturn;
|
||||
//For testing the import/export, the versioning can be omitted by using gpgOnly = true.
|
||||
bool gpgOnly = false;
|
||||
|
||||
if (gpgOnly && !cmd.Equals("gpg"))
|
||||
{
|
||||
stdout = "std\r\nout";
|
||||
stderr = "std\r\nerr";
|
||||
Thread.Sleep(2000);
|
||||
toReturn = true;
|
||||
} else
|
||||
{
|
||||
p.Start();
|
||||
stdout = p.StandardOutput.ReadToEnd();
|
||||
stderr = p.StandardError.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
toReturn = p.ExitCode == 0;
|
||||
}
|
||||
|
||||
if (stdout.Length > 0)
|
||||
{
|
||||
if (log != null) log.LogRaw(stdout);
|
||||
|
@ -65,7 +83,7 @@ namespace dezentrale.core
|
|||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
return p.ExitCode == 0;
|
||||
return toReturn;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -11,28 +11,39 @@ namespace dezentrale.core
|
|||
public ImportProcess()
|
||||
{
|
||||
Caption = "Database import";
|
||||
Steps = 4;
|
||||
Steps = 5;
|
||||
}
|
||||
protected override bool Run()
|
||||
{
|
||||
|
||||
LogTarget.StepStarted(0, "Preparing import");
|
||||
|
||||
if (MemberImportSettings == null)
|
||||
if (ImportExportSettings == null)
|
||||
{
|
||||
LogTarget.LogLine("MemberImportExport data class not set.", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MemberDir == null)
|
||||
{
|
||||
LogTarget.LogLine("Member directory not set.", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
} else if (!Directory.Exists(MemberDir))
|
||||
{
|
||||
LogTarget.LogLine($"Cannot find directory '{MemberDir}'", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (InputDir == null)
|
||||
{
|
||||
LogTarget.LogLine("Input directory not set.", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
}
|
||||
else if (!Directory.Exists(InputDir))
|
||||
{
|
||||
LogTarget.LogLine($"Cannot find directory '{InputDir}'", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -40,63 +51,50 @@ namespace dezentrale.core
|
|||
|
||||
LogTarget.StepStarted(1, "Fetching repository");
|
||||
|
||||
if (MemberImportSettings.HgEnabled)
|
||||
if (ImportExportSettings.HgEnabled)
|
||||
{
|
||||
RunProcess("hg", "init", InputDir, LogTarget);
|
||||
RunProcess("hg", "update null", InputDir, LogTarget);
|
||||
if (!RunProcess("hg", $"--config auth.rc.prefix={MemberImportSettings.HgURL} --config auth.rc.username={MemberImportSettings.HgUserName} --config auth.rc.password={MemberImportSettings.HgPassword} pull {MemberImportSettings.HgURL}", InputDir, LogTarget))
|
||||
if (!RunProcess("hg", $"--config auth.rc.prefix={ImportExportSettings.HgURL} --config auth.rc.username={ImportExportSettings.HgUserName} --config auth.rc.password={ImportExportSettings.HgPassword} pull {ImportExportSettings.HgURL}", InputDir, LogTarget))
|
||||
return false;
|
||||
if (!RunProcess("hg", $"update", InputDir, LogTarget))
|
||||
return false;
|
||||
}
|
||||
if (MemberImportSettings.GpgEnabled)
|
||||
|
||||
if (ImportExportSettings.GpgEnabled)
|
||||
{
|
||||
Console.WriteLine($"Import: Using GPG to decrypt {Path.Combine(InputDir, MemberImportSettings.GpgFile)}");
|
||||
if (!Gpg($"--output {Path.Combine(InputDir, MemberImportSettings.ZipFile)} --decrypt {Path.Combine(InputDir, MemberImportSettings.GpgFile)}", MemberImportSettings.GpgPassword)) return false;
|
||||
}
|
||||
if (!Directory.Exists(MemberDir))
|
||||
{
|
||||
LogTarget.LogLine($"Cannot find directory '{MemberDir}'", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
}
|
||||
if (!Directory.Exists(InputDir))
|
||||
{
|
||||
LogTarget.LogLine($"Cannot find directory '{InputDir}'", LogEvent.ELogLevel.Error, "ImportProcess");
|
||||
return false;
|
||||
LogTarget.StepStarted(2, $"Decrypting {ImportExportSettings.GpgFile}");
|
||||
LogTarget.LogLine($"Import: Using GPG to decrypt {Path.Combine(InputDir, ImportExportSettings.GpgFile)}", LogEvent.ELogLevel.Info, "ImportProcess");
|
||||
if (!Gpg($"--output {Path.Combine(InputDir, ImportExportSettings.ZipFile)} --decrypt {Path.Combine(InputDir, ImportExportSettings.GpgFile)}", ImportExportSettings.GpgPassword, LogTarget)) return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LogTarget.StepStarted(2, $"Backupping Contents of {MemberDir}");
|
||||
LogTarget.StepStarted(3, $"Backupping Contents of {MemberDir}");
|
||||
|
||||
string[] filenames = Directory.GetFiles(MemberDir, "*.xml");
|
||||
LogTarget.LogLine($"Renaming {filenames.Length} xml files to xml.bak in {MemberDir}", LogEvent.ELogLevel.Info, "ImportProcess");
|
||||
LogTarget.LogLine($"Backing up all xml in {MemberDir} ({filenames.Length} files)", LogEvent.ELogLevel.Info, "ImportProcess");
|
||||
|
||||
foreach (string f in filenames)
|
||||
{
|
||||
|
||||
string fileName = Path.GetFileName(f);
|
||||
string backupName = $"{fileName}.bak";
|
||||
if (File.Exists(backupName))
|
||||
{
|
||||
LogTarget.LogLine($"Deleting previous {backupName}", LogEvent.ELogLevel.Trace, "ImportProcess");
|
||||
File.Delete(backupName);
|
||||
}
|
||||
LogTarget.LogLine($"Renaming {fileName} ({f}) to {backupName}", LogEvent.ELogLevel.Trace, "ImportProcess");
|
||||
File.Move(fileName, backupName);
|
||||
|
||||
LogTarget.LogLine($"Deleting backupped {fileName}", LogEvent.ELogLevel.Trace, "ImportProcess");
|
||||
File.Delete(fileName);
|
||||
//LogTarget.LogLine($"Creating backup of {f}", LogEvent.ELogLevel.Trace, "ImportProcess");
|
||||
XmlData.CreateBackup(f, false, "DbImport", true);
|
||||
}
|
||||
foreach (string f in filenames)
|
||||
{
|
||||
//LogTarget.LogLine($"Deleting backupped {f}", LogEvent.ELogLevel.Trace, "ImportProcess");
|
||||
File.Delete(f);
|
||||
}
|
||||
System.Threading.Thread.Sleep(10);
|
||||
|
||||
LogTarget.StepStarted(3, $"Unpacking {MemberImportSettings.ZipFile}");
|
||||
LogTarget.LogLine($"Extracting {Path.Combine(InputDir, MemberImportSettings.ZipFile)}", LogEvent.ELogLevel.Info, "ImportProcess");
|
||||
string inFile = Path.Combine(InputDir, MemberImportSettings.ZipFile);
|
||||
LogTarget.StepStarted(4, $"Unpacking {ImportExportSettings.ZipFile}");
|
||||
LogTarget.LogLine($"Extracting {Path.Combine(InputDir, ImportExportSettings.ZipFile)}", LogEvent.ELogLevel.Info, "ImportProcess");
|
||||
string inFile = Path.Combine(InputDir, ImportExportSettings.ZipFile);
|
||||
|
||||
|
||||
using (ZipInputStream s = new ZipInputStream(File.OpenRead(inFile)))
|
||||
{
|
||||
s.Password = MemberImportSettings.ZipPassword;
|
||||
s.Password = ImportExportSettings.ZipPassword;
|
||||
|
||||
ZipEntry theEntry;
|
||||
while ((theEntry = s.GetNextEntry()) != null)
|
||||
|
@ -136,7 +134,7 @@ namespace dezentrale.core
|
|||
}
|
||||
}
|
||||
}
|
||||
LogTarget.StepCompleted(3, $"Unpacking {MemberImportSettings.ZipFile}", true);
|
||||
LogTarget.StepCompleted(4, $"Unpacking {ImportExportSettings.ZipFile}", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace dezentrale.model
|
|||
[XmlElement] public MemberImportExport ImportExport{ get; set; } = new MemberImportExport();
|
||||
|
||||
[XmlElement] public string DbDirectory { get; set; } = DefaultDbDirectory;
|
||||
//[XmlElement] public string DbBackupDirectory { get; set; } = DefaultDbBackupDirectory;
|
||||
//[XmlElement] public string ImportExportDirectory { get; set; } = DefaultImportExportDirectory;
|
||||
[XmlElement] public uint RegularPaymentAmount { get; set; } = 3200; //cents
|
||||
[XmlElement] public string RegularPaymentCurrency { get; set; } = "EUR";
|
||||
[XmlElement] public string LocalUser { get; set; } = "John Doe";
|
||||
|
@ -26,6 +28,8 @@ namespace dezentrale.model
|
|||
[XmlElement] public List<KeyValue> MoneyTransferRegEx { get; set; } = new List<KeyValue>(); //This doesn't belong here! Move to new file within db-data!
|
||||
[XmlElement] public DateTime LastCronjobRun { get; set; } = DateTime.Now; //This doesn't belong here! Move to new file within db-data!
|
||||
|
||||
[XmlIgnore] public static string DefaultDbDirectory{ get; private set; } = "db-data";
|
||||
[XmlIgnore] public static string DefaultDbDirectory { get; private set; } = "db-data";
|
||||
//[XmlIgnore] public static string DefaultDbBackupDirectory { get; private set; } = "db-backup";
|
||||
//[XmlIgnore] public static string DefaultImportExportDirectory { get; private set; } = "import-export";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,34 +21,6 @@ namespace dezentrale.model
|
|||
[XmlElement] public string GitUserName { get; set; } = "";
|
||||
[XmlElement] public string GitPassword { get; set; } = "";
|
||||
|
||||
[Obsolete]
|
||||
public bool Export(string memberDirectory, string outputDir)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public bool Import(string memberDirectory, string inputDir)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/*if(HgEnabled)
|
||||
{
|
||||
RunProcess("hg", "init", inputDir);
|
||||
RunProcess("hg", "update null", inputDir);
|
||||
if (!RunProcess("hg", $"--config auth.rc.prefix={HgURL} --config auth.rc.username={HgUserName} --config auth.rc.password={HgPassword} pull {HgURL}", inputDir))
|
||||
return false;
|
||||
if (!RunProcess("hg", $"update", inputDir))
|
||||
return false;
|
||||
}
|
||||
if (GpgEnabled)
|
||||
{
|
||||
Console.WriteLine($"Import: Using GPG to decrypt {Path.Combine(inputDir, GpgFile)}");
|
||||
if (!Gpg($"--output {Path.Combine(inputDir, ZipFile)} --decrypt {Path.Combine(inputDir, GpgFile)}", GpgPassword)) return false;
|
||||
}
|
||||
Console.WriteLine($"Import: Extracting {Path.Combine(inputDir, ZipFile)}");
|
||||
if (ZipImport(memberDirectory, inputDir) != true) return false;
|
||||
return true;*/
|
||||
}
|
||||
private bool FilesCompare(string file1, string file2)
|
||||
{
|
||||
try
|
||||
|
@ -68,85 +40,5 @@ namespace dezentrale.model
|
|||
}
|
||||
return true;
|
||||
}
|
||||
[Obsolete]
|
||||
public bool VerifyExport(string memberDirectory, string outputDir)
|
||||
{
|
||||
if (!Directory.Exists(memberDirectory))
|
||||
{
|
||||
Console.WriteLine($"Cannot find directory '{memberDirectory}'");
|
||||
return false;
|
||||
}
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
Console.WriteLine($"Cannot find directory '{outputDir}'");
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.WriteLine("Verifying exported");
|
||||
//extract all to
|
||||
string verifyDirectory = Path.Combine(memberDirectory, "verify");
|
||||
try { Directory.CreateDirectory(verifyDirectory); }
|
||||
catch (Exception ex) { Console.WriteLine($"Error while creating verify directory:\n{ex.Message}"); return false; }
|
||||
|
||||
//Move all *.xml to *.bak in verify directory
|
||||
string[] filenames = Directory.GetFiles(verifyDirectory, "*.xml");
|
||||
foreach (string f in filenames)
|
||||
{
|
||||
string fileName = Path.Combine(verifyDirectory, f);
|
||||
string backupName = $"{fileName}.bak";
|
||||
if (File.Exists(backupName)) File.Delete(backupName);
|
||||
File.Move(fileName, backupName);
|
||||
File.Delete(fileName);
|
||||
}
|
||||
|
||||
if (!Import(verifyDirectory, outputDir)) return false;
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Verify: Checking files");
|
||||
filenames = Directory.GetFiles(memberDirectory, "*.xml");
|
||||
foreach (string fileWithPath in filenames)
|
||||
{
|
||||
string fileName = Path.GetFileName(fileWithPath);
|
||||
Console.WriteLine($"Checking for {fileName}");
|
||||
string origFile = Path.Combine(memberDirectory, fileName);
|
||||
string compareFile = Path.Combine(verifyDirectory, fileName);
|
||||
if (!File.Exists(compareFile))
|
||||
{
|
||||
Console.WriteLine($"File doesn't exist: {compareFile}");
|
||||
return false;
|
||||
}
|
||||
if (!FilesCompare(origFile, compareFile))
|
||||
{
|
||||
Console.WriteLine($"File comparison failed between: \"{compareFile}\" and \"{compareFile}\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
filenames = Directory.GetFiles(verifyDirectory, "*.xml");
|
||||
foreach (string fileWithPath in filenames)
|
||||
{
|
||||
string fileName = Path.GetFileName(fileWithPath);
|
||||
string origFile = Path.Combine(memberDirectory, fileName);
|
||||
string compareFile = Path.Combine(verifyDirectory, fileName);
|
||||
if (!File.Exists(origFile))
|
||||
{
|
||||
Console.WriteLine($"Found extra xml in verify folder: {compareFile}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Verify: Done. All OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception during verify: {ex.Message}");
|
||||
|
||||
// No need to rethrow the exception as for our purposes its handled.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,36 @@ namespace dezentrale.model
|
|||
public class XmlData
|
||||
{
|
||||
[XmlAttribute] public DateTime LastChanged { get; set; } = DateTime.Now;
|
||||
[XmlAttribute] public string ProgramVersion { get; set; } = "";
|
||||
[XmlAttribute] public string ProgramVersion { get; set; } = "";
|
||||
|
||||
/** \brief Move or make a backup copy of the specified file to the same folder. Will overwrite old backups if @ref permanentWithTimestamp is false
|
||||
* \param name="fileWithPath" Source file to copy. File must exist.
|
||||
* \param name="backupName" Optional name for a backup. E.g. "PreImport" or "NewProgVersion"
|
||||
* \param param name="permanentWithTimestamp" Stores the backup including a timestamp (@ref DateTime.Now) and fails if the target file already exists.
|
||||
* \return the resulting name on success.
|
||||
* \note this method throws Exceptions when failing.
|
||||
*/
|
||||
public static string CreateBackup(string fileWithPath, bool fileMove = true, string backupName = null, bool permanentWithTimestamp = false)
|
||||
{
|
||||
if (!File.Exists(fileWithPath)) throw new FileNotFoundException(fileWithPath);
|
||||
string backupFile = fileWithPath;
|
||||
if (backupName != null) backupFile += "." + backupName;
|
||||
if (permanentWithTimestamp) backupFile += "." + DateTime.Now.ToString("yyMMdd_HHmmss");
|
||||
backupFile += ".bak";
|
||||
|
||||
if (File.Exists(backupFile))
|
||||
{
|
||||
if (permanentWithTimestamp)
|
||||
throw new IOException($"File {backupFile} already exists");
|
||||
|
||||
File.Delete(backupFile);
|
||||
}
|
||||
|
||||
if (fileMove) File.Move(fileWithPath, backupFile);
|
||||
else File.Copy(fileWithPath, backupFile);
|
||||
|
||||
return backupName;
|
||||
}
|
||||
|
||||
public static XmlData LoadFromFile(string fileName, Type type = null)
|
||||
{
|
||||
|
@ -26,10 +55,14 @@ namespace dezentrale.model
|
|||
{
|
||||
Console.WriteLine($"Object of type {ds.GetType()} was stored in Version {ds.ProgramVersion:X8}, Re-Storing with {Program.VersionNumber:X8}");
|
||||
//backup file
|
||||
string backupName = $"{fileName}.v{ds.ProgramVersion:X8}.bak";
|
||||
if (File.Exists(backupName)) File.Delete(backupName);
|
||||
File.Move(fileName, backupName);
|
||||
if (!SaveToFile(fileName, ds)) throw new Exception("Saving returned false");
|
||||
try
|
||||
{
|
||||
CreateBackup(fileName, true, $"v{ds.ProgramVersion:X8}", true);
|
||||
if (!SaveToFile(fileName, ds)) throw new Exception("Saving returned false");
|
||||
} catch(Exception e2)
|
||||
{
|
||||
Console.WriteLine($"Error {e2.GetType()}: {e2.Message}");
|
||||
}
|
||||
}
|
||||
return ds;
|
||||
}
|
||||
|
@ -48,9 +81,10 @@ namespace dezentrale.model
|
|||
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
string backupName = $"{fileName}.bak";
|
||||
if (File.Exists(backupName)) File.Delete(backupName);
|
||||
File.Move(fileName, backupName);
|
||||
CreateBackup(fileName);
|
||||
//string backupName = $"{fileName}.bak";
|
||||
//if (File.Exists(backupName)) File.Delete(backupName);
|
||||
//File.Move(fileName, backupName);
|
||||
}
|
||||
Console.WriteLine($"XmlData.SaveToFile({ds.GetType()})");
|
||||
ds.ProgramVersion = Program.VersionString;
|
||||
|
|
|
@ -121,16 +121,14 @@ namespace dezentrale.view
|
|||
}
|
||||
private void mnuMain_File_Export(object sender, EventArgs e)
|
||||
{
|
||||
if (!Program.config.ImportExport.Export(Program.config.DbDirectory, Program.DmDirectory))
|
||||
{
|
||||
MessageBox.Show("Export failed!");
|
||||
return;
|
||||
}
|
||||
if (!Program.config.ImportExport.VerifyExport(Program.config.DbDirectory, Program.DmDirectory))
|
||||
{
|
||||
MessageBox.Show("Export verify failed!");
|
||||
return;
|
||||
}
|
||||
ExportProcess export = new ExportProcess()
|
||||
{
|
||||
ImportExportSettings = Program.config.ImportExport,
|
||||
MemberDir = Program.config.DbDirectory,
|
||||
OutputDir = Program.DmDirectory,
|
||||
};
|
||||
frmProcessWithLog frmImport = new frmProcessWithLog(export, false);
|
||||
frmImport.ShowDialog();
|
||||
}
|
||||
|
||||
private void mnuMain_File_Import(object sender, EventArgs e)
|
||||
|
@ -140,7 +138,7 @@ namespace dezentrale.view
|
|||
{
|
||||
ImportProcess import = new ImportProcess()
|
||||
{
|
||||
MemberImportSettings = Program.config.ImportExport,
|
||||
ImportExportSettings = Program.config.ImportExport,
|
||||
MemberDir = Program.config.DbDirectory,
|
||||
InputDir = Program.DmDirectory,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue