mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Refactored Volume to have Name and Number (int) so that we can properly sort and still handle possible split volumes.
Refactored ScanLibrary into Library controller and updated it so it adds the new library to all admins.
This commit is contained in:
parent
d632e53f18
commit
9168e12483
@ -79,6 +79,8 @@ namespace API.Controllers
|
||||
_userRepository.Update(user);
|
||||
await _userRepository.SaveAllAsync();
|
||||
|
||||
_logger.LogInformation($"{user.UserName} logged in at {user.LastActive}");
|
||||
|
||||
return new UserDto
|
||||
{
|
||||
Username = user.UserName,
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs;
|
||||
using API.Entities;
|
||||
@ -36,6 +37,47 @@ namespace API.Controllers
|
||||
_seriesRepository = seriesRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Library. Upon library creation, adds new library to all Admin accounts.
|
||||
/// </summary>
|
||||
/// <param name="createLibraryDto"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpPost("create")]
|
||||
public async Task<ActionResult> AddLibrary(CreateLibraryDto createLibraryDto)
|
||||
{
|
||||
if (await _libraryRepository.LibraryExists(createLibraryDto.Name))
|
||||
{
|
||||
return BadRequest("Library name already exists. Please choose a unique name to the server.");
|
||||
}
|
||||
|
||||
var admins = (await _userRepository.GetAdminUsersAsync()).ToList();
|
||||
|
||||
var library = new Library
|
||||
{
|
||||
Name = createLibraryDto.Name,
|
||||
Type = createLibraryDto.Type,
|
||||
AppUsers = admins,
|
||||
Folders = createLibraryDto.Folders.Select(x => new FolderPath {Path = x}).ToList()
|
||||
};
|
||||
|
||||
foreach (var admin in admins)
|
||||
{
|
||||
// If user is null, then set it
|
||||
admin.Libraries ??= new List<Library>();
|
||||
admin.Libraries.Add(library);
|
||||
}
|
||||
|
||||
|
||||
if (await _userRepository.SaveAllAsync())
|
||||
{
|
||||
//TODO: Enqueue scan library task
|
||||
return Ok();
|
||||
}
|
||||
|
||||
return BadRequest("There was a critical issue. Please try again.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of directories for a given path. If path is empty, returns root drives.
|
||||
/// </summary>
|
||||
@ -92,6 +134,7 @@ namespace API.Controllers
|
||||
|
||||
// We have to send a json encoded Library (aka a DTO) to the Background Job thread.
|
||||
// Because we use EF, we have circular dependencies back to Library and it will crap out
|
||||
// TODO: Refactor this to use libraryId and move Library call in method.
|
||||
BackgroundJob.Enqueue(() => _directoryService.ScanLibrary(library));
|
||||
return Ok();
|
||||
}
|
||||
@ -106,7 +149,6 @@ namespace API.Controllers
|
||||
public async Task<ActionResult<IEnumerable<Series>>> GetSeriesForLibrary(int libraryId)
|
||||
{
|
||||
return Ok(await _seriesRepository.GetSeriesForLibraryIdAsync(libraryId));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -22,47 +22,6 @@ namespace API.Controllers
|
||||
_libraryRepository = libraryRepository;
|
||||
}
|
||||
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpPost("add-library")]
|
||||
public async Task<ActionResult> AddLibrary(CreateLibraryDto createLibraryDto)
|
||||
{
|
||||
// NOTE: I think we should move this into library controller because it gets added to all admins
|
||||
|
||||
var user = await _userRepository.GetUserByUsernameAsync(User.GetUsername());
|
||||
|
||||
if (user == null) return BadRequest("Could not validate user");
|
||||
|
||||
|
||||
if (await _libraryRepository.LibraryExists(createLibraryDto.Name))
|
||||
{
|
||||
return BadRequest("Library name already exists. Please choose a unique name to the server.");
|
||||
}
|
||||
|
||||
var library = new Library
|
||||
{
|
||||
Name = createLibraryDto.Name.ToLower(),
|
||||
Type = createLibraryDto.Type,
|
||||
AppUsers = new List<AppUser>() { user }
|
||||
};
|
||||
|
||||
library.Folders = createLibraryDto.Folders.Select(x => new FolderPath
|
||||
{
|
||||
Path = x,
|
||||
Library = library
|
||||
}).ToList();
|
||||
|
||||
user.Libraries ??= new List<Library>(); // If user is null, then set it
|
||||
|
||||
user.Libraries.Add(library);
|
||||
|
||||
if (await _userRepository.SaveAllAsync())
|
||||
{
|
||||
return Ok();
|
||||
}
|
||||
|
||||
return BadRequest("Not implemented");
|
||||
}
|
||||
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpDelete("delete-user")]
|
||||
public async Task<ActionResult> DeleteUser(string username)
|
||||
|
@ -5,7 +5,8 @@ namespace API.DTOs
|
||||
public class VolumeDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Number { get; set; }
|
||||
public int Number { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string CoverImage { get; set; }
|
||||
public ICollection<string> Files { get; set; }
|
||||
}
|
||||
|
512
API/Data/Migrations/20210102173326_VolumeNumberRefactor.Designer.cs
generated
Normal file
512
API/Data/Migrations/20210102173326_VolumeNumberRefactor.Designer.cs
generated
Normal file
@ -0,0 +1,512 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using API.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace API.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20210102173326_VolumeNumberRefactor")]
|
||||
partial class VolumeNumberRefactor
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "5.0.1");
|
||||
|
||||
modelBuilder.Entity("API.Entities.AppRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.AppUser", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastActive")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
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<uint>("RowVersion")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.AppUserRole", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("RoleId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.FolderPath", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("LibraryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LibraryId");
|
||||
|
||||
b.ToTable("FolderPath");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Library", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CoverImage")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Library");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.MangaFile", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FilePath")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("VolumeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("VolumeId");
|
||||
|
||||
b.ToTable("MangaFile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Series", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CoverImage")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("LibraryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("OriginalName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SortName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Summary")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LibraryId");
|
||||
|
||||
b.ToTable("Series");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Number")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SeriesId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SeriesId");
|
||||
|
||||
b.ToTable("Volume");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AppUserLibrary", b =>
|
||||
{
|
||||
b.Property<int>("AppUsersId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("LibrariesId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("AppUsersId", "LibrariesId");
|
||||
|
||||
b.HasIndex("LibrariesId");
|
||||
|
||||
b.ToTable("AppUserLibrary");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("RoleId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
|
||||
{
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.AppUserRole", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.AppRole", "Role")
|
||||
.WithMany("UserRoles")
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Entities.AppUser", "User")
|
||||
.WithMany("UserRoles")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Role");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.FolderPath", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.Library", "Library")
|
||||
.WithMany("Folders")
|
||||
.HasForeignKey("LibraryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Library");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.MangaFile", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.Volume", "Volume")
|
||||
.WithMany("Files")
|
||||
.HasForeignKey("VolumeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Volume");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Series", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.Library", "Library")
|
||||
.WithMany("Series")
|
||||
.HasForeignKey("LibraryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Library");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.Series", "Series")
|
||||
.WithMany("Volumes")
|
||||
.HasForeignKey("SeriesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Series");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AppUserLibrary", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("AppUsersId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Entities.Library", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("LibrariesId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.AppRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
|
||||
{
|
||||
b.HasOne("API.Entities.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.AppRole", b =>
|
||||
{
|
||||
b.Navigation("UserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.AppUser", b =>
|
||||
{
|
||||
b.Navigation("UserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Library", b =>
|
||||
{
|
||||
b.Navigation("Folders");
|
||||
|
||||
b.Navigation("Series");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Series", b =>
|
||||
{
|
||||
b.Navigation("Volumes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||
{
|
||||
b.Navigation("Files");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
41
API/Data/Migrations/20210102173326_VolumeNumberRefactor.cs
Normal file
41
API/Data/Migrations/20210102173326_VolumeNumberRefactor.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace API.Data.Migrations
|
||||
{
|
||||
public partial class VolumeNumberRefactor : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "Number",
|
||||
table: "Volume",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Volume",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Volume");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Number",
|
||||
table: "Volume",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER");
|
||||
}
|
||||
}
|
||||
}
|
@ -249,9 +249,12 @@ namespace API.Data.Migrations
|
||||
b.Property<DateTime>("LastModified")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Number")
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Number")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SeriesId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -50,6 +50,7 @@ namespace API.Data
|
||||
{
|
||||
return await _context.Series
|
||||
.Where(series => series.LibraryId == libraryId)
|
||||
.OrderBy(s => s.SortName)
|
||||
.ProjectTo<SeriesDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
@ -57,6 +58,7 @@ namespace API.Data
|
||||
{
|
||||
return await _context.Volume
|
||||
.Where(vol => vol.SeriesId == seriesId)
|
||||
.OrderBy(volume => volume.Number)
|
||||
.ProjectTo<VolumeDto>(_mapper.ConfigurationProvider).ToListAsync();
|
||||
}
|
||||
|
||||
@ -64,6 +66,7 @@ namespace API.Data
|
||||
{
|
||||
return _context.Volume
|
||||
.Where(vol => vol.SeriesId == seriesId)
|
||||
.OrderBy(vol => vol.Number)
|
||||
.ProjectTo<VolumeDto>(_mapper.ConfigurationProvider).ToList();
|
||||
}
|
||||
|
||||
@ -71,6 +74,7 @@ namespace API.Data
|
||||
{
|
||||
return _context.Volume
|
||||
.Where(vol => vol.SeriesId == seriesId)
|
||||
.OrderBy(vol => vol.Number)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.DTOs;
|
||||
using API.Entities;
|
||||
using API.Interfaces;
|
||||
@ -55,6 +56,11 @@ namespace API.Data
|
||||
.SingleOrDefaultAsync(x => x.UserName == username);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AppUser>> GetAdminUsersAsync()
|
||||
{
|
||||
return await _userManager.GetUsersInRoleAsync(PolicyConstants.AdminRole);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<MemberDto>> GetMembersAsync()
|
||||
{
|
||||
return await _userManager.Users
|
||||
|
@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Entities.Interfaces;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
|
||||
namespace API.Entities
|
||||
{
|
||||
public class AppUser : IdentityUser<int>
|
||||
public class AppUser : IdentityUser<int>, IHasConcurrencyToken
|
||||
{
|
||||
public DateTime Created { get; set; } = DateTime.Now;
|
||||
public DateTime LastActive { get; set; }
|
||||
public bool IsAdmin { get; set; }
|
||||
public ICollection<Library> Libraries { get; set; }
|
||||
|
||||
[ConcurrencyCheck]
|
||||
|
@ -7,7 +7,8 @@ namespace API.Entities
|
||||
public class Volume : IEntityDate
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int Number { get; set; }
|
||||
public ICollection<MangaFile> Files { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public DateTime LastModified { get; set; }
|
||||
|
@ -15,5 +15,6 @@ namespace API.Interfaces
|
||||
Task<IEnumerable<MemberDto>> GetMembersAsync();
|
||||
Task<MemberDto> GetMemberAsync(string username);
|
||||
public void Delete(AppUser user);
|
||||
Task<IEnumerable<AppUser>> GetAdminUsersAsync();
|
||||
}
|
||||
}
|
@ -151,7 +151,7 @@ namespace API.Services
|
||||
IList<Volume> existingVolumes = _seriesRepository.GetVolumes(series.Id).ToList();
|
||||
foreach (var info in infos)
|
||||
{
|
||||
var existingVolume = existingVolumes.SingleOrDefault(v => v.Number == info.Volumes);
|
||||
var existingVolume = existingVolumes.SingleOrDefault(v => v.Name == info.Volumes);
|
||||
if (existingVolume != null)
|
||||
{
|
||||
// Temp let's overwrite all files (we need to enhance to update files)
|
||||
@ -168,7 +168,8 @@ namespace API.Services
|
||||
{
|
||||
var vol = new Volume()
|
||||
{
|
||||
Number = info.Volumes,
|
||||
Name = info.Volumes,
|
||||
Number = Int32.Parse(info.Volumes),
|
||||
Files = new List<MangaFile>()
|
||||
{
|
||||
new MangaFile()
|
||||
|
Loading…
x
Reference in New Issue
Block a user