2021-05-30PX Bugfixing, working towards attachments
This commit is contained in:
parent
2934e9c75a
commit
44922db6f7
|
@ -38,7 +38,7 @@ namespace dezentrale
|
|||
{
|
||||
public class Program
|
||||
{
|
||||
public static uint VersionNumber { get; private set; } = 0x20120500;
|
||||
public static uint VersionNumber { get; private set; } = 0x21052800;
|
||||
public static string VersionString { get; private set; } = $"{VersionNumber:x}";
|
||||
|
||||
public static string AppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.IO;
|
|||
using ICSharpCode.SharpZipLib.Zip;
|
||||
|
||||
using dezentrale.model;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace dezentrale.core
|
||||
{
|
||||
|
@ -63,14 +64,16 @@ namespace dezentrale.core
|
|||
{
|
||||
// Depending on the directory this could be very large and would require more attention
|
||||
// in a commercial package.
|
||||
string[] filenames = Directory.GetFiles(MemberDir, "*.xml");
|
||||
List<string> filenames = new List<string>();
|
||||
filenames.AddRange(Directory.GetFiles(MemberDir, "*.xml")); //All serializable datasets
|
||||
filenames.AddRange(Directory.GetFiles(MemberDir, "*.zip")); //compressed blobs, e.g. Attachments
|
||||
|
||||
if (File.Exists(outFile))
|
||||
{
|
||||
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)");
|
||||
LogTarget.StepStarted(2, $"Packing {ImportExportSettings.ZipFile} ({filenames.Count} 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.
|
||||
|
|
|
@ -70,10 +70,10 @@ namespace dezentrale.core
|
|||
mvi.Member.MvMissCounter++;
|
||||
if (mvi.Member.MvMissCounter >= 2)
|
||||
{
|
||||
mvi.Member.Type = Member.eType.Foerdermitglied;
|
||||
//Send mail that type changed to Foerdermitglied
|
||||
lse = mvTypeChangeNotification.Send(mvi.Member);
|
||||
if (lse.Type == LogEvent.eEventType.Error) throw new Exception($"Sending mail to {entryDesc} failed.");
|
||||
mvi.Member.Type = Member.eType.Foerdermitglied;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -208,6 +208,7 @@
|
|||
<Compile Include="view\LvMvInvitations.cs" />
|
||||
<Compile Include="model\XmlLog.cs" />
|
||||
<Compile Include="core\MvFinishProcess.cs" />
|
||||
<Compile Include="view\LvAttachments.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
|
|
179
model/Blob.cs
179
model/Blob.cs
|
@ -2,107 +2,114 @@
|
|||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
|
||||
namespace dezentrale.model
|
||||
{
|
||||
public class Blob
|
||||
{
|
||||
[XmlAttribute] public DateTime Added { get; set; } = DateTime.Now;
|
||||
[XmlAttribute] public DateTime Modified { get; set; }
|
||||
[XmlElement] public string FileName { get; set; } = "";
|
||||
[XmlIgnore] public string DataFileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{FileName}.xml";
|
||||
}
|
||||
}
|
||||
private BlobData data = null;
|
||||
[XmlIgnore] public BlobData Data
|
||||
{
|
||||
get
|
||||
{
|
||||
if(data == null)
|
||||
{
|
||||
data = new BlobData();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
set
|
||||
{
|
||||
data = value;
|
||||
}
|
||||
}
|
||||
[XmlAttribute] public string FileName { get; set; } = "";
|
||||
[XmlAttribute] public DateTime Added { get; set; } = DateTime.Now;
|
||||
[XmlAttribute] public DateTime Modified { get; set; }
|
||||
[XmlAttribute] public int Size { get; set; } = 0;
|
||||
[XmlAttribute] public string DataFileName { get; set; } = null;
|
||||
[XmlIgnore] public string CompletePath
|
||||
{ get {
|
||||
return System.IO.Path.Combine(Program.config.DbDirectory, DataFileName);
|
||||
} }
|
||||
|
||||
public Blob() : base() { }
|
||||
public Blob(string fileName) : base()
|
||||
{
|
||||
Added = DateTime.Now;
|
||||
FileName = fileName;
|
||||
Added = Modified = DateTime.Now;
|
||||
}
|
||||
public Blob(string fileName, byte[] contents) : base()
|
||||
{
|
||||
Added = DateTime.Now;
|
||||
FileName = fileName;
|
||||
SetContents(contents);
|
||||
}
|
||||
|
||||
public byte[] GetContents()
|
||||
{
|
||||
if (DataFileName == null) return null;
|
||||
using (ZipInputStream s = new ZipInputStream(File.OpenRead(CompletePath)))
|
||||
{
|
||||
ZipEntry theEntry;
|
||||
while ((theEntry = s.GetNextEntry()) != null)
|
||||
{
|
||||
|
||||
Console.WriteLine(theEntry.Name);
|
||||
string fileName = Path.GetFileName(theEntry.Name);
|
||||
|
||||
if(fileName == FileName)
|
||||
{
|
||||
long size = theEntry.Size;
|
||||
if (size != this.Size) throw new Exception($"Size in file {DataFileName} ({FileName}) differs from expected.");
|
||||
byte[] contents = new byte[size];
|
||||
size = s.Read(contents, 0, size);
|
||||
if(size != Size) throw new Exception($"Size in file {DataFileName} ({FileName}) differs from expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetContents(byte[] contents, bool deleteOldContentFile = true)
|
||||
{
|
||||
Modified = DateTime.Now;
|
||||
if (DataFileName != null)
|
||||
{
|
||||
//Delete old contents
|
||||
try
|
||||
{
|
||||
File.Delete(CompletePath);
|
||||
Console.WriteLine($"Old content file {DataFileName} deleted.");
|
||||
DataFileName = null;
|
||||
Size = 0;
|
||||
} catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Cannot delete file {DataFileName}:");
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
} else
|
||||
{
|
||||
Console.WriteLine($"Old content file {DataFileName} kept. This is an orphan now.");
|
||||
}
|
||||
|
||||
if (contents != null)
|
||||
{
|
||||
//store into file
|
||||
string completePath = "";
|
||||
|
||||
do
|
||||
{
|
||||
DataFileName = $"{Guid.NewGuid().ToString()}.zip";
|
||||
} while (File.Exists(CompletePath)); //should never happen but we're checking to be sure.
|
||||
|
||||
Size = contents.Length;
|
||||
|
||||
using (ZipOutputStream s = new ZipOutputStream(File.Create(completePath)))
|
||||
{
|
||||
s.SetLevel(9); // 0 - store only ... 9 - best compression
|
||||
|
||||
var entry = new ZipEntry(FileName) { DateTime = DateTime.Now };
|
||||
s.PutNextEntry(entry);
|
||||
|
||||
s.Write(contents, 0, contents.Length);
|
||||
s.Finish();
|
||||
s.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool SaveData()
|
||||
{
|
||||
string completePath = System.IO.Path.Combine(Program.config.DbDirectory, DataFileName);
|
||||
Program.config.DbChangedSinceExport = true;
|
||||
Program.config.LastDbLocalChange = DateTime.Now;
|
||||
XmlData.SaveToFile(Program.ConfigFile, Program.config);
|
||||
return XmlData.SaveToFile(completePath, Data);
|
||||
}
|
||||
}
|
||||
|
||||
public class BlobData : XmlData
|
||||
{
|
||||
[XmlAttribute] public bool Compressed { get; set; } = false;
|
||||
[XmlAttribute] public int DecompressedLength { get; set; } = 0;
|
||||
public byte[] DataInternal { get; set; }
|
||||
[XmlIgnore] public byte[] Bytes
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!Compressed)
|
||||
{
|
||||
return DataInternal;
|
||||
} else
|
||||
{
|
||||
//\todo This doesn't work right yet
|
||||
Inflater i = new Inflater(false);
|
||||
i.SetInput(DataInternal);
|
||||
byte[] ret = new byte[DecompressedLength];
|
||||
|
||||
int len = i.Inflate(ret);
|
||||
if (len != DecompressedLength) throw new Exception("Decompression of {DecompressedLength} Bytes using Inflater failed");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
DecompressedLength = value.Length;
|
||||
if(true) //if (DecompressedLength == 0)
|
||||
{
|
||||
Compressed = false;
|
||||
DataInternal = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//\todo This doesn't work right yet
|
||||
Deflater d = new Deflater(Deflater.BEST_COMPRESSION, false);
|
||||
d.SetInput(value);
|
||||
byte[] output = new byte[DecompressedLength];
|
||||
int len = d.Deflate(output, 0, DecompressedLength);
|
||||
if (len < 0)
|
||||
{
|
||||
Console.WriteLine($"Deflate compression of {DecompressedLength} Bytes returned {len}, storing uncompressed");
|
||||
Compressed = false;
|
||||
DataInternal = value;
|
||||
} else
|
||||
{
|
||||
Compressed = true;
|
||||
byte[] di = new byte[len];
|
||||
Buffer.BlockCopy(output, 0, di, 0, len);
|
||||
DataInternal = di;
|
||||
}
|
||||
}
|
||||
}
|
||||
return XmlData.SaveToFile(Program.ConfigFile, Program.config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace dezentrale.model
|
|||
[XmlElement("MvListColumn")] public List<ConfigLVColumn> MvListColumns { get; set; } = new List<ConfigLVColumn>();
|
||||
[XmlElement("MvInvitationsListColumn")]
|
||||
public List<ConfigLVColumn> MvInvitationsListColumns{ get; set; } = new List<ConfigLVColumn>();
|
||||
[XmlElement("AttachmentsColumn")]public List<ConfigLVColumn> AttachmentsColumns{ get; set; } = new List<ConfigLVColumn>();
|
||||
|
||||
[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!
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using dezentrale.model;
|
||||
|
||||
namespace dezentrale.view
|
||||
{
|
||||
public class LvAttachments : CustomListView<MvInvitedMember>
|
||||
{
|
||||
protected override List<ConfigLVDataHandler> DefaultColumns
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<ConfigLVDataHandler>()
|
||||
{
|
||||
new ConfigLVDataHandler()
|
||||
{
|
||||
Name = "fileName",
|
||||
Display = "FileName",
|
||||
Width = 40,
|
||||
CustomToString = x => ((MvInvitedMember)x).NumberString,
|
||||
},
|
||||
new ConfigLVDataHandler()
|
||||
{
|
||||
Name = "added",
|
||||
Display = "Added",
|
||||
Width = 88,
|
||||
CustomToString = ( x => (((MvInvitedMember)x).InvitationDate.Year > 1 ? ((MvInvitedMember)x).InvitationDate.ToString() : "-") ),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public LvAttachments() : base(Program.config.AttachmentsColumns, LvAttachments_ColumnsChanged) { }
|
||||
|
||||
private static void LvAttachments_ColumnsChanged(object sender, ColumnsChangedArgs e)
|
||||
{
|
||||
Console.WriteLine("LvAttachments_ColumnsChanged");
|
||||
Program.config.AttachmentsColumns.Clear();
|
||||
foreach (ConfigLVDataHandler c in e.Columns) Program.config.AttachmentsColumns.Add(new ConfigLVColumn(c));
|
||||
XmlData.SaveToFile(Program.ConfigFile, Program.config);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,15 +102,17 @@ namespace dezentrale.view
|
|||
AddButton("Close", btnClose_Click);
|
||||
|
||||
|
||||
mvDate.Enabled = mv.Status == Mv.MvStatus.InPreparation;
|
||||
mvTime.Enabled = mv.Status == Mv.MvStatus.InPreparation;
|
||||
tbPlace.ReadOnly = mv.Status != Mv.MvStatus.InPreparation;
|
||||
tbMvAgenda.ReadOnly = mv.Status != Mv.MvStatus.InPreparation;
|
||||
tbInviteHeadline.ReadOnly= mv.Status != Mv.MvStatus.InPreparation;
|
||||
tbInviteBody.ReadOnly = mv.Status != Mv.MvStatus.InPreparation;
|
||||
bool invitationPhase = (mv.Status == Mv.MvStatus.InPreparation)
|
||||
|| (mv.Status == Mv.MvStatus.InvitationSent);
|
||||
mvDate.Enabled = invitationPhase;
|
||||
mvTime.Enabled = invitationPhase;
|
||||
tbPlace.ReadOnly = !invitationPhase;
|
||||
tbMvAgenda.ReadOnly = !invitationPhase;
|
||||
tbInviteHeadline.ReadOnly= !invitationPhase;
|
||||
tbInviteBody.ReadOnly = !invitationPhase;
|
||||
|
||||
tbAuthCodePaste.ReadOnly = mv.Status != Mv.MvStatus.Started;
|
||||
tbMvProtocol.ReadOnly = mv.Status != Mv.MvStatus.Started;
|
||||
tbMvProtocol.ReadOnly = invitationPhase;
|
||||
switch (mv.Status)
|
||||
{
|
||||
case Mv.MvStatus.InPreparation:
|
||||
|
|
Loading…
Reference in New Issue