using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Windows; using System.Windows.Media.Imaging; using InABox.Core; using InABox.Scripting; using InABox.WPF; using Microsoft.Win32; namespace InABox.DynamicGrid { public delegate bool OnImportItem(object o); public class CustomiseImportArgs { public string FileName { get; set; } } public delegate void OnCustomiseImport(object sender, CustomiseImportArgs e); public class DynamicImportGrid : DynamicDataGrid { private static readonly BitmapImage run = Wpf.Resources.rightarrow.AsBitmapImage(); public DynamicImportGrid() { Options.AddRange(DynamicGridOption.RecordCount, DynamicGridOption.ShowHelp); ActionColumns.Add(new DynamicImageColumn(ImportImage, ImportAction)); HiddenColumns.Add(x => x.EntityName); HiddenColumns.Add(x => x.ImporterDescription); HiddenColumns.Add(x => x.FileName); HiddenColumns.Add(x => x.Definition); HiddenColumns.Add(x => x.HasHeader); HiddenColumns.Add(x => x.HeaderRows); HiddenColumns.Add(x => x.ColumnWidths); HiddenColumns.Add(x => x.Script); } public Type EntityType { get; set; } public Guid EntityID { get; set; } public event OnImportItem OnImportItem; public event OnCustomiseImport OnCustomiseImport; public event ImportSaveEvent OnSave; public event ImportLoadEvent OnLoad; protected override void ShowHelp(string slug) { base.ShowHelp("Import_Data"); } private BitmapImage? ImportImage(CoreRow? arg) { return arg != null ? run : null; } private int[] ExtractColumnWidths(string widths) { if (string.IsNullOrWhiteSpace(widths)) return new[] { 1024 }; try { return widths.Split(',').Select(x => int.Parse(x)).ToArray(); } catch { return new[] { 1024 }; } } private bool ImportAction(CoreRow? arg) { if (arg != null) { var definition = ImportFactory.Definitions.FirstOrDefault(x => x.Description.Equals(arg.Get(c => c.ImporterDescription))); if (definition != null) { ScriptDocument? helper = null; try { var script = arg.Get(x => x.Script); if (!string.IsNullOrWhiteSpace(script)) { helper = new ScriptDocument(script); if (!helper.Compile()) { MessageBox.Show("Unable to Compile Import Helper Script!"); return false; } } } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } var fullfilename = arg.Get(x => x.FileName); var path = Path.GetDirectoryName(fullfilename); var extension = Path.GetExtension(fullfilename); var args = new CustomiseImportArgs { FileName = Path.GetFileNameWithoutExtension(fullfilename) }; OnCustomiseImport?.Invoke(this, args); var filename = CoreUtils.SanitiseFileName(args.FileName); var dlg = new OpenFileDialog(); dlg.Filter = definition.Filter; dlg.FileName = Path.Combine(path, filename) + (extension.StartsWith(".") ? "" : ".") + extension; if (!string.IsNullOrWhiteSpace(dlg.FileName) && Directory.Exists(Path.GetDirectoryName(dlg.FileName))) dlg.InitialDirectory = Path.GetDirectoryName(dlg.FileName); if (dlg.ShowDialog() == true) { Progress.Show("Importing Data"); var importer = ImportFactory.Create(definition, EntityType); if (importer is IFixedWidthImporter) ((IFixedWidthImporter)importer).ColumnWidths = ExtractColumnWidths(arg.Get(x => x.ColumnWidths)); try { importer.HasHeader = arg.Get(x => x.HasHeader); } catch { importer.HasHeader = true; } try { importer.HeaderRow = Math.Max(1, arg.Get(x => x.HeaderRows)); } catch { importer.HeaderRow = 1; } importer.BeforeProcess += (sender, values) => { if (helper != null) return helper.Execute("Module", "BeforeProcess", new object[] { values }); return true; }; importer.AfterProcess += (sender, item, values) => { var bOK = true; if (helper != null) bOK = helper.Execute("Module", "AfterProcess", new[] { item, values }); bOK = !bOK || OnImportItem == null || OnImportItem.Invoke(item); return bOK; }; importer.OnSave += (sender, entity) => OnSave?.Invoke(sender, entity); importer.OnLoad += (sender, type, fields, id) => OnLoad(sender, type, fields, id); importer.OnNotify += (o, m) => { Progress.SetMessage(m); }; var settings = arg.Get(c => c.Definition); var mappings = Serialization.Deserialize>(settings); importer.Mappings.AddRange(mappings); using (var stream = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read)) { Progress.SetMessage("Opening File"); if (importer.Open(stream)) { if (importer.ReadHeader()) { var mismatches = mappings.Where(x => !string.IsNullOrWhiteSpace(x.Field) && !importer.Fields.Contains(x.Field) ).Select(x => x.Field).ToArray(); if (!mismatches.Any()) { var imported = importer.Import(); Progress.Close(); MessageBox.Show(string.Format("Imported {0} records!", imported)); var LogFile = Path.ChangeExtension(dlg.FileName, ".log"); File.AppendAllLines(LogFile, importer.Log.ToArray()); Process.Start(new ProcessStartInfo(LogFile) { UseShellExecute = true }); } else { Progress.Close(); MessageBox.Show("Import Mappings do not match file headers!\n\n- " + string.Join("\n- ", mismatches), "Import Failed"); } } else { Progress.Close(); MessageBox.Show("Unable to Read Headers from {0}", Path.GetFileName(dlg.FileName)); } } else { Progress.Close(); MessageBox.Show("Unable to Open {0}", Path.GetFileName(dlg.FileName)); } importer.Close(); } } } } return false; } private bool Importer_BeforeProcess(object sender, Dictionary values) { return true; //throw new NotImplementedException(); } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, Action action) { criteria.Add(new Filter(x => x.EntityName).IsEqualTo(EntityType.EntityName())); if (EntityID != Guid.Empty) criteria.Add(new Filter(x => x.EntityID).IsEqualTo(EntityID)); base.Reload(criteria, columns, ref sort, action); } protected override Importer CreateItem() { var result = base.CreateItem(); result.EntityName = EntityType.EntityName(); result.EntityID = EntityID; return result; } public override bool EditItems(Importer[] items, Func? PageDataHandler = null, bool PreloadPages = false) { if (items.Length != 1) { MessageBox.Show("Please select a single item to edit!"); return false; } var form = new DynamicImportForm(items[0]); if (form.ShowDialog() == true) { SaveItem(items[0]); return true; } return false; } } }