1
0
mirror of https://github.com/chylex/Backup-Essentials.git synced 2025-05-19 10:34:08 +02:00

Moved IO classes out and added a report generator

This commit is contained in:
chylex 2015-04-06 13:43:53 +02:00
parent adaf5c82ef
commit 7dcf4a4db4
6 changed files with 128 additions and 11 deletions

View File

@ -0,0 +1,81 @@
using BackupEssentials.Backup.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace BackupEssentials.Backup{
class BackupReport{
private readonly string _plain;
private string _parsed;
public string Report {
get {
if (_parsed == null){
StringBuilder build = new StringBuilder(16+(int)Math.Floor(_plain.Length*1.5D));
foreach(string line in SplitByLine(_plain)){
if (line.Length == 0)continue;
if (line[0] == 'I')build.Append(line.Substring(1)).Append(Environment.NewLine);
else if (line[0] == 'A' && line.Length > 3)build.Append(GetFullNameAction(line[1])).Append(' ').Append(GetFullNameType(line[2])).Append(' ').Append(line.Substring(3)).Append(Environment.NewLine);
}
_parsed = build.ToString();
}
return _parsed;
}
}
private BackupReport(string report){
this._plain = report;
}
public override string ToString(){
return Report;
}
public class Builder{
private StringBuilder Build = new StringBuilder(256);
public void Add(IOAction action, IOType type, string path){
Build.Append('A').Append(GetShortName(action)).Append(GetShortName(type)).Append(path).Append(Environment.NewLine);
}
public void Add(string message){
Build.Append('I').Append(message).Append(Environment.NewLine);
}
public BackupReport Finish(){
return new BackupReport(Build.ToString());
}
}
private static char GetShortName(IOAction action){
return action == IOAction.Create ? 'C' : action == IOAction.Delete ? 'D' : action == IOAction.Replace ? 'R' : '?';
}
private static string GetFullNameAction(char key){
return key == 'C' ? "Added" : key == 'D' ? "Deleted" : key == 'R' ? "Updated" : "(unknown action)";
}
private static char GetShortName(IOType type){
return type == IOType.File ? 'F' : type == IOType.Directory ? 'D' : '?';
}
private static string GetFullNameType(char key){
return key == 'F' ? "File" : key == 'D' ? "Folder" : "(unknown type)";
}
private static IEnumerable<string> SplitByLine(string str){
using(StringReader reader = new StringReader(str)){
string line;
while((line = reader.ReadLine()) != null){
yield return line;
}
}
}
}
}

View File

@ -1,10 +1,13 @@
using BackupEssentials.Utils;
using BackupEssentials.Backup.IO;
using BackupEssentials.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
namespace BackupEssentials.Backup{
public class BackupRunner{
@ -101,6 +104,19 @@ namespace BackupEssentials.Backup{
int totalActions = actions.Count, attempts = 10;
string path;
BackupReport.Builder reportBuilder = new BackupReport.Builder();
reportBuilder.Add("= Preparing backup =");
reportBuilder.Add("Source: "+src);
reportBuilder.Add("Destination: "+destFolder);
reportBuilder.Add("Date: "+DateTime.Now.ToString("d")+" "+DateTime.Now.ToString("t"));
reportBuilder.Add("");
reportBuilder.Add("= Files and folders =");
reportBuilder.Add("Added: "+actions.Count((entry) => entry.Action == IOAction.Create));
reportBuilder.Add("Updated: "+actions.Count((entry) => entry.Action == IOAction.Replace));
reportBuilder.Add("Deleted: "+actions.Count((entry) => entry.Action == IOAction.Delete));
reportBuilder.Add("");
reportBuilder.Add("= Starting backup =");
while(actions.Count > 0 && --attempts > 0){
for(int index = 0; index < actions.Count; index++){
IOActionEntry entry = actions[index];
@ -129,7 +145,7 @@ namespace BackupEssentials.Backup{
}
indexesToRemove.Add(index-indexesToRemove.Count); // goes from 0 to actions.Count, removing each index will move the structure
Debug.WriteLine("Finished: "+entry.ToString());
reportBuilder.Add(entry.Action,entry.Type,entry.RelativePath);
worker.ReportProgress((int)Math.Ceiling(((totalActions-actions.Count+indexesToRemove.Count)*100D)/totalActions));
if (worker.CancellationPending)break;
@ -139,22 +155,25 @@ namespace BackupEssentials.Backup{
// TODO handle special exceptions (security etc)
}
if (worker.CancellationPending)throw new Exception("Backup canceled.");
if (worker.CancellationPending){
reportBuilder.Add("= Backup canceled =");
e.Result = reportBuilder.Finish();
throw new Exception("Backup canceled.");
}
}
foreach(int index in indexesToRemove)actions.RemoveAt(index);
indexesToRemove.Clear();
}
if (attempts == 0)throw new Exception("Backup failed: ran out of attempts.");
}
if (attempts == 0){
reportBuilder.Add("= Backup failed (out of attempts) =");
e.Result = reportBuilder.Finish();
throw new Exception("Backup failed: ran out of attempts.");
}
private enum IOType{
None, File, Directory
}
private enum IOAction{
None, Create, Replace, Delete
reportBuilder.Add("= Backup finished =");
e.Result = reportBuilder.Finish();
}
private class IOEntry{

View File

@ -0,0 +1,5 @@
namespace BackupEssentials.Backup.IO{
enum IOAction{
None, Create, Replace, Delete
}
}

View File

@ -0,0 +1,5 @@
namespace BackupEssentials.Backup.IO{
enum IOType{
None, File, Directory
}
}

View File

@ -83,9 +83,12 @@
<DependentUpon>BackupWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Backup\BackupLocation.cs" />
<Compile Include="Backup\BackupReport.cs" />
<Compile Include="Backup\BackupRunner.cs" />
<Compile Include="Backup\DataStorage.cs" />
<Compile Include="Backup\ExplorerIntegration.cs" />
<Compile Include="Backup\IO\IOAction.cs" />
<Compile Include="Backup\IO\IOType.cs" />
<Compile Include="Pages\About.xaml.cs">
<DependentUpon>About.xaml</DependentUpon>
</Compile>

View File

@ -10,6 +10,7 @@ namespace BackupEssentials{
public partial class BackupWindow : Window{
private BackupRunner Runner;
private int ActionCount;
private BackupReport Report;
private DispatcherTimer CloseTimer;
public BackupWindow(BackupRunner runner){
@ -48,6 +49,9 @@ namespace BackupEssentials{
Runner = null;
ButtonShowReport.IsEnabled = true;
ButtonEnd.Content = "Close";
Report = e.Result as BackupReport;
Debug.WriteLine(Report.Report);
if (e.Error != null){
LabelInfo.Content = e.Error.Message;