diff --git a/LANCommander.Server.Services/Importers/ActionImporter.cs b/LANCommander.Server.Services/Importers/ActionImporter.cs index 6cbe12e2..41ba6306 100644 --- a/LANCommander.Server.Services/Importers/ActionImporter.cs +++ b/LANCommander.Server.Services/Importers/ActionImporter.cs @@ -24,6 +24,7 @@ public class ActionImporter( { var action = new Data.Models.Action { + Name = record.Name, Game = ImportContext.DataRecord as Data.Models.Game, Path = record.Path, WorkingDirectory = record.WorkingDirectory, diff --git a/LANCommander.Server.Services/Importers/CollectionImporter.cs b/LANCommander.Server.Services/Importers/CollectionImporter.cs index fad19ca6..f1ed6e9a 100644 --- a/LANCommander.Server.Services/Importers/CollectionImporter.cs +++ b/LANCommander.Server.Services/Importers/CollectionImporter.cs @@ -7,7 +7,8 @@ namespace LANCommander.Server.Services.Importers; public class CollectionImporter( IMapper mapper, - CollectionService collectionService) : BaseImporter + CollectionService collectionService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Collection record) { @@ -54,15 +55,19 @@ public class CollectionImporter( public override async Task UpdateAsync(Collection record) { var existing = await collectionService.Include(c => c.Games).FirstOrDefaultAsync(c => c.Name == record.Name); - + var game = ImportContext.DataRecord as Data.Models.Game; + try { if (existing.Games == null) existing.Games = new List(); - - existing.Games.Add(ImportContext.DataRecord as Data.Models.Game); - - existing = await collectionService.UpdateAsync(existing); + + if (!existing.Games.Any(g => g.Id == game.Id)) + { + existing.Games.Add(await gameService.GetAsync(game.Id)); + + existing = await collectionService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server.Services/Importers/DeveloperImporter.cs b/LANCommander.Server.Services/Importers/DeveloperImporter.cs index ba5d4906..ae6ae548 100644 --- a/LANCommander.Server.Services/Importers/DeveloperImporter.cs +++ b/LANCommander.Server.Services/Importers/DeveloperImporter.cs @@ -7,7 +7,8 @@ namespace LANCommander.Server.Services.Importers; public class DeveloperImporter( IMapper mapper, - CompanyService companyService) : BaseImporter + CompanyService companyService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Company record) { @@ -33,14 +34,16 @@ public class DeveloperImporter( public override async Task AddAsync(Company record) { - if (ImportContext.DataRecord is not Data.Models.Game game) + if (ImportContext.DataRecord is not Data.Models.Game) throw new ImportSkippedException(record, $"Cannot import developers for a {ImportContext.DataRecord.GetType().Name}"); try { + var game = ImportContext.DataRecord as Data.Models.Game; + var company = new Data.Models.Company { - DevelopedGames = new List() { game }, + DevelopedGames = [await gameService.GetAsync(game.Id)], Name = record.Name, }; @@ -56,19 +59,24 @@ public class DeveloperImporter( public override async Task UpdateAsync(Company record) { - if (ImportContext.DataRecord is not Data.Models.Game game) + if (ImportContext.DataRecord is not Data.Models.Game) throw new ImportSkippedException(record, $"Cannot import developers for a {ImportContext.DataRecord.GetType().Name}"); var existing = await companyService.Include(g => g.DevelopedGames).FirstOrDefaultAsync(c => c.Name == record.Name); try { + var game = ImportContext.DataRecord as Data.Models.Game; + if (existing.DevelopedGames == null) existing.DevelopedGames = new List(); + + if (!existing.DevelopedGames.Any(g => g.Id == game.Id)) + { + existing.DevelopedGames.Add(await gameService.GetAsync(game.Id)); - existing.DevelopedGames.Add(game); - - existing = await companyService.UpdateAsync(existing); + existing = await companyService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server.Services/Importers/EngineImporter.cs b/LANCommander.Server.Services/Importers/EngineImporter.cs index caf97f6a..02bb2c46 100644 --- a/LANCommander.Server.Services/Importers/EngineImporter.cs +++ b/LANCommander.Server.Services/Importers/EngineImporter.cs @@ -7,7 +7,8 @@ namespace LANCommander.Server.Services.Importers; public class EngineImporter( IMapper mapper, - EngineService engineService) : BaseImporter + EngineService engineService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Engine record) { @@ -54,15 +55,20 @@ public class EngineImporter( public override async Task UpdateAsync(Engine record) { var existing = await engineService.Include(g => g.Games).FirstOrDefaultAsync(c => c.Name == record.Name); - + var game = ImportContext.DataRecord as Data.Models.Game; + try { + if (existing.Games == null) existing.Games = new List(); - - existing.Games.Add(ImportContext.DataRecord as Data.Models.Game); - - existing = await engineService.UpdateAsync(existing); + + if (!existing.Games.Any(g => g.Id == game.Id)) + { + existing.Games.Add(await gameService.GetAsync(game.Id)); + + existing = await engineService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server.Services/Importers/GameImporter.cs b/LANCommander.Server.Services/Importers/GameImporter.cs index 21a26f3f..c52f0206 100644 --- a/LANCommander.Server.Services/Importers/GameImporter.cs +++ b/LANCommander.Server.Services/Importers/GameImporter.cs @@ -32,7 +32,26 @@ public class GameImporter( public override async Task AddAsync(Game record) { - var game = mapper.Map(record); + var game = new Data.Models.Game + { + Title = record.Title, + SortTitle = record.SortTitle, + Description = record.Description, + Notes = record.Notes, + ReleasedOn = record.ReleasedOn, + Singleplayer = record.Singleplayer, + Type = record.Type, + IGDBId = record.IGDBId, + CreatedOn = record.CreatedOn, + UpdatedOn = record.UpdatedOn, + DirectoryName = record.DirectoryName, + }; + + if (!String.IsNullOrWhiteSpace(record.CreatedBy)) + game.CreatedBy = await userService.GetAsync(record.CreatedBy); + + if (!String.IsNullOrWhiteSpace(record.UpdatedBy)) + game.UpdatedBy = await userService.GetAsync(record.UpdatedBy); try { @@ -58,10 +77,14 @@ public class GameImporter( existing.Singleplayer = record.Singleplayer; existing.Type = record.Type; existing.IGDBId = record.IGDBId; - existing.CreatedBy = await userService.GetAsync(record.CreatedBy); existing.CreatedOn = record.CreatedOn; - existing.UpdatedBy = await userService.GetAsync(record.UpdatedBy); existing.DirectoryName = record.DirectoryName; + + if (!String.IsNullOrWhiteSpace(record.CreatedBy)) + existing.CreatedBy = await userService.GetAsync(record.CreatedBy); + + if (!String.IsNullOrWhiteSpace(record.UpdatedBy)) + existing.UpdatedBy = await userService.GetAsync(record.UpdatedBy); existing = await gameService.UpdateAsync(existing); diff --git a/LANCommander.Server.Services/Importers/GenreImporter.cs b/LANCommander.Server.Services/Importers/GenreImporter.cs index b769527f..493b7e69 100644 --- a/LANCommander.Server.Services/Importers/GenreImporter.cs +++ b/LANCommander.Server.Services/Importers/GenreImporter.cs @@ -7,7 +7,8 @@ namespace LANCommander.Server.Services.Importers; public class GenreImporter( IMapper mapper, - GenreService genreService) : BaseImporter + GenreService genreService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Genre record) { @@ -54,15 +55,19 @@ public class GenreImporter( public override async Task UpdateAsync(Genre record) { var existing = await genreService.Include(g => g.Games).FirstOrDefaultAsync(c => c.Name == record.Name); - + var game = ImportContext.DataRecord as Data.Models.Game; + try { if (existing.Games == null) existing.Games = new List(); - - existing.Games.Add(ImportContext.DataRecord as Data.Models.Game); - - existing = await genreService.UpdateAsync(existing); + + if (!existing.Games.Any(g => g.Id == game.Id)) + { + existing.Games.Add(await gameService.GetAsync(game.Id)); + + existing = await genreService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server.Services/Importers/ImportContext.cs b/LANCommander.Server.Services/Importers/ImportContext.cs index 7a392349..59557462 100644 --- a/LANCommander.Server.Services/Importers/ImportContext.cs +++ b/LANCommander.Server.Services/Importers/ImportContext.cs @@ -145,7 +145,10 @@ public class ImportContext( importItemInfo.AddRange(await GetImportItemInfoAsync(gameManifest.Collections, Collections).ToListAsync()); importItemInfo.AddRange(await GetImportItemInfoAsync(gameManifest.CustomFields, CustomFields).ToListAsync()); importItemInfo.AddRange(await GetImportItemInfoAsync(gameManifest.Developers, Developers).ToListAsync()); - importItemInfo.AddRange(await GetImportItemInfoAsync([gameManifest.Engine], Engines).ToListAsync()); + + if (gameManifest.Engine != null) + importItemInfo.AddRange(await GetImportItemInfoAsync([gameManifest.Engine], Engines).ToListAsync()); + importItemInfo.AddRange(await GetImportItemInfoAsync(gameManifest.Genres, Genres).ToListAsync()); importItemInfo.AddRange(await GetImportItemInfoAsync(gameManifest.Keys, Keys).ToListAsync()); importItemInfo.AddRange(await GetImportItemInfoAsync(gameManifest.Media, Media).ToListAsync()); @@ -350,7 +353,7 @@ public class ImportContext( if (importRecordFlags.HasFlag(ImportRecordFlags.Developers)) await AddToImportQueueAsync(ImportRecordFlags.Developers, gameManifest.Developers); - if (importRecordFlags.HasFlag(ImportRecordFlags.Engine)) + if (importRecordFlags.HasFlag(ImportRecordFlags.Engine) && gameManifest.Engine != null) await AddToImportQueueAsync(ImportRecordFlags.Engine, [gameManifest.Engine]); if (importRecordFlags.HasFlag(ImportRecordFlags.Genres)) @@ -377,13 +380,13 @@ public class ImportContext( if (importRecordFlags.HasFlag(ImportRecordFlags.Saves)) await AddToImportQueueAsync(ImportRecordFlags.Saves, gameManifest.Saves); - if (importRecordFlags.HasFlag(ImportRecordFlags.Scripts)) + if (importRecordFlags.HasFlag(ImportRecordFlags.SavePaths)) await AddToImportQueueAsync(ImportRecordFlags.SavePaths, gameManifest.SavePaths); if (importRecordFlags.HasFlag(ImportRecordFlags.Scripts)) await AddToImportQueueAsync(ImportRecordFlags.Scripts, gameManifest.Scripts); - if (importRecordFlags.HasFlag(ImportRecordFlags.Archives)) + if (importRecordFlags.HasFlag(ImportRecordFlags.Tags)) await AddToImportQueueAsync(ImportRecordFlags.Tags, gameManifest.Tags); } diff --git a/LANCommander.Server.Services/Importers/PlatformImporter.cs b/LANCommander.Server.Services/Importers/PlatformImporter.cs index ed4a2047..0b2fa718 100644 --- a/LANCommander.Server.Services/Importers/PlatformImporter.cs +++ b/LANCommander.Server.Services/Importers/PlatformImporter.cs @@ -7,7 +7,8 @@ namespace LANCommander.Server.Services.Importers; public class PlatformImporter( IMapper mapper, - PlatformService platformService) : BaseImporter + PlatformService platformService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Platform record) { @@ -54,15 +55,19 @@ public class PlatformImporter( public override async Task UpdateAsync(Platform record) { var existing = await platformService.Include(p => p.Games).FirstOrDefaultAsync(c => c.Name == record.Name); - + var game = ImportContext.DataRecord as Data.Models.Game; + try { if (existing.Games == null) existing.Games = new List(); - - existing.Games.Add(ImportContext.DataRecord as Data.Models.Game); - - existing = await platformService.UpdateAsync(existing); + + if (!existing.Games.Any(g => g.Id == game.Id)) + { + existing.Games.Add(await gameService.GetAsync(game.Id)); + + existing = await platformService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server.Services/Importers/PublisherImporter.cs b/LANCommander.Server.Services/Importers/PublisherImporter.cs index 4f3beeb0..09e6c240 100644 --- a/LANCommander.Server.Services/Importers/PublisherImporter.cs +++ b/LANCommander.Server.Services/Importers/PublisherImporter.cs @@ -7,7 +7,8 @@ namespace LANCommander.Server.Services.Importers; public class PublisherImporter( IMapper mapper, - CompanyService companyService) : BaseImporter + CompanyService companyService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Company record) { @@ -35,9 +36,11 @@ public class PublisherImporter( { try { + var game = ImportContext.DataRecord as Data.Models.Game; + var company = new Data.Models.Company { - PublishedGames = new List() { ImportContext.DataRecord as Data.Models.Game }, + PublishedGames = [await gameService.GetAsync(game.Id)], Name = record.Name, }; @@ -54,15 +57,19 @@ public class PublisherImporter( public override async Task UpdateAsync(Company record) { var existing = await companyService.Include(g => g.PublishedGames).FirstOrDefaultAsync(c => c.Name == record.Name); + var game = ImportContext.DataRecord as Data.Models.Game; try { if (existing.PublishedGames == null) existing.PublishedGames = new List(); - existing.PublishedGames.Add(ImportContext.DataRecord as Data.Models.Game); + if (!existing.PublishedGames.Any(g => g.Id == game.Id)) + { + existing.PublishedGames.Add(await gameService.GetAsync(game.Id)); - existing = await companyService.UpdateAsync(existing); + existing = await companyService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server.Services/Importers/TagImporter.cs b/LANCommander.Server.Services/Importers/TagImporter.cs index 18d404a2..423d69cc 100644 --- a/LANCommander.Server.Services/Importers/TagImporter.cs +++ b/LANCommander.Server.Services/Importers/TagImporter.cs @@ -6,7 +6,8 @@ namespace LANCommander.Server.Services.Importers; public class TagImporter( IMapper mapper, - TagService tagService) : BaseImporter + TagService tagService, + GameService gameService) : BaseImporter { public override async Task GetImportInfoAsync(Tag record) { @@ -53,15 +54,19 @@ public class TagImporter( public override async Task UpdateAsync(Tag record) { var existing = await tagService.Include(t => t.Games).FirstOrDefaultAsync(c => c.Name == record.Name); - + var game = ImportContext.DataRecord as Data.Models.Game; + try { if (existing.Games == null) existing.Games = new List(); - - existing.Games.Add(ImportContext.DataRecord as Data.Models.Game); - - existing = await tagService.UpdateAsync(existing); + + if (!existing.Games.Any(g => g.Id == game.Id)) + { + existing.Games.Add(await gameService.GetAsync(game.Id)); + + existing = await tagService.UpdateAsync(existing); + } return existing; } diff --git a/LANCommander.Server/UI/Components/ImportUploadDialog.razor b/LANCommander.Server/UI/Components/ImportUploadDialog.razor index ba9dc8b3..e7ea9e55 100644 --- a/LANCommander.Server/UI/Components/ImportUploadDialog.razor +++ b/LANCommander.Server/UI/Components/ImportUploadDialog.razor @@ -8,39 +8,88 @@ @inject IMessageService MessageService @inject ILogger Logger - - - -

Drag and Drop

-

or

-

- -

-
- @Options.Hint -
+@if (!Uploaded) +{ + + + +

Drag and Drop

+

or

+

+ +

+
+ @Options.Hint +
- -
+ +
+ + + + Use Local File + + + + +} +else +{ + + @foreach (var group in ImportItems.GroupBy(i => i.Flag)) + { + + + + + @group.Key - - - Use Local File - - - - + @{ + var size = group.Sum(i => i.Size); + + if (size > 0) + { + + } + } + + + + + + + + @item.Name + + @if (item.Size > 0) + { + + } + + + + + + + } + + + + + + +} @code { IBrowserFile File; @@ -52,6 +101,7 @@ string RootPath = Path.GetPathRoot(Directory.GetCurrentDirectory()); + bool Uploaded = false; bool IsValid = false; string Filename; string Status; @@ -98,8 +148,22 @@ .Where(f => f.Value) .Aggregate(ImportRecordFlags.None, (cur, f) => cur | f.Key); - await ImportContext.PrepareImportQueueAsync(flags); - await ImportContext.ImportQueueAsync(); + try + { + await ImportContext.PrepareImportQueueAsync(flags); + await ImportContext.ImportQueueAsync(); + + MessageService.Success("Game successfully imported!"); + } + catch (Exception ex) + { + MessageService.Error("Game could not be imported!"); + Logger?.LogError(ex, "An unknown error occurred while trying to import"); + } + + await Clear(); + ImportContext.Dispose(); + await CloseFeedbackAsync(); } async Task Clear() @@ -140,6 +204,8 @@ var archivePath = await ArchiveService.GetArchiveFileLocationAsync(objectKey.ToString()); ImportItems = await ImportContext.InitializeImportAsync(archivePath); + + Uploaded = true; await InvokeAsync(StateHasChanged); } @@ -178,6 +244,8 @@ try { ImportItems = await ImportContext.InitializeImportAsync(path); + + Uploaded = true; await InvokeAsync(StateHasChanged); }