Record archive file sizes. Automatically create archive record after upload.
parent
f5b136720a
commit
98bf631a9a
|
@ -0,0 +1,40 @@
|
|||
using LANCommander.Data;
|
||||
using LANCommander.Data.Models;
|
||||
using LANCommander.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LANCommander.Controllers.Api
|
||||
{
|
||||
[Authorize(AuthenticationSchemes = "Bearer")]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ArchivesController : ControllerBase
|
||||
{
|
||||
private DatabaseContext Context;
|
||||
|
||||
public ArchivesController(DatabaseContext context)
|
||||
{
|
||||
Context = context;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Download(Guid id)
|
||||
{
|
||||
using (var repo = new Repository<Archive>(Context, HttpContext))
|
||||
{
|
||||
var archive = await repo.Find(id);
|
||||
|
||||
if (archive == null)
|
||||
return NotFound();
|
||||
|
||||
var filename = Path.Combine("Upload", archive.ObjectKey);
|
||||
|
||||
if (!System.IO.File.Exists(filename))
|
||||
return NotFound();
|
||||
|
||||
return File(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read), "application/octet-stream", $"{archive.Game.Title.SanitizeFilename()}.zip");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -103,34 +103,33 @@ namespace LANCommander.Controllers
|
|||
return RedirectToAction("Edit", "Games", new { id = gameId });
|
||||
}
|
||||
|
||||
public async Task<IActionResult> ValidateManifest(Guid id)
|
||||
public async Task<IActionResult> Validate(Guid id, Archive archive)
|
||||
{
|
||||
var path = Path.Combine("Upload", id.ToString());
|
||||
|
||||
string manifestContents = String.Empty;
|
||||
long compressedSize = 0;
|
||||
long uncompressedSize = 0;
|
||||
|
||||
if (!System.IO.File.Exists(path))
|
||||
return BadRequest("Specified object does not exist");
|
||||
|
||||
try
|
||||
{
|
||||
using (ZipArchive archive = ZipFile.OpenRead(path))
|
||||
using (ZipArchive zip = ZipFile.OpenRead(path))
|
||||
{
|
||||
var manifest = archive.Entries.FirstOrDefault(e => e.FullName == "_manifest.yml");
|
||||
var manifest = zip.Entries.FirstOrDefault(e => e.FullName == "_manifest.yml");
|
||||
|
||||
if (manifest == null)
|
||||
throw new FileNotFoundException("Manifest file not found. Add a _manifest.yml file to your archive and try again.");
|
||||
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
using (StreamReader sr = new StreamReader(manifest.Open()))
|
||||
{
|
||||
if (entry.FullName == "_manifest.yml")
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(entry.Open()))
|
||||
{
|
||||
manifestContents = await sr.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
manifestContents = await sr.ReadToEndAsync();
|
||||
}
|
||||
|
||||
compressedSize = zip.Entries.Sum(e => e.CompressedLength);
|
||||
uncompressedSize = zip.Entries.Sum(e => e.Length);
|
||||
}
|
||||
}
|
||||
catch (InvalidDataException ex)
|
||||
|
@ -163,7 +162,32 @@ namespace LANCommander.Controllers
|
|||
return BadRequest("The manifest file is invalid or corrupt.");
|
||||
}
|
||||
|
||||
return Ok();
|
||||
using (var repo = new Repository<Game>(Context, HttpContext))
|
||||
{
|
||||
var game = await repo.Find(archive.Game.Id);
|
||||
|
||||
if (game == null)
|
||||
return BadRequest("The related game is missing or corrupt.");
|
||||
|
||||
archive.Game = game;
|
||||
}
|
||||
|
||||
using (var repo = new Repository<Archive>(Context, HttpContext))
|
||||
{
|
||||
archive.Id = Guid.Empty;
|
||||
archive.CompressedSize = compressedSize;
|
||||
archive.UncompressedSize = uncompressedSize;
|
||||
archive.ObjectKey = id.ToString();
|
||||
|
||||
archive = await repo.Add(archive);
|
||||
await repo.SaveChanges();
|
||||
|
||||
return Json(new
|
||||
{
|
||||
Id = archive.Id,
|
||||
ObjectKey = archive.ObjectKey,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,5 +15,8 @@ namespace LANCommander.Data.Models
|
|||
public virtual Game Game { get; set; }
|
||||
|
||||
public virtual Archive? LastVersion { get; set; }
|
||||
|
||||
public long UncompressedSize { get; set; }
|
||||
public long CompressedSize { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,572 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using LANCommander.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LANCommander.Migrations
|
||||
{
|
||||
[DbContext(typeof(DatabaseContext))]
|
||||
[Migration("20230106065219_AddArchiveFileSizes")]
|
||||
partial class AddArchiveFileSizes
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.8");
|
||||
|
||||
modelBuilder.Entity("GameTag", b =>
|
||||
{
|
||||
b.Property<Guid>("GamesId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("TagsId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("GamesId", "TagsId");
|
||||
|
||||
b.HasIndex("TagsId");
|
||||
|
||||
b.ToTable("GameTag");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Archive", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Changelog")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("CompressedSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("GameId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("LastVersionId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ObjectKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("UncompressedSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Version")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("GameId");
|
||||
|
||||
b.HasIndex("LastVersionId");
|
||||
|
||||
b.HasIndex("UpdatedById");
|
||||
|
||||
b.ToTable("Archive");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Company", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("UpdatedById");
|
||||
|
||||
b.ToTable("Companies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Game", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("DeveloperId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DirectoryName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("PublisherId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("ReleasedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SortTitle")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("DeveloperId");
|
||||
|
||||
b.HasIndex("PublisherId");
|
||||
|
||||
b.HasIndex("UpdatedById");
|
||||
|
||||
b.ToTable("Games");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Role", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Tag", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.HasIndex("UpdatedById");
|
||||
|
||||
b.ToTable("Tags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("RefreshToken")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("RefreshTokenExpiration")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameTag", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.Game", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("GamesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.Tag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("TagsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Archive", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.Game", "Game")
|
||||
.WithMany("Archives")
|
||||
.HasForeignKey("GameId");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.Archive", "LastVersion")
|
||||
.WithMany()
|
||||
.HasForeignKey("LastVersionId");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "UpdatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedById");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("Game");
|
||||
|
||||
b.Navigation("LastVersion");
|
||||
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Company", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "UpdatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedById");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Game", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.Company", "Developer")
|
||||
.WithMany("DevelopedGames")
|
||||
.HasForeignKey("DeveloperId");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.Company", "Publisher")
|
||||
.WithMany("PublishedGames")
|
||||
.HasForeignKey("PublisherId");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "UpdatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedById");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("Developer");
|
||||
|
||||
b.Navigation("Publisher");
|
||||
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Tag", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", "CreatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedById");
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", "UpdatedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedById");
|
||||
|
||||
b.Navigation("CreatedBy");
|
||||
|
||||
b.Navigation("UpdatedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.Role", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.Role", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("LANCommander.Data.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("LANCommander.Data.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Company", b =>
|
||||
{
|
||||
b.Navigation("DevelopedGames");
|
||||
|
||||
b.Navigation("PublishedGames");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("LANCommander.Data.Models.Game", b =>
|
||||
{
|
||||
b.Navigation("Archives");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LANCommander.Migrations
|
||||
{
|
||||
public partial class AddArchiveFileSizes : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "CompressedSize",
|
||||
table: "Archive",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "UncompressedSize",
|
||||
table: "Archive",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CompressedSize",
|
||||
table: "Archive");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UncompressedSize",
|
||||
table: "Archive");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,6 +41,9 @@ namespace LANCommander.Migrations
|
|||
b.Property<string>("Changelog")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("CompressedSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("CreatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -57,6 +60,9 @@ namespace LANCommander.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("UncompressedSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("UpdatedById")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" asp-for="Game.Id" />
|
||||
<input type="hidden" asp-for="LastVersion.Id" />
|
||||
<input type="hidden" asp-for="ObjectKey" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -62,7 +64,6 @@
|
|||
<div class="d-flex">
|
||||
<a asp-action="Edit" asp-controller="Games" asp-route-id="@Model.Game.Id" class="btn btn-link">Cancel</a>
|
||||
<button class="btn btn-primary" id="UploadButton">Upload</button>
|
||||
<input type="submit" value="Save" id="SaveButton" class="btn btn-primary" style="display: none;" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
@ -90,14 +91,11 @@
|
|||
.addClass('progress-bar-striped')
|
||||
.addClass('progress-bar-animated')
|
||||
.text('0%');
|
||||
|
||||
$('#UploadButton').show();
|
||||
$('#SaveButton').hide();
|
||||
};
|
||||
|
||||
uploader.OnComplete = (key) => {
|
||||
uploader.OnComplete = (id, key) => {
|
||||
$('#Id').val(id);
|
||||
$('#ObjectKey').val(key);
|
||||
$('fieldset').prop('disabled', false);
|
||||
$('.progress-bar')
|
||||
.css('width', '100%')
|
||||
.removeClass('progress-bar-striped')
|
||||
|
@ -105,8 +103,9 @@
|
|||
.addClass('bg-success')
|
||||
.text('Upload Complete!');
|
||||
|
||||
$('#UploadButton').hide();
|
||||
$('#SaveButton').show();
|
||||
setTimeout(() => {
|
||||
window.location.href = '@Url.Action("Edit", "Games", new { id = Model.Game.Id })';
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
uploader.OnProgress = (percent) => {
|
||||
|
@ -123,9 +122,6 @@
|
|||
.removeClass('progress-bar-animated')
|
||||
.addClass('bg-danger')
|
||||
.text('Upload Error!');
|
||||
|
||||
$('#UploadButton').show();
|
||||
$('#SaveButton').hide();
|
||||
};
|
||||
</script>
|
||||
}
|
||||
|
|
|
@ -18,12 +18,16 @@ class Uploader {
|
|||
constructor() {
|
||||
this.InitRoute = "/Upload/Init";
|
||||
this.ChunkRoute = "/Upload/Chunk";
|
||||
this.ValidateManifestRoute = "/Archives/ValidateManifest";
|
||||
this.ValidateRoute = "/Archives/Validate";
|
||||
this.MaxChunkSize = 1024 * 1024 * 25;
|
||||
}
|
||||
Init(fileInputId, uploadButtonId) {
|
||||
this.FileInput = document.getElementById(fileInputId);
|
||||
this.UploadButton = document.getElementById(uploadButtonId);
|
||||
this.FileInput = document.getElementById("File");
|
||||
this.UploadButton = document.getElementById("UploadButton");
|
||||
this.VersionInput = document.getElementById("Version");
|
||||
this.ChangelogTextArea = document.getElementById("Changelog");
|
||||
this.LastVersionIdInput = document.getElementById("LastVersion_Id");
|
||||
this.GameIdInput = document.getElementById("Game_Id");
|
||||
this.ParentForm = this.FileInput.closest("form");
|
||||
this.Chunks = [];
|
||||
this.UploadButton.onclick = (e) => __awaiter(this, void 0, void 0, function* () {
|
||||
|
@ -47,9 +51,9 @@ class Uploader {
|
|||
for (let chunk of this.Chunks) {
|
||||
yield this.UploadChunk(chunk);
|
||||
}
|
||||
var isValid = yield this.ValidateManifest();
|
||||
var isValid = yield this.Validate();
|
||||
if (isValid)
|
||||
this.OnComplete(this.Key);
|
||||
this.OnComplete(this.Id, this.Key);
|
||||
else
|
||||
this.OnError();
|
||||
}
|
||||
|
@ -77,15 +81,27 @@ class Uploader {
|
|||
this.OnProgress(chunk.Index / this.TotalChunks);
|
||||
});
|
||||
}
|
||||
ValidateManifest() {
|
||||
Validate() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let validationResponse = yield fetch(`${this.ValidateManifestRoute}/${this.Key}`, {
|
||||
method: "GET"
|
||||
let formData = new FormData();
|
||||
formData.append('Version', this.VersionInput.value);
|
||||
formData.append('Changelog', this.ChangelogTextArea.value);
|
||||
formData.append('Game.Id', this.GameIdInput.value);
|
||||
formData.append('ObjectKey', this.Key);
|
||||
let validationResponse = yield fetch(`${this.ValidateRoute}/${this.Key}`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
if (!validationResponse.ok) {
|
||||
ErrorModal.Show("Archive Invalid", yield validationResponse.text());
|
||||
return false;
|
||||
}
|
||||
let data = yield validationResponse.json();
|
||||
if (data == null || data.Id === "") {
|
||||
ErrorModal.Show("Upload Error", "Something interfered with the upload. Try again.");
|
||||
return false;
|
||||
}
|
||||
this.Id = data.Id;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"Upload.js","sourceRoot":"","sources":["Upload.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"Upload.js","sourceRoot":"","sources":["Upload.ts"],"names":[],"mappings":"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"}
|
|
@ -14,11 +14,18 @@ class Uploader {
|
|||
ParentForm: HTMLFormElement;
|
||||
FileInput: HTMLInputElement;
|
||||
UploadButton: HTMLButtonElement;
|
||||
VersionInput: HTMLInputElement;
|
||||
LastVersionIdInput: HTMLInputElement;
|
||||
GameIdInput: HTMLInputElement;
|
||||
ChangelogTextArea: HTMLTextAreaElement;
|
||||
ObjectKeyInput: HTMLInputElement;
|
||||
IdInput: HTMLInputElement;
|
||||
|
||||
File: File;
|
||||
|
||||
InitRoute: string = "/Upload/Init";
|
||||
ChunkRoute: string = "/Upload/Chunk";
|
||||
ValidateManifestRoute: string = "/Archives/ValidateManifest";
|
||||
ValidateRoute: string = "/Archives/Validate";
|
||||
|
||||
MaxChunkSize: number = 1024 * 1024 * 25;
|
||||
TotalChunks: number;
|
||||
|
@ -26,10 +33,15 @@ class Uploader {
|
|||
Chunks: Chunk[];
|
||||
|
||||
Key: string;
|
||||
Id: string;
|
||||
|
||||
Init(fileInputId: string, uploadButtonId: string) {
|
||||
this.FileInput = document.getElementById(fileInputId) as HTMLInputElement;
|
||||
this.UploadButton = document.getElementById(uploadButtonId) as HTMLButtonElement;
|
||||
this.FileInput = document.getElementById("File") as HTMLInputElement;
|
||||
this.UploadButton = document.getElementById("UploadButton") as HTMLButtonElement;
|
||||
this.VersionInput = document.getElementById("Version") as HTMLInputElement;
|
||||
this.ChangelogTextArea = document.getElementById("Changelog") as HTMLTextAreaElement;
|
||||
this.LastVersionIdInput = document.getElementById("LastVersion_Id") as HTMLInputElement;
|
||||
this.GameIdInput = document.getElementById("Game_Id") as HTMLInputElement;
|
||||
this.ParentForm = this.FileInput.closest("form");
|
||||
|
||||
this.Chunks = [];
|
||||
|
@ -63,10 +75,10 @@ class Uploader {
|
|||
await this.UploadChunk(chunk);
|
||||
}
|
||||
|
||||
var isValid = await this.ValidateManifest();
|
||||
var isValid = await this.Validate();
|
||||
|
||||
if (isValid)
|
||||
this.OnComplete(this.Key);
|
||||
this.OnComplete(this.Id, this.Key);
|
||||
else
|
||||
this.OnError();
|
||||
}
|
||||
|
@ -98,9 +110,17 @@ class Uploader {
|
|||
this.OnProgress(chunk.Index / this.TotalChunks);
|
||||
}
|
||||
|
||||
async ValidateManifest(): Promise<boolean> {
|
||||
let validationResponse = await fetch(`${this.ValidateManifestRoute}/${this.Key}`, {
|
||||
method: "GET"
|
||||
async Validate(): Promise<boolean> {
|
||||
let formData = new FormData();
|
||||
|
||||
formData.append('Version', this.VersionInput.value);
|
||||
formData.append('Changelog', this.ChangelogTextArea.value);
|
||||
formData.append('Game.Id', this.GameIdInput.value);
|
||||
formData.append('ObjectKey', this.Key);
|
||||
|
||||
let validationResponse = await fetch(`${this.ValidateRoute}/${this.Key}`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!validationResponse.ok) {
|
||||
|
@ -109,6 +129,16 @@ class Uploader {
|
|||
return false;
|
||||
}
|
||||
|
||||
let data = await validationResponse.json();
|
||||
|
||||
if (data == null || data.Id === "") {
|
||||
ErrorModal.Show("Upload Error", "Something interfered with the upload. Try again.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.Id = data.Id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -125,7 +155,7 @@ class Uploader {
|
|||
}
|
||||
|
||||
OnStart: () => void;
|
||||
OnComplete: (key: string) => void;
|
||||
OnComplete: (id: string, key: string) => void;
|
||||
OnProgress: (percent: number) => void;
|
||||
OnError: () => void;
|
||||
}
|
Loading…
Reference in New Issue