mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-06-03 13:44:31 -04:00
Implemented the ability to correct a match from UI and further scans will show that new Series name.
This commit is contained in:
parent
5186508aff
commit
c6e1fec9f2
@ -51,8 +51,9 @@ namespace API.Controllers
|
|||||||
|
|
||||||
result = await _userManager.AddPasswordAsync(user, resetPasswordDto.Password);
|
result = await _userManager.AddPasswordAsync(user, resetPasswordDto.Password);
|
||||||
if (!result.Succeeded) return BadRequest("Unable to update password");
|
if (!result.Succeeded) return BadRequest("Unable to update password");
|
||||||
|
|
||||||
return Ok($"{resetPasswordDto.UserName}'s Password has been reset.");
|
_logger.LogInformation("{User}'s Password has been reset", resetPasswordDto.UserName);
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("register")]
|
[HttpPost("register")]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Data;
|
using API.Data;
|
||||||
@ -42,9 +43,32 @@ namespace API.Controllers
|
|||||||
file.Page = page;
|
file.Page = page;
|
||||||
file.MangaFileName = mangaFile.FilePath;
|
file.MangaFileName = mangaFile.FilePath;
|
||||||
file.NeedsSplitting = file.Width > file.Height;
|
file.NeedsSplitting = file.Width > file.Height;
|
||||||
|
|
||||||
|
// TODO: Validate if sending page whole (not base64 encoded) fixes Tablet issue
|
||||||
|
//Response.Headers.Add("Transfer-Encoding", "gzip");
|
||||||
|
|
||||||
return Ok(file);
|
return Ok(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("image2")]
|
||||||
|
public async Task<ActionResult> GetImage2(int chapterId, int page)
|
||||||
|
{
|
||||||
|
// Temp let's iterate the directory each call to get next image
|
||||||
|
var chapter = await _cacheService.Ensure(chapterId);
|
||||||
|
|
||||||
|
if (chapter == null) return BadRequest("There was an issue finding image file for reading");
|
||||||
|
|
||||||
|
var (path, mangaFile) = await _cacheService.GetCachedPagePath(chapter, page);
|
||||||
|
if (string.IsNullOrEmpty(path)) return BadRequest($"No such image for page {page}");
|
||||||
|
var file = await _directoryService.ReadImageAsync(path);
|
||||||
|
file.Page = page;
|
||||||
|
file.MangaFileName = mangaFile.FilePath;
|
||||||
|
file.NeedsSplitting = file.Width > file.Height;
|
||||||
|
|
||||||
|
// TODO: Validate if sending page whole (not base64 encoded) fixes Tablet issue
|
||||||
|
|
||||||
|
return File(file.Content, "image/jpeg", mangaFile.FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("get-bookmark")]
|
[HttpGet("get-bookmark")]
|
||||||
public async Task<ActionResult<int>> GetBookmark(int chapterId)
|
public async Task<ActionResult<int>> GetBookmark(int chapterId)
|
||||||
|
@ -104,11 +104,16 @@ namespace API.Controllers
|
|||||||
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(updateSeries.Id);
|
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(updateSeries.Id);
|
||||||
|
|
||||||
if (series == null) return BadRequest("Series does not exist");
|
if (series == null) return BadRequest("Series does not exist");
|
||||||
|
|
||||||
// TODO: Support changing series properties once "locking" is implemented.
|
// TODO: check if new name isn't an existing series
|
||||||
// series.Name = updateSeries.Name;
|
var existingSeries = await _unitOfWork.SeriesRepository.GetSeriesByNameAsync(updateSeries.Name); // NOTE: This isnt checking library
|
||||||
// series.OriginalName = updateSeries.OriginalName;
|
if (existingSeries != null && existingSeries.Id != series.Id)
|
||||||
// series.SortName = updateSeries.SortName;
|
{
|
||||||
|
return BadRequest("A series already exists with this name. Name must be unique.");
|
||||||
|
}
|
||||||
|
series.Name = updateSeries.Name;
|
||||||
|
series.LocalizedName = updateSeries.LocalizedName;
|
||||||
|
series.SortName = updateSeries.SortName;
|
||||||
series.Summary = updateSeries.Summary;
|
series.Summary = updateSeries.Summary;
|
||||||
//series.CoverImage = updateSeries.CoverImage;
|
//series.CoverImage = updateSeries.CoverImage;
|
||||||
|
|
||||||
|
@ -76,14 +76,12 @@ namespace API.Controllers
|
|||||||
|
|
||||||
if (!_unitOfWork.HasChanges()) return Ok("Nothing was updated");
|
if (!_unitOfWork.HasChanges()) return Ok("Nothing was updated");
|
||||||
|
|
||||||
if (_unitOfWork.HasChanges() && await _unitOfWork.Complete())
|
if (!_unitOfWork.HasChanges() || !await _unitOfWork.Complete())
|
||||||
{
|
return BadRequest("There was a critical issue. Please try again.");
|
||||||
_logger.LogInformation("Server Settings updated");
|
|
||||||
_taskScheduler.ScheduleTasks();
|
_logger.LogInformation("Server Settings updated");
|
||||||
return Ok(updateSettingsDto);
|
_taskScheduler.ScheduleTasks();
|
||||||
}
|
return Ok(updateSettingsDto);
|
||||||
|
|
||||||
return BadRequest("There was a critical issue. Please try again.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "RequireAdminRole")]
|
[Authorize(Policy = "RequireAdminRole")]
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
public int Id { get; init; }
|
public int Id { get; init; }
|
||||||
public string Name { get; init; }
|
public string Name { get; init; }
|
||||||
public string OriginalName { get; init; }
|
public string OriginalName { get; init; }
|
||||||
|
public string LocalizedName { get; init; }
|
||||||
public string SortName { get; init; }
|
public string SortName { get; init; }
|
||||||
public string Summary { get; init; }
|
public string Summary { get; init; }
|
||||||
public byte[] CoverImage { get; init; }
|
public byte[] CoverImage { get; init; }
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
public int Id { get; init; }
|
public int Id { get; init; }
|
||||||
public string Name { get; init; }
|
public string Name { get; init; }
|
||||||
public string OriginalName { get; init; }
|
public string LocalizedName { get; init; }
|
||||||
public string SortName { get; init; }
|
public string SortName { get; init; }
|
||||||
public string Summary { get; init; }
|
public string Summary { get; init; }
|
||||||
public byte[] CoverImage { get; init; }
|
public byte[] CoverImage { get; init; }
|
||||||
|
724
API/Data/Migrations/20210225150830_AddLocalizedName.Designer.cs
generated
Normal file
724
API/Data/Migrations/20210225150830_AddLocalizedName.Designer.cs
generated
Normal file
@ -0,0 +1,724 @@
|
|||||||
|
// <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("20210225150830_AddLocalizedName")]
|
||||||
|
partial class AddLocalizedName
|
||||||
|
{
|
||||||
|
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<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.AppUserPreferences", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("HideReadOnDetails")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("PageSplitOption")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ReadingDirection")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ScalingOption")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("AppUserPreferences");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ChapterId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("PagesRead")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("VolumeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserProgresses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Rating")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Review")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserRating");
|
||||||
|
});
|
||||||
|
|
||||||
|
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.Chapter", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte[]>("CoverImage")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Number")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Pages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Range")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("VolumeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("VolumeId");
|
||||||
|
|
||||||
|
b.ToTable("Chapter");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.FolderPath", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastScanned")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
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<int>("ChapterId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("FilePath")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Format")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("NumberOfPages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ChapterId");
|
||||||
|
|
||||||
|
b.ToTable("MangaFile");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Series", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte[]>("CoverImage")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("LibraryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("LocalizedName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("OriginalName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Pages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
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.ServerSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Key")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<uint>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Key");
|
||||||
|
|
||||||
|
b.ToTable("ServerSetting");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte[]>("CoverImage")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSpecial")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Number")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Pages")
|
||||||
|
.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.AppUserPreferences", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithOne("UserPreferences")
|
||||||
|
.HasForeignKey("API.Entities.AppUserPreferences", "AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithMany("Progresses")
|
||||||
|
.HasForeignKey("AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
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.Chapter", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.Volume", "Volume")
|
||||||
|
.WithMany("Chapters")
|
||||||
|
.HasForeignKey("VolumeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Volume");
|
||||||
|
});
|
||||||
|
|
||||||
|
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.Chapter", "Chapter")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("ChapterId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Chapter");
|
||||||
|
});
|
||||||
|
|
||||||
|
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("Progresses");
|
||||||
|
|
||||||
|
b.Navigation("Ratings");
|
||||||
|
|
||||||
|
b.Navigation("UserPreferences");
|
||||||
|
|
||||||
|
b.Navigation("UserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Chapter", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Files");
|
||||||
|
});
|
||||||
|
|
||||||
|
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("Chapters");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
API/Data/Migrations/20210225150830_AddLocalizedName.cs
Normal file
23
API/Data/Migrations/20210225150830_AddLocalizedName.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace API.Data.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddLocalizedName : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "LocalizedName",
|
||||||
|
table: "Series",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "LocalizedName",
|
||||||
|
table: "Series");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -340,6 +340,9 @@ namespace API.Data.Migrations
|
|||||||
b.Property<int>("LibraryId")
|
b.Property<int>("LibraryId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("LocalizedName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@ namespace API.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string SortName { get; set; }
|
public string SortName { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Name in Japanese. By default, will be same as Name.
|
||||||
|
/// </summary>
|
||||||
|
public string LocalizedName { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// Original Name on disk. Not exposed to UI.
|
/// Original Name on disk. Not exposed to UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string OriginalName { get; set; }
|
public string OriginalName { get; set; }
|
||||||
|
@ -144,11 +144,14 @@ namespace API.Services.Tasks
|
|||||||
|
|
||||||
private void UpdateLibrary(Library library, Dictionary<string, List<ParserInfo>> parsedSeries)
|
private void UpdateLibrary(Library library, Dictionary<string, List<ParserInfo>> parsedSeries)
|
||||||
{
|
{
|
||||||
|
if (parsedSeries == null) throw new ArgumentNullException(nameof(parsedSeries));
|
||||||
|
|
||||||
// First, remove any series that are not in parsedSeries list
|
// First, remove any series that are not in parsedSeries list
|
||||||
var foundSeries = parsedSeries.Select(s => Parser.Parser.Normalize(s.Key)).ToList();
|
var foundSeries = parsedSeries.Select(s => Parser.Parser.Normalize(s.Key)).ToList();
|
||||||
var missingSeries = library.Series.Where(existingSeries =>
|
var missingSeries = library.Series.Where(existingSeries =>
|
||||||
!foundSeries.Contains(existingSeries.NormalizedName) || !parsedSeries.ContainsKey(existingSeries.Name) ||
|
!foundSeries.Contains(existingSeries.NormalizedName) || !parsedSeries.ContainsKey(existingSeries.Name)
|
||||||
!parsedSeries.ContainsKey(existingSeries.OriginalName));
|
|| (existingSeries.LocalizedName != null && !parsedSeries.ContainsKey(existingSeries.LocalizedName))
|
||||||
|
|| !parsedSeries.ContainsKey(existingSeries.OriginalName));
|
||||||
var removeCount = 0;
|
var removeCount = 0;
|
||||||
foreach (var existingSeries in missingSeries)
|
foreach (var existingSeries in missingSeries)
|
||||||
{
|
{
|
||||||
@ -167,6 +170,7 @@ namespace API.Services.Tasks
|
|||||||
{
|
{
|
||||||
Name = key,
|
Name = key,
|
||||||
OriginalName = key,
|
OriginalName = key,
|
||||||
|
LocalizedName = key,
|
||||||
NormalizedName = Parser.Parser.Normalize(key),
|
NormalizedName = Parser.Parser.Normalize(key),
|
||||||
SortName = key,
|
SortName = key,
|
||||||
Summary = "",
|
Summary = "",
|
||||||
@ -175,6 +179,7 @@ namespace API.Services.Tasks
|
|||||||
library.Series.Add(existingSeries);
|
library.Series.Add(existingSeries);
|
||||||
}
|
}
|
||||||
existingSeries.NormalizedName = Parser.Parser.Normalize(key);
|
existingSeries.NormalizedName = Parser.Parser.Normalize(key);
|
||||||
|
existingSeries.LocalizedName ??= key;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, we only have to deal with series that exist on disk. Let's recalculate the volumes for each series
|
// Now, we only have to deal with series that exist on disk. Let's recalculate the volumes for each series
|
||||||
|
Loading…
x
Reference in New Issue
Block a user