CSV Import command created

This commit is contained in:
Geoffroy BONNEVILLE
2020-06-05 19:08:29 +02:00
parent 1f04f941c2
commit 4e7aca5517
10 changed files with 78 additions and 51 deletions

View File

@@ -81,7 +81,6 @@
<Compile Include="Common\Interfaces\IDatabaseProxy.cs" /> <Compile Include="Common\Interfaces\IDatabaseProxy.cs" />
<Compile Include="Common\Interfaces\IEntityVm.cs" /> <Compile Include="Common\Interfaces\IEntityVm.cs" />
<Compile Include="Common\Interfaces\IFileProxy.cs" /> <Compile Include="Common\Interfaces\IFileProxy.cs" />
<Compile Include="Common\Interfaces\IImportFormat.cs" />
<Compile Include="Common\Interfaces\ICredentialsProxy.cs" /> <Compile Include="Common\Interfaces\ICredentialsProxy.cs" />
<Compile Include="Common\Interfaces\ILogger.cs" /> <Compile Include="Common\Interfaces\ILogger.cs" />
<Compile Include="Common\Interfaces\INotificationService.cs" /> <Compile Include="Common\Interfaces\INotificationService.cs" />
@@ -105,6 +104,8 @@
<Compile Include="Group\Queries\GetAllGroups\GetAllGroupsQuery.cs" /> <Compile Include="Group\Queries\GetAllGroups\GetAllGroupsQuery.cs" />
<Compile Include="Group\Queries\GetGroup\GetGroupQuery.cs" /> <Compile Include="Group\Queries\GetGroup\GetGroupQuery.cs" />
<Compile Include="Group\Queries\SearchEntries\SearchEntriesQuery.cs" /> <Compile Include="Group\Queries\SearchEntries\SearchEntriesQuery.cs" />
<Compile Include="Import\Commands\ImportFromCsv\ImportFromCsvCommand.cs" />
<Compile Include="Import\Commands\ImportFromCsv\ImportFromCsvCommandValidator.cs" />
<Compile Include="Parameters\Commands\SetCipher\SetCipherCommand.cs" /> <Compile Include="Parameters\Commands\SetCipher\SetCipherCommand.cs" />
<Compile Include="Parameters\Commands\SetCompression\SetCompressionCommand.cs" /> <Compile Include="Parameters\Commands\SetCompression\SetCompressionCommand.cs" />
<Compile Include="Parameters\Commands\SetHasRecycleBin\SetHasRecycleBinCommand.cs" /> <Compile Include="Parameters\Commands\SetHasRecycleBin\SetHasRecycleBinCommand.cs" />
@@ -119,7 +120,7 @@
<Compile Include="Parameters\Queries\GetKeyDerivations\GetKeyDerivationsQuery.cs" /> <Compile Include="Parameters\Queries\GetKeyDerivations\GetKeyDerivationsQuery.cs" />
<Compile Include="Database\Commands\CloseDatabase\CloseDatabaseCommand.cs" /> <Compile Include="Database\Commands\CloseDatabase\CloseDatabaseCommand.cs" />
<Compile Include="Database\Commands\CreateDatabase\CreateDatabaseCommand.cs" /> <Compile Include="Database\Commands\CreateDatabase\CreateDatabaseCommand.cs" />
<Compile Include="Database\Commands\CreateDatabase\CreateDatabaseQueryValidator.cs" /> <Compile Include="Database\Commands\CreateDatabase\CreateDatabaseCommandValidator.cs" />
<Compile Include="Database\Commands\SaveDatabase\SaveDatabaseCommand.cs" /> <Compile Include="Database\Commands\SaveDatabase\SaveDatabaseCommand.cs" />
<Compile Include="Database\Commands\UpdateCredentials\UpdateCredentialsCommand.cs" /> <Compile Include="Database\Commands\UpdateCredentials\UpdateCredentialsCommand.cs" />
<Compile Include="Database\Models\DatabaseVm.cs" /> <Compile Include="Database\Models\DatabaseVm.cs" />

View File

@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace ModernKeePass.Application.Common.Interfaces
{
public interface IImportFormat
{
List<Dictionary<string, string>> Import(IList<string> fileContents);
}
}

View File

@@ -2,9 +2,9 @@
namespace ModernKeePass.Application.Database.Commands.CreateDatabase namespace ModernKeePass.Application.Database.Commands.CreateDatabase
{ {
public class CreateDatabaseQueryValidator : AbstractValidator<CreateDatabaseCommand> public class CreateDatabaseCommandValidator : AbstractValidator<CreateDatabaseCommand>
{ {
public CreateDatabaseQueryValidator() public CreateDatabaseCommandValidator()
{ {
RuleFor(v => v.FilePath) RuleFor(v => v.FilePath)
.NotNull() .NotNull()

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using MediatR;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Domain.Enums;
using ModernKeePass.Domain.Exceptions;
namespace ModernKeePass.Application.Import.Commands.ImportFromCsv
{
public class ImportFromCsvCommand : IRequest
{
public string FilePath { get; set; }
public string DestinationGroupId { get; set; }
public bool HasHeaderRow { get; set; }
public char Delimiter { get; set; } = ';';
public Dictionary<int, string> FieldMappings { get; set; }
public class CreateDatabaseCommandHandler : IAsyncRequestHandler<ImportFromCsvCommand>
{
private readonly IDatabaseProxy _database;
private readonly IFileProxy _file;
public CreateDatabaseCommandHandler(IDatabaseProxy database, IFileProxy file)
{
_database = database;
_file = file;
}
public async Task Handle(ImportFromCsvCommand message)
{
if (!_database.IsOpen) throw new DatabaseClosedException();
var fileContents = await _file.ReadTextFile(message.FilePath);
for (var index = message.HasHeaderRow ? 1 : 0; index < fileContents.Count; index++)
{
var line = fileContents[index];
var fields = line.Split(message.Delimiter);
var entry = _database.CreateEntry(message.DestinationGroupId);
for (var i = 0; i < fields.Length; i++)
{
var fieldMapping = message.FieldMappings[i];
await _database.UpdateEntry(entry.Id, fieldMapping, fields[i], fieldMapping == EntryFieldName.Password);
}
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
using FluentValidation;
namespace ModernKeePass.Application.Import.Commands.ImportFromCsv
{
public class ImportFromCsvCommandValidator : AbstractValidator<ImportFromCsvCommand>
{
public ImportFromCsvCommandValidator()
{
RuleFor(v => v.FilePath)
.NotNull()
.NotEmpty();
RuleFor(v => v.DestinationGroupId)
.NotNull()
.NotEmpty();
}
}
}

View File

@@ -1,31 +0,0 @@
using System.Collections.Generic;
using ModernKeePass.Application.Common.Interfaces;
namespace ModernKeePass.Infrastructure.File
{
public class CsvImportFormat: IImportFormat
{
private const bool HasHeaderRow = true;
private const char Delimiter = ';';
private const char LineDelimiter = '\n';
public List<Dictionary<string, string>> Import(IList<string> fileContents)
{
var parsedResult = new List<Dictionary<string, string>>();
foreach (var line in fileContents)
{
var fields = line.Split(Delimiter);
var recordItem = new Dictionary<string, string>();
var i = 0;
foreach (var field in fields)
{
recordItem.Add(i.ToString(), field);
i++;
}
parsedResult.Add(recordItem);
}
return parsedResult;
}
}
}

View File

@@ -78,7 +78,6 @@
<ItemGroup> <ItemGroup>
<Compile Include="Common\MachineDateTime.cs" /> <Compile Include="Common\MachineDateTime.cs" />
<Compile Include="DependencyInjection.cs" /> <Compile Include="DependencyInjection.cs" />
<Compile Include="File\CsvImportFormat.cs" />
<Compile Include="KeePass\MappingProfiles.cs" /> <Compile Include="KeePass\MappingProfiles.cs" />
<Compile Include="KeePass\IconMapper.cs" /> <Compile Include="KeePass\IconMapper.cs" />
<Compile Include="KeePass\KeePassDatabaseSettingsProxy.cs" /> <Compile Include="KeePass\KeePassDatabaseSettingsProxy.cs" />

View File

@@ -1,5 +1,5 @@
<Page <Page
x:Class="ModernKeePass.Views.ImportExportPage" x:Class="ModernKeePass.Views.ImportPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

View File

@@ -5,9 +5,9 @@ namespace ModernKeePass.Views
/// <summary> /// <summary>
/// The import/export page. /// The import/export page.
/// </summary> /// </summary>
public sealed partial class ImportExportPage public sealed partial class ImportPage
{ {
public ImportExportPage() public ImportPage()
{ {
InitializeComponent(); InitializeComponent();
} }

View File

@@ -100,8 +100,8 @@
<DependentUpon>DonatePage.xaml</DependentUpon> <DependentUpon>DonatePage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" /> <Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
<Compile Include="Views\MainPageFrames\ImportExportPage.xaml.cs"> <Compile Include="Views\MainPageFrames\ImportPage.xaml.cs">
<DependentUpon>ImportExportPage.xaml</DependentUpon> <DependentUpon>ImportPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\SettingsPageFrames\SettingsHistoryPage.xaml.cs"> <Compile Include="Views\SettingsPageFrames\SettingsHistoryPage.xaml.cs">
<DependentUpon>SettingsHistoryPage.xaml</DependentUpon> <DependentUpon>SettingsHistoryPage.xaml</DependentUpon>
@@ -203,7 +203,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page> </Page>
<Page Include="Views\MainPageFrames\ImportExportPage.xaml"> <Page Include="Views\MainPageFrames\ImportPage.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>