UserManager
+@inject AuthenticationStateProvider AuthenticationStateProvider
+@attribute [Authorize(Roles = "UberAdmin, Admin")]
+
+
+@L["Dump details"]
+
+
+@if (!_loaded)
+{
+ @L["Loading..."]
+
+ return;
+}
+
+
+
+ @L["Dumper"]
+
+
+
+ @L["Please enter a valid dumper."]
+
+
+
+
+ @if (_editing || _model.UserId != null)
+ {
+
+ @L["Dumper's user"]
+ @if (_editing)
+ {
+ @L["Unknown (user)"]
+ }
+ @if (!_editing ||
+ !_unknownUser)
+ {
+
+ }
+
+ }
+ @if (_editing || _model.DumpingGroup != null)
+ {
+
+ @L["Dumping group, or group whose guidelines where followed to make the dump"]
+ @if (_editing)
+ {
+ @L["Unknown (dumping group)"]
+ }
+ @if (!_editing ||
+ !_unknownDumpingGroup)
+ {
+
+
+
+ @L["Please enter a valid dumping group."]
+
+
+
+ }
+
+ }
+ @if (_editing || _model.DumpDate != null)
+ {
+
+ @L["Dump date"]
+ @if (_editing)
+ {
+ @L["Unknown (dump date)"]
+ }
+ @if (!_editing || !_unknownDumpDate)
+ {
+
+
+
+ @L["Please enter a valid dump date."]
+
+
+
+ }
+
+ }
+
+ @L["Media"]
+
+
+@{
+ // TODO: Dump hardware
+}
+
+
+ @if (!_editing)
+ {
+
+ }
+ else
+ {
+
+
+ }
+
@L["Back to list"]
+
diff --git a/Marechai/Pages/Admin/Details/Dump.razor.cs b/Marechai/Pages/Admin/Details/Dump.razor.cs
new file mode 100644
index 00000000..a35de8cb
--- /dev/null
+++ b/Marechai/Pages/Admin/Details/Dump.razor.cs
@@ -0,0 +1,159 @@
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Blazorise;
+using Marechai.Database.Models;
+using Marechai.Shared;
+using Marechai.ViewModels;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Authorization;
+
+namespace Marechai.Pages.Admin.Details
+{
+ public partial class Dump
+ {
+ AuthenticationState _authState;
+ bool _creating;
+ bool _editing;
+ bool _loaded;
+ List _medias;
+ DumpViewModel _model;
+ bool _unknownDumpDate;
+ bool _unknownDumpingGroup;
+ bool _unknownUser;
+ List _users;
+
+ [Parameter]
+ public ulong Id { get; set; }
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if(_loaded)
+ return;
+
+ _loaded = true;
+
+ _creating = NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant().
+ StartsWith("admin/dumps/create", StringComparison.InvariantCulture);
+
+ if(Id <= 0 &&
+ !_creating)
+ return;
+
+ _medias = await MediaService.GetTitlesAsync();
+ _model = _creating ? new DumpViewModel() : await Service.GetAsync(Id);
+ _authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
+
+ _users = UserManager.Users.Select(u => new ApplicationUser
+ {
+ Id = u.Id,
+ UserName = u.UserName
+ }).ToList();
+
+ _editing = _creating || NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant().
+ StartsWith("admin/dumps/edit/",
+ StringComparison.InvariantCulture);
+
+ if(_editing)
+ SetCheckboxes();
+
+ StateHasChanged();
+ }
+
+ void SetCheckboxes()
+ {
+ _unknownUser = string.IsNullOrWhiteSpace(_model.UserId);
+ _unknownDumpingGroup = string.IsNullOrWhiteSpace(_model.DumpingGroup);
+ _unknownDumpDate = !_model.DumpDate.HasValue;
+ }
+
+ void OnEditClicked()
+ {
+ _editing = true;
+ SetCheckboxes();
+ StateHasChanged();
+ }
+
+ async void OnCancelClicked()
+ {
+ _editing = false;
+
+ if(_creating)
+ {
+ NavigationManager.ToBaseRelativePath("admin/dumps");
+
+ return;
+ }
+
+ _model = await Service.GetAsync(Id);
+ SetCheckboxes();
+ StateHasChanged();
+ }
+
+ async void OnSaveClicked()
+ {
+ if(_unknownUser)
+ _model.UserId = null;
+ else if(string.IsNullOrWhiteSpace(_model.UserId))
+ return;
+
+ if(_unknownDumpingGroup)
+ _model.DumpingGroup = null;
+ else if(string.IsNullOrWhiteSpace(_model.DumpingGroup))
+ return;
+
+ if(_unknownDumpDate)
+ _model.DumpDate = null;
+ else if(_model.DumpDate?.Date >= DateTime.UtcNow.Date)
+ return;
+
+ if(string.IsNullOrWhiteSpace(_model.Dumper))
+ return;
+
+ if(_creating)
+ Id = await Service.CreateAsync(_model, (await UserManager.GetUserAsync(_authState.User)).Id);
+ else
+ await Service.UpdateAsync(_model, (await UserManager.GetUserAsync(_authState.User)).Id);
+
+ _editing = false;
+ _creating = false;
+ _model = await Service.GetAsync(Id);
+ SetCheckboxes();
+ StateHasChanged();
+ }
+
+ void ValidateDumper(ValidatorEventArgs e) =>
+ Validators.ValidateString(e, L["Dumper must be smaller than 256 characters."], 256);
+
+ void ValidateDumpingGroup(ValidatorEventArgs e) =>
+ Validators.ValidateString(e, L["Dumping group must be smaller than 256 characters."], 256);
+
+ void ValidateDumpDate(ValidatorEventArgs e) => Validators.ValidateDate(e);
+ }
+}
\ No newline at end of file
diff --git a/Marechai/Pages/Admin/Dumps.razor b/Marechai/Pages/Admin/Dumps.razor
new file mode 100644
index 00000000..0ab35985
--- /dev/null
+++ b/Marechai/Pages/Admin/Dumps.razor
@@ -0,0 +1,110 @@
+@{
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+}
+
+@page "/admin/dumps"
+@using Marechai.Database.Models
+@inherits OwningComponentBase
+@inject IStringLocalizer L
+@inject Microsoft.AspNetCore.Identity.UserManager UserManager
+@inject AuthenticationStateProvider AuthenticationStateProvider
+@attribute [Authorize(Roles = "UberAdmin, Admin")]
+@L["Dumps"]
+@if (_dumps is null)
+{
+ @L["Loading..."]
+
+ return;
+}
+
+ @L["Create new"]
+
+
+
+
+ |
+ @L["Dumper"]
+ |
+
+ @L["Dumping group"]
+ |
+
+ @L["Dump date"]
+ |
+
+ @L["Media title"]
+ |
+
+ @L["Username"]
+ |
+ |
+
+
+
+ @foreach (var item in _dumps)
+ {
+
+ |
+ @item.Dumper
+ |
+
+ @item.DumpingGroup
+ |
+
+ @item.DumpDate
+ |
+
+ @item.MediaTitle
+ |
+
+ @item.UserName
+ |
+
+ @L["Details"]
+ @L["Edit"]
+
+ |
+
+ }
+
+
+
+
+
+
+
+ @L["Delete dump"]
+
+
+
+ @string.Format(@L["Are you sure you want to delete the dump made by {0} on {1} for media titled {2}?"], _currentDump?.Dumper, _currentDump?.DumpDate.ToString() ?? L["Unknown (dump date)"], _currentDump?.MediaTitle)
+
+
+
+
+
+
+
diff --git a/Marechai/Pages/Admin/Dumps.razor.cs b/Marechai/Pages/Admin/Dumps.razor.cs
new file mode 100644
index 00000000..ff9b2c0b
--- /dev/null
+++ b/Marechai/Pages/Admin/Dumps.razor.cs
@@ -0,0 +1,88 @@
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Blazorise;
+using Marechai.ViewModels;
+using Microsoft.AspNetCore.Components.Authorization;
+
+namespace Marechai.Pages.Admin
+{
+ public partial class Dumps
+ {
+ DumpViewModel _currentDump;
+ bool _deleteInProgress;
+ List _dumps;
+ Modal _frmDelete;
+ bool _loaded;
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if(_loaded)
+ return;
+
+ _dumps = await Service.GetAsync();
+ _loaded = true;
+ StateHasChanged();
+ }
+
+ void ShowModal(ulong itemId)
+ {
+ _currentDump = _dumps.FirstOrDefault(n => n.Id == itemId);
+ _frmDelete.Show();
+ }
+
+ void HideModal() => _frmDelete.Hide();
+
+ async void ConfirmDelete()
+ {
+ if(_currentDump is null)
+ return;
+
+ _deleteInProgress = true;
+ _dumps = null;
+ AuthenticationState authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
+
+ // Yield thread to let UI to update
+ await Task.Yield();
+
+ await Service.DeleteAsync(_currentDump.Id, (await UserManager.GetUserAsync(authState.User)).Id);
+ _dumps = await Service.GetAsync();
+
+ _deleteInProgress = false;
+ _frmDelete.Hide();
+
+ // Yield thread to let UI to update
+ await Task.Yield();
+
+ // Tell we finished loading
+ StateHasChanged();
+ }
+
+ void ModalClosing(ModalClosingEventArgs obj) => _currentDump = null;
+ }
+}
\ No newline at end of file
diff --git a/Marechai/Pages/Admin/Index.razor b/Marechai/Pages/Admin/Index.razor
index 06ea3c89..972ce8ee 100644
--- a/Marechai/Pages/Admin/Index.razor
+++ b/Marechai/Pages/Admin/Index.razor
@@ -111,3 +111,11 @@
+
+
@L["Administrative pages for media dumps"]
+
+
diff --git a/Marechai/Resources/Services/AdminService.en.resx b/Marechai/Resources/Services/AdminService.en.resx
index 3d02d4eb..c1097dc7 100644
--- a/Marechai/Resources/Services/AdminService.en.resx
+++ b/Marechai/Resources/Services/AdminService.en.resx
@@ -23,4 +23,10 @@
Currency pegging
+
+ Dumps
+
+
+ Administrative pages for media dumps
+
\ No newline at end of file
diff --git a/Marechai/Resources/Services/AdminService.es.resx b/Marechai/Resources/Services/AdminService.es.resx
index c5b98060..987f7ce6 100644
--- a/Marechai/Resources/Services/AdminService.es.resx
+++ b/Marechai/Resources/Services/AdminService.es.resx
@@ -222,4 +222,10 @@
Vinculación de divisa
+
+ Volcados
+
+
+ Páginas de administración de volcados
+
\ No newline at end of file
diff --git a/Marechai/Resources/Services/DumpsService.en.resx b/Marechai/Resources/Services/DumpsService.en.resx
new file mode 100644
index 00000000..81723015
--- /dev/null
+++ b/Marechai/Resources/Services/DumpsService.en.resx
@@ -0,0 +1,92 @@
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Dumps
+
+
+ Loading...
+
+
+ Create new
+
+
+ Dumper
+
+
+ Dumping group
+
+
+ Dump date
+
+
+ Media title
+
+
+ Username
+
+
+ Details
+
+
+ Edit
+
+
+ Delete
+
+
+ Delete dump
+
+
+ Are you sure you want to delete the dump made by {0} on {1} for media titled {2}?
+
+
+ Unknown
+
+
+ Cancel
+
+
+ Dump details
+
+
+ Please enter a valid dumper.
+
+
+ Dumper's user
+
+
+ Unknown
+
+
+ Dumping group, or group whose guidelines where followed to make the dump
+
+
+ Unknown
+
+
+ Please enter a valid dumping group.
+
+
+ Please enter a valid dump date.
+
+
+ Media
+
+
+ Save
+
+
+ Back to list
+
+
\ No newline at end of file
diff --git a/Marechai/Resources/Services/DumpsService.es.resx b/Marechai/Resources/Services/DumpsService.es.resx
new file mode 100644
index 00000000..c6cb52fe
--- /dev/null
+++ b/Marechai/Resources/Services/DumpsService.es.resx
@@ -0,0 +1,92 @@
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Volcados
+
+
+ Cargando...
+
+
+ Crear nuevo
+
+
+ Volcador(a)
+
+
+ Grupo de volcado
+
+
+ Fecha de volcado
+
+
+ Título del medio
+
+
+ Nombre de usuario/a
+
+
+ Detalles
+
+
+ Editar
+
+
+ Eliminar
+
+
+ Eliminar volcado
+
+
+ ¿Estás seguro de eliminar el volcado realizado por {0} el {1} para el medio titulado {2}?
+
+
+ Desconocida
+
+
+ Cancelar
+
+
+ Detalles del volcado
+
+
+ Por favor introduce un(a) volcador(a) válido/a.
+
+
+ Usuario/a del volcador(a)
+
+
+ Desconocido
+
+
+ Grupo de volcado, o grupo cuyas instrucciones se siguieron para realizar el volcado
+
+
+ Desconocido
+
+
+ Por favor introduce un grupo de volcado válido.
+
+
+ Por favor introduce una fecha de volcado válida.
+
+
+ Medio
+
+
+ Guardar
+
+
+ Volver a la lista
+
+
\ No newline at end of file
diff --git a/Marechai/Services/DumpsService.cs b/Marechai/Services/DumpsService.cs
new file mode 100644
index 00000000..0fcde4ae
--- /dev/null
+++ b/Marechai/Services/DumpsService.cs
@@ -0,0 +1,118 @@
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Marechai.Database.Models;
+using Marechai.ViewModels;
+using Microsoft.EntityFrameworkCore;
+
+namespace Marechai.Services
+{
+ public class DumpsService
+ {
+ readonly MarechaiContext _context;
+
+ public DumpsService(MarechaiContext context) => _context = context;
+
+ public async Task> GetAsync() => await _context.
+ Dumps.OrderBy(d => d.Dumper).
+ ThenBy(d => d.DumpingGroup).
+ ThenBy(b => b.Media.Title).ThenBy(d => d.DumpDate).
+ Select(d => new DumpViewModel
+ {
+ Id = d.Id,
+ Dumper = d.Dumper,
+ UserId = d.UserId,
+ DumpingGroup = d.DumpingGroup,
+ DumpDate = d.DumpDate,
+ UserName = d.User.UserName,
+ MediaId = d.MediaId,
+ MediaTitle = d.Media.Title,
+ MediaDumpId = d.MediaDumpId
+ }).ToListAsync();
+
+ public async Task GetAsync(ulong id) => await _context.Dumps.Where(d => d.Id == id).
+ Select(d => new DumpViewModel
+ {
+ Id = d.Id,
+ Dumper = d.Dumper,
+ UserId = d.User.Id,
+ DumpingGroup = d.DumpingGroup,
+ DumpDate = d.DumpDate,
+ UserName = d.User.UserName,
+ MediaId = d.MediaId,
+ MediaTitle = d.Media.Title,
+ MediaDumpId = d.MediaDumpId
+ }).FirstOrDefaultAsync();
+
+ public async Task UpdateAsync(DumpViewModel viewModel, string userId)
+ {
+ Dump model = await _context.Dumps.FindAsync(viewModel.Id);
+
+ if(model is null)
+ return;
+
+ model.Dumper = viewModel.Dumper;
+ model.UserId = viewModel.UserId;
+ model.DumpingGroup = viewModel.DumpingGroup;
+ model.DumpDate = viewModel.DumpDate;
+ model.MediaId = viewModel.MediaId;
+ model.MediaDumpId = viewModel.MediaDumpId;
+ await _context.SaveChangesWithUserAsync(userId);
+ }
+
+ public async Task CreateAsync(DumpViewModel viewModel, string userId)
+ {
+ var model = new Dump
+ {
+ Dumper = viewModel.Dumper,
+ UserId = viewModel.UserId,
+ DumpingGroup = viewModel.DumpingGroup,
+ DumpDate = viewModel.DumpDate,
+ MediaId = viewModel.MediaId,
+ MediaDumpId = viewModel.MediaDumpId
+ };
+
+ await _context.Dumps.AddAsync(model);
+ await _context.SaveChangesWithUserAsync(userId);
+
+ return model.Id;
+ }
+
+ public async Task DeleteAsync(ulong id, string userId)
+ {
+ Dump item = await _context.Dumps.FindAsync(id);
+
+ if(item is null)
+ return;
+
+ _context.Dumps.Remove(item);
+
+ await _context.SaveChangesWithUserAsync(userId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Marechai/Services/MediaService.cs b/Marechai/Services/MediaService.cs
new file mode 100644
index 00000000..b628eea0
--- /dev/null
+++ b/Marechai/Services/MediaService.cs
@@ -0,0 +1,200 @@
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Marechai.Database.Models;
+using Marechai.ViewModels;
+using Microsoft.EntityFrameworkCore;
+
+namespace Marechai.Services
+{
+ public class MediaService
+ {
+ readonly MarechaiContext _context;
+
+ public MediaService(MarechaiContext context) => _context = context;
+
+ public async Task> GetAsync() => await _context.
+ Media.OrderBy(d => d.Title).
+ Select(d => new MediaViewModel
+ {
+ Id = d.Id,
+ Title = d.Title,
+ Sequence = d.Sequence,
+ LastSequence = d.LastSequence,
+ Type = d.Type,
+ WriteOffset = d.WriteOffset,
+ Sides = d.Sides,
+ Layers = d.Layers,
+ Sessions = d.Sessions,
+ Tracks = d.Tracks,
+ Sectors = d.Sectors,
+ Size = d.Size,
+ CopyProtection = d.CopyProtection,
+ PartNumber = d.PartNumber,
+ SerialNumber = d.SerialNumber,
+ Barcode = d.Barcode,
+ CatalogueNumber = d.CatalogueNumber,
+ Manufacturer = d.Manufacturer,
+ Model = d.Model,
+ Revision = d.Revision,
+ Firmware = d.Firmware,
+ PhysicalBlockSize = d.PhysicalBlockSize,
+ LogicalBlockSize = d.LogicalBlockSize,
+ BlockSizes = d.BlockSizes.Object,
+ StorageInterface = d.StorageInterface,
+ TableOfContents = d.TableOfContents.Object
+ }).ToListAsync();
+
+ public async Task> GetTitlesAsync() => await _context.
+ Media.OrderBy(d => d.Title).
+ Select(d => new MediaViewModel
+ {
+ Id = d.Id,
+ Title = d.Title
+ }).ToListAsync();
+
+ public async Task GetAsync(ulong id) => await _context.Media.Where(d => d.Id == id).
+ Select(d => new MediaViewModel
+ {
+ Id = d.Id,
+ Title = d.Title,
+ Sequence = d.Sequence,
+ LastSequence = d.LastSequence,
+ Type = d.Type,
+ WriteOffset = d.WriteOffset,
+ Sides = d.Sides,
+ Layers = d.Layers,
+ Sessions = d.Sessions,
+ Tracks = d.Tracks,
+ Sectors = d.Sectors,
+ Size = d.Size,
+ CopyProtection = d.CopyProtection,
+ PartNumber = d.PartNumber,
+ SerialNumber = d.SerialNumber,
+ Barcode = d.Barcode,
+ CatalogueNumber = d.CatalogueNumber,
+ Manufacturer = d.Manufacturer,
+ Model = d.Model,
+ Revision = d.Revision,
+ Firmware = d.Firmware,
+ PhysicalBlockSize =
+ d.PhysicalBlockSize,
+ LogicalBlockSize =
+ d.LogicalBlockSize,
+ BlockSizes = d.BlockSizes.Object,
+ StorageInterface =
+ d.StorageInterface,
+ TableOfContents =
+ d.TableOfContents.Object
+ }).FirstOrDefaultAsync();
+
+ public async Task UpdateAsync(MediaViewModel viewModel, string userId)
+ {
+ Media model = await _context.Media.FindAsync(viewModel.Id);
+
+ if(model is null)
+ return;
+
+ model.Title = viewModel.Title;
+ model.Sequence = viewModel.Sequence;
+ model.LastSequence = viewModel.LastSequence;
+ model.Type = viewModel.Type;
+ model.WriteOffset = viewModel.WriteOffset;
+ model.Sides = viewModel.Sides;
+ model.Layers = viewModel.Layers;
+ model.Sessions = viewModel.Sessions;
+ model.Tracks = viewModel.Tracks;
+ model.Sectors = viewModel.Sectors;
+ model.Size = viewModel.Size;
+ model.CopyProtection = viewModel.CopyProtection;
+ model.PartNumber = viewModel.PartNumber;
+ model.SerialNumber = viewModel.SerialNumber;
+ model.Barcode = viewModel.Barcode;
+ model.CatalogueNumber = viewModel.CatalogueNumber;
+ model.Manufacturer = viewModel.Manufacturer;
+ model.Model = viewModel.Model;
+ model.Revision = viewModel.Revision;
+ model.Firmware = viewModel.Firmware;
+ model.PhysicalBlockSize = viewModel.PhysicalBlockSize;
+ model.LogicalBlockSize = viewModel.LogicalBlockSize;
+ model.BlockSizes = viewModel.BlockSizes;
+ model.StorageInterface = viewModel.StorageInterface;
+ model.TableOfContents = viewModel.TableOfContents;
+ await _context.SaveChangesWithUserAsync(userId);
+ }
+
+ public async Task CreateAsync(MediaViewModel viewModel, string userId)
+ {
+ var model = new Media
+ {
+ Title = viewModel.Title,
+ Sequence = viewModel.Sequence,
+ LastSequence = viewModel.LastSequence,
+ Type = viewModel.Type,
+ WriteOffset = viewModel.WriteOffset,
+ Sides = viewModel.Sides,
+ Layers = viewModel.Layers,
+ Sessions = viewModel.Sessions,
+ Tracks = viewModel.Tracks,
+ Sectors = viewModel.Sectors,
+ Size = viewModel.Size,
+ CopyProtection = viewModel.CopyProtection,
+ PartNumber = viewModel.PartNumber,
+ SerialNumber = viewModel.SerialNumber,
+ Barcode = viewModel.Barcode,
+ CatalogueNumber = viewModel.CatalogueNumber,
+ Manufacturer = viewModel.Manufacturer,
+ Model = viewModel.Model,
+ Revision = viewModel.Revision,
+ Firmware = viewModel.Firmware,
+ PhysicalBlockSize = viewModel.PhysicalBlockSize,
+ LogicalBlockSize = viewModel.LogicalBlockSize,
+ BlockSizes = viewModel.BlockSizes,
+ StorageInterface = viewModel.StorageInterface,
+ TableOfContents = viewModel.TableOfContents
+ };
+
+ await _context.Media.AddAsync(model);
+ await _context.SaveChangesWithUserAsync(userId);
+
+ return model.Id;
+ }
+
+ public async Task DeleteAsync(ulong id, string userId)
+ {
+ Media item = await _context.Media.FindAsync(id);
+
+ if(item is null)
+ return;
+
+ _context.Media.Remove(item);
+
+ await _context.SaveChangesWithUserAsync(userId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Marechai/Services/Register.cs b/Marechai/Services/Register.cs
index c2547438..2dd9592d 100644
--- a/Marechai/Services/Register.cs
+++ b/Marechai/Services/Register.cs
@@ -72,6 +72,8 @@ namespace Marechai.Services
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
}
}
}
\ No newline at end of file
diff --git a/Marechai/ViewModels/DumpViewModel.cs b/Marechai/ViewModels/DumpViewModel.cs
new file mode 100644
index 00000000..b00993d5
--- /dev/null
+++ b/Marechai/ViewModels/DumpViewModel.cs
@@ -0,0 +1,41 @@
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+
+using System;
+
+namespace Marechai.ViewModels
+{
+ public class DumpViewModel : BaseViewModel
+ {
+ public string Dumper { get; set; }
+ public string UserId { get; set; }
+ public string DumpingGroup { get; set; }
+ public DateTime? DumpDate { get; set; }
+ public string UserName { get; set; }
+ public ulong MediaId { get; set; }
+ public string MediaTitle { get; set; }
+ public ulong MediaDumpId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Marechai/ViewModels/MediaViewModel.cs b/Marechai/ViewModels/MediaViewModel.cs
new file mode 100644
index 00000000..452b7dd2
--- /dev/null
+++ b/Marechai/ViewModels/MediaViewModel.cs
@@ -0,0 +1,60 @@
+/******************************************************************************
+// MARECHAI: Master repository of computing history artifacts information
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2003-2020 Natalia Portillo
+*******************************************************************************/
+
+using Aaru.CommonTypes;
+using Marechai.Database;
+using Marechai.Database.Models;
+
+namespace Marechai.ViewModels
+{
+ public class MediaViewModel : BaseViewModel
+ {
+ public string Title { get; set; }
+ public ushort? Sequence { get; set; }
+ public ushort? LastSequence { get; set; }
+ public MediaType Type { get; set; }
+ public int? WriteOffset { get; set; }
+ public ushort? Sides { get; set; }
+ public ushort? Layers { get; set; }
+ public ushort? Sessions { get; set; }
+ public ushort? Tracks { get; set; }
+ public ulong Sectors { get; set; }
+ public ulong Size { get; set; }
+ public string CopyProtection { get; set; }
+ public string PartNumber { get; set; }
+ public string SerialNumber { get; set; }
+ public string Barcode { get; set; }
+ public string CatalogueNumber { get; set; }
+ public string Manufacturer { get; set; }
+ public string Model { get; set; }
+ public string Revision { get; set; }
+ public string Firmware { get; set; }
+ public int? PhysicalBlockSize { get; set; }
+ public int? LogicalBlockSize { get; set; }
+ public VariableBlockSize[] BlockSizes { get; set; }
+ public StorageInterface? StorageInterface { get; set; }
+ public OpticalDiscTrack[] TableOfContents { get; set; }
+ }
+}
\ No newline at end of file