diff --git a/DiscImageChef.CommonTypes b/DiscImageChef.CommonTypes index e95d90a9..40ce44b1 160000 --- a/DiscImageChef.CommonTypes +++ b/DiscImageChef.CommonTypes @@ -1 +1 @@ -Subproject commit e95d90a9327686e6e84da25f531135abfc0af1c6 +Subproject commit 40ce44b1d4b9e66338c8715ab6c0f2660c33c634 diff --git a/DiscImageChef.Server/Areas/Admin/Controllers/ScsisController.cs b/DiscImageChef.Server/Areas/Admin/Controllers/ScsisController.cs index 34aaa235..1d049f21 100644 --- a/DiscImageChef.Server/Areas/Admin/Controllers/ScsisController.cs +++ b/DiscImageChef.Server/Areas/Admin/Controllers/ScsisController.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using DiscImageChef.CommonTypes.Metadata; @@ -5,6 +6,7 @@ using DiscImageChef.Server.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; namespace DiscImageChef.Server.Areas.Admin.Controllers { @@ -65,6 +67,88 @@ namespace DiscImageChef.Server.Areas.Admin.Controllers return RedirectToAction(nameof(Index)); } - bool ScsiExists(int id) => _context.Scsi.Any(e => e.Id == id); + public IActionResult Consolidate() + { + List hashes = _context.Scsi.Where(m => m.InquiryData != null). + Select(m => new IdHashModel(m.Id, Hash.Sha512(m.InquiryData))).ToList(); + + List dups = hashes.GroupBy(x => x.Hash).Where(g => g.Count() > 1). + Select(x => hashes.FirstOrDefault(y => y.Hash == x.Key)).ToList(); + + for(int i = 0; i < dups.Count; i++) + { + Scsi unique = _context.Scsi.First(a => a.Id == dups[i].Id); + + dups[i].Description = + $"{StringHandlers.CToString(unique.Inquiry?.VendorIdentification)} {StringHandlers.CToString(unique.Inquiry?.ProductIdentification)}"; + + dups[i].Duplicates = hashes.Where(h => h.Hash == dups[i].Hash).Skip(1).Select(x => x.Id).ToArray(); + } + + return View(new IdHashModelForView + { + List = dups, Json = JsonConvert.SerializeObject(dups) + }); + } + + [HttpPost, ActionName("Consolidate"), ValidateAntiForgeryToken] + public IActionResult ConsolidateConfirmed(string models) + { + IdHashModel[] duplicates; + + try + { + duplicates = JsonConvert.DeserializeObject(models); + } + catch(JsonSerializationException) + { + return BadRequest(); + } + + if(duplicates is null) + return BadRequest(); + + foreach(IdHashModel duplicate in duplicates) + { + Scsi master = _context.Scsi.FirstOrDefault(m => m.Id == duplicate.Id); + + if(master is null) + continue; + + foreach(int duplicateId in duplicate.Duplicates) + { + Scsi slave = _context.Scsi.FirstOrDefault(m => m.Id == duplicateId); + + if(slave is null) + continue; + + foreach(Device scsiDevice in _context.Devices.Where(d => d.SCSI.Id == duplicateId)) + { + scsiDevice.SCSI = master; + } + + foreach(UploadedReport scsiReport in _context.Reports.Where(d => d.SCSI.Id == duplicateId)) + { + scsiReport.SCSI = master; + } + + foreach(TestedMedia testedMedia in _context.TestedMedia.Where(d => d.ScsiId == duplicateId)) + { + testedMedia.ScsiId = duplicate.Id; + _context.Update(testedMedia); + } + + if(master.ReadCapabilities is null && + slave.ReadCapabilities != null) + master.ReadCapabilities = slave.ReadCapabilities; + + _context.Scsi.Remove(slave); + } + } + + _context.SaveChanges(); + + return RedirectToAction(nameof(Index)); + } } } \ No newline at end of file diff --git a/DiscImageChef.Server/Areas/Admin/Views/Scsis/Consolidate.cshtml b/DiscImageChef.Server/Areas/Admin/Views/Scsis/Consolidate.cshtml new file mode 100644 index 00000000..81ba55e0 --- /dev/null +++ b/DiscImageChef.Server/Areas/Admin/Views/Scsis/Consolidate.cshtml @@ -0,0 +1,31 @@ +@model IdHashModelForView + +@{ + ViewBag.Title = "Consolidate duplicate SCSIs"; + Layout = "_Layout"; +} +

Consolidate duplicate SCSIs

+
+ The following SCSI INQUIRY have duplicates. + + + + @foreach (var item in Model.List) + { + + + + } + +
+ @Html.DisplayFor(modelItem => item.Description) +
+
+
+ Do you want to remove the duplicates? +
+ + Back to List + +
+
\ No newline at end of file diff --git a/DiscImageChef.Server/Areas/Admin/Views/Scsis/Index.cshtml b/DiscImageChef.Server/Areas/Admin/Views/Scsis/Index.cshtml index 192b31d7..9dd03d87 100644 --- a/DiscImageChef.Server/Areas/Admin/Views/Scsis/Index.cshtml +++ b/DiscImageChef.Server/Areas/Admin/Views/Scsis/Index.cshtml @@ -34,6 +34,10 @@ // Copyright © 2011-2019 Natalia Portillo // ****************************************************************************/ } +SCSI INQUIRY responses +
+ Consolidate duplicates +