New feature #469 - <language> and <language short> template options
This commit is contained in:
parent
74290ec609
commit
867085600c
@ -2,7 +2,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Version>9.1.1.1</Version>
|
<Version>9.2.0.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Octokit" Version="5.0.0" />
|
<PackageReference Include="Octokit" Version="5.0.0" />
|
||||||
|
|||||||
@ -103,6 +103,9 @@ namespace ApplicationServices
|
|||||||
|
|
||||||
[Name("Audio Format")]
|
[Name("Audio Format")]
|
||||||
public string AudioFormat { get; set; }
|
public string AudioFormat { get; set; }
|
||||||
|
|
||||||
|
[Name("Language")]
|
||||||
|
public string Language { get; set; }
|
||||||
}
|
}
|
||||||
public static class LibToDtos
|
public static class LibToDtos
|
||||||
{
|
{
|
||||||
@ -136,7 +139,8 @@ namespace ApplicationServices
|
|||||||
BookStatus = a.Book.UserDefinedItem.BookStatus.ToString(),
|
BookStatus = a.Book.UserDefinedItem.BookStatus.ToString(),
|
||||||
PdfStatus = a.Book.UserDefinedItem.PdfStatus.ToString(),
|
PdfStatus = a.Book.UserDefinedItem.PdfStatus.ToString(),
|
||||||
ContentType = a.Book.ContentType.ToString(),
|
ContentType = a.Book.ContentType.ToString(),
|
||||||
AudioFormat = a.Book.AudioFormat.ToString()
|
AudioFormat = a.Book.AudioFormat.ToString(),
|
||||||
|
Language = a.Book.Language
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
public static class LibraryExporter
|
public static class LibraryExporter
|
||||||
@ -207,7 +211,8 @@ namespace ApplicationServices
|
|||||||
nameof(ExportDto.BookStatus),
|
nameof(ExportDto.BookStatus),
|
||||||
nameof(ExportDto.PdfStatus),
|
nameof(ExportDto.PdfStatus),
|
||||||
nameof(ExportDto.ContentType),
|
nameof(ExportDto.ContentType),
|
||||||
nameof(ExportDto.AudioFormat)
|
nameof(ExportDto.AudioFormat),
|
||||||
|
nameof(ExportDto.Language)
|
||||||
};
|
};
|
||||||
var col = 0;
|
var col = 0;
|
||||||
foreach (var c in columns)
|
foreach (var c in columns)
|
||||||
@ -274,6 +279,7 @@ namespace ApplicationServices
|
|||||||
row.CreateCell(col++).SetCellValue(dto.PdfStatus);
|
row.CreateCell(col++).SetCellValue(dto.PdfStatus);
|
||||||
row.CreateCell(col++).SetCellValue(dto.ContentType);
|
row.CreateCell(col++).SetCellValue(dto.ContentType);
|
||||||
row.CreateCell(col++).SetCellValue(dto.AudioFormat);
|
row.CreateCell(col++).SetCellValue(dto.AudioFormat);
|
||||||
|
row.CreateCell(col++).SetCellValue(dto.Language);
|
||||||
|
|
||||||
rowIndex++;
|
rowIndex++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,6 +50,7 @@ namespace DataLayer
|
|||||||
// book details
|
// book details
|
||||||
public bool IsAbridged { get; private set; }
|
public bool IsAbridged { get; private set; }
|
||||||
public DateTime? DatePublished { get; private set; }
|
public DateTime? DatePublished { get; private set; }
|
||||||
|
public string Language { get; private set; }
|
||||||
|
|
||||||
// non-null. use "empty pattern"
|
// non-null. use "empty pattern"
|
||||||
internal int CategoryId { get; private set; }
|
internal int CategoryId { get; private set; }
|
||||||
@ -215,11 +216,12 @@ namespace DataLayer
|
|||||||
public void UpdateProductRating(float overallRating, float performanceRating, float storyRating)
|
public void UpdateProductRating(float overallRating, float performanceRating, float storyRating)
|
||||||
=> Rating.Update(overallRating, performanceRating, storyRating);
|
=> Rating.Update(overallRating, performanceRating, storyRating);
|
||||||
|
|
||||||
public void UpdateBookDetails(bool isAbridged, DateTime? datePublished)
|
public void UpdateBookDetails(bool isAbridged, DateTime? datePublished, string language)
|
||||||
{
|
{
|
||||||
// don't overwrite with default values
|
// don't overwrite with default values
|
||||||
IsAbridged |= isAbridged;
|
IsAbridged |= isAbridged;
|
||||||
DatePublished = datePublished ?? DatePublished;
|
DatePublished = datePublished ?? DatePublished;
|
||||||
|
Language = language?.FirstCharToUpper() ?? Language;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCategory(Category category, DbContext context = null)
|
public void UpdateCategory(Category category, DbContext context = null)
|
||||||
|
|||||||
404
Source/DataLayer/Migrations/20230201162454_AddBookLanguage.Designer.cs
generated
Normal file
404
Source/DataLayer/Migrations/20230201162454_AddBookLanguage.Designer.cs
generated
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using DataLayer;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DataLayer.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(LibationContext))]
|
||||||
|
[Migration("20230201162454_AddBookLanguage")]
|
||||||
|
partial class AddBookLanguage
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Book", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("BookId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AudibleProductId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ContentType")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DatePublished")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAbridged")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Language")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("LengthInMinutes")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Locale")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PictureId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PictureLarge")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("_audioFormat")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("BookId");
|
||||||
|
|
||||||
|
b.HasIndex("AudibleProductId");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.ToTable("Books");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.BookContributor", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("BookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ContributorId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Role")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte>("Order")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("BookId", "ContributorId", "Role");
|
||||||
|
|
||||||
|
b.HasIndex("BookId");
|
||||||
|
|
||||||
|
b.HasIndex("ContributorId");
|
||||||
|
|
||||||
|
b.ToTable("BookContributor");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AudibleCategoryId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ParentCategoryCategoryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("CategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("AudibleCategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ParentCategoryCategoryId");
|
||||||
|
|
||||||
|
b.ToTable("Categories");
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
CategoryId = -1,
|
||||||
|
AudibleCategoryId = "",
|
||||||
|
Name = ""
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Contributor", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ContributorId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AudibleContributorId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("ContributorId");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.ToTable("Contributors");
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
ContributorId = -1,
|
||||||
|
Name = ""
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.LibraryBook", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("BookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Account")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAdded")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("BookId");
|
||||||
|
|
||||||
|
b.ToTable("LibraryBooks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Series", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AudibleSeriesId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("SeriesId");
|
||||||
|
|
||||||
|
b.HasIndex("AudibleSeriesId");
|
||||||
|
|
||||||
|
b.ToTable("Series");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.SeriesBook", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("BookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Order")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("SeriesId", "BookId");
|
||||||
|
|
||||||
|
b.HasIndex("BookId");
|
||||||
|
|
||||||
|
b.HasIndex("SeriesId");
|
||||||
|
|
||||||
|
b.ToTable("SeriesBook");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Book", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DataLayer.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.OwnsOne("DataLayer.Rating", "Rating", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<int>("BookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.Property<float>("OverallRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b1.Property<float>("PerformanceRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b1.Property<float>("StoryRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b1.HasKey("BookId");
|
||||||
|
|
||||||
|
b1.ToTable("Books");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("BookId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsMany("DataLayer.Supplement", "Supplements", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<int>("SupplementId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.Property<int>("BookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.Property<string>("Url")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b1.HasKey("SupplementId");
|
||||||
|
|
||||||
|
b1.HasIndex("BookId");
|
||||||
|
|
||||||
|
b1.ToTable("Supplement");
|
||||||
|
|
||||||
|
b1.WithOwner("Book")
|
||||||
|
.HasForeignKey("BookId");
|
||||||
|
|
||||||
|
b1.Navigation("Book");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsOne("DataLayer.UserDefinedItem", "UserDefinedItem", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<int>("BookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.Property<int>("BookStatus")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.Property<int?>("PdfStatus")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.Property<string>("Tags")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b1.HasKey("BookId");
|
||||||
|
|
||||||
|
b1.ToTable("UserDefinedItem", (string)null);
|
||||||
|
|
||||||
|
b1.WithOwner("Book")
|
||||||
|
.HasForeignKey("BookId");
|
||||||
|
|
||||||
|
b1.OwnsOne("DataLayer.Rating", "Rating", b2 =>
|
||||||
|
{
|
||||||
|
b2.Property<int>("UserDefinedItemBookId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b2.Property<float>("OverallRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b2.Property<float>("PerformanceRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b2.Property<float>("StoryRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b2.HasKey("UserDefinedItemBookId");
|
||||||
|
|
||||||
|
b2.ToTable("UserDefinedItem");
|
||||||
|
|
||||||
|
b2.WithOwner()
|
||||||
|
.HasForeignKey("UserDefinedItemBookId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b1.Navigation("Book");
|
||||||
|
|
||||||
|
b1.Navigation("Rating");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Rating");
|
||||||
|
|
||||||
|
b.Navigation("Supplements");
|
||||||
|
|
||||||
|
b.Navigation("UserDefinedItem");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.BookContributor", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DataLayer.Book", "Book")
|
||||||
|
.WithMany("ContributorsLink")
|
||||||
|
.HasForeignKey("BookId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("DataLayer.Contributor", "Contributor")
|
||||||
|
.WithMany("BooksLink")
|
||||||
|
.HasForeignKey("ContributorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Book");
|
||||||
|
|
||||||
|
b.Navigation("Contributor");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Category", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DataLayer.Category", "ParentCategory")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ParentCategoryCategoryId");
|
||||||
|
|
||||||
|
b.Navigation("ParentCategory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.LibraryBook", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DataLayer.Book", "Book")
|
||||||
|
.WithOne()
|
||||||
|
.HasForeignKey("DataLayer.LibraryBook", "BookId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Book");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.SeriesBook", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DataLayer.Book", "Book")
|
||||||
|
.WithMany("SeriesLink")
|
||||||
|
.HasForeignKey("BookId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("DataLayer.Series", "Series")
|
||||||
|
.WithMany("BooksLink")
|
||||||
|
.HasForeignKey("SeriesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Book");
|
||||||
|
|
||||||
|
b.Navigation("Series");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Book", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ContributorsLink");
|
||||||
|
|
||||||
|
b.Navigation("SeriesLink");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Contributor", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("BooksLink");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DataLayer.Series", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("BooksLink");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DataLayer.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddBookLanguage : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Language",
|
||||||
|
table: "Books",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Language",
|
||||||
|
table: "Books");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ namespace DataLayer.Migrations
|
|||||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.0");
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
|
||||||
|
|
||||||
modelBuilder.Entity("DataLayer.Book", b =>
|
modelBuilder.Entity("DataLayer.Book", b =>
|
||||||
{
|
{
|
||||||
@ -41,6 +41,9 @@ namespace DataLayer.Migrations
|
|||||||
b.Property<bool>("IsAbridged")
|
b.Property<bool>("IsAbridged")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Language")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int>("LengthInMinutes")
|
b.Property<int>("LengthInMinutes")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
|||||||
@ -152,7 +152,7 @@ namespace DtoImporterService
|
|||||||
book.ReplacePublisher(publisher);
|
book.ReplacePublisher(publisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
book.UpdateBookDetails(item.IsAbridged, item.DatePublished);
|
book.UpdateBookDetails(item.IsAbridged, item.DatePublished, item.Language);
|
||||||
|
|
||||||
if (item.PdfUrl is not null)
|
if (item.PdfUrl is not null)
|
||||||
book.AddSupplementDownloadUrl(item.PdfUrl.ToString());
|
book.AddSupplementDownloadUrl(item.PdfUrl.ToString());
|
||||||
@ -174,6 +174,11 @@ namespace DtoImporterService
|
|||||||
if (item.PictureLarge is not null)
|
if (item.PictureLarge is not null)
|
||||||
book.PictureLarge = item.PictureLarge;
|
book.PictureLarge = item.PictureLarge;
|
||||||
|
|
||||||
|
// 2023-02-01
|
||||||
|
// updateBook must update language on books which were imported before the migration which added language.
|
||||||
|
// Can eventually delete this
|
||||||
|
book.UpdateBookDetails(item.IsAbridged, item.DatePublished, item.Language);
|
||||||
|
|
||||||
book.UpdateProductRating(
|
book.UpdateProductRating(
|
||||||
(float)(item.Rating?.OverallDistribution?.AverageRating ?? 0),
|
(float)(item.Rating?.OverallDistribution?.AverageRating ?? 0),
|
||||||
(float)(item.Rating?.PerformanceDistribution?.AverageRating ?? 0),
|
(float)(item.Rating?.PerformanceDistribution?.AverageRating ?? 0),
|
||||||
|
|||||||
@ -45,6 +45,7 @@ namespace FileLiberator
|
|||||||
BitRate = libraryBook.Book.AudioFormat.Bitrate,
|
BitRate = libraryBook.Book.AudioFormat.Bitrate,
|
||||||
SampleRate = libraryBook.Book.AudioFormat.SampleRate,
|
SampleRate = libraryBook.Book.AudioFormat.SampleRate,
|
||||||
Channels = libraryBook.Book.AudioFormat.Channels,
|
Channels = libraryBook.Book.AudioFormat.Channels,
|
||||||
|
Language = libraryBook.Book.Language
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,6 +105,8 @@ namespace LibationAvalonia.Dialogs
|
|||||||
|
|
||||||
public BookDetailsDialogViewModel(LibraryBook libraryBook)
|
public BookDetailsDialogViewModel(LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
|
var Book = libraryBook.Book;
|
||||||
|
|
||||||
//init tags
|
//init tags
|
||||||
Tags = libraryBook.Book.UserDefinedItem.Tags;
|
Tags = libraryBook.Book.UserDefinedItem.Tags;
|
||||||
|
|
||||||
@ -115,14 +117,15 @@ namespace LibationAvalonia.Dialogs
|
|||||||
|
|
||||||
//init book details
|
//init book details
|
||||||
DetailsText = @$"
|
DetailsText = @$"
|
||||||
Title: {libraryBook.Book.Title}
|
Title: {Book.Title}
|
||||||
Author(s): {libraryBook.Book.AuthorNames()}
|
Author(s): {Book.AuthorNames()}
|
||||||
Narrator(s): {libraryBook.Book.NarratorNames()}
|
Narrator(s): {Book.NarratorNames()}
|
||||||
Length: {(libraryBook.Book.LengthInMinutes == 0 ? "" : $"{libraryBook.Book.LengthInMinutes / 60} hr {libraryBook.Book.LengthInMinutes % 60} min")}
|
Length: {(Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min")}
|
||||||
Audio Bitrate: {libraryBook.Book.AudioFormat}
|
Audio Bitrate: {Book.AudioFormat}
|
||||||
Category: {string.Join(" > ", libraryBook.Book.CategoriesNames())}
|
Category: {string.Join(" > ", Book.CategoriesNames())}
|
||||||
Purchase Date: {libraryBook.DateAdded:d}
|
Purchase Date: {libraryBook.DateAdded:d}
|
||||||
Audible ID: {libraryBook.Book.AudibleProductId}
|
Language: {Book.Language}
|
||||||
|
Audible ID: {Book.AudibleProductId}
|
||||||
".Trim();
|
".Trim();
|
||||||
|
|
||||||
var seriesNames = libraryBook.Book.SeriesNames();
|
var seriesNames = libraryBook.Book.SeriesNames();
|
||||||
|
|||||||
@ -153,7 +153,8 @@ namespace LibationAvalonia.Dialogs
|
|||||||
SeriesNumber = "1",
|
SeriesNumber = "1",
|
||||||
BitRate = 128,
|
BitRate = 128,
|
||||||
SampleRate = 44100,
|
SampleRate = 44100,
|
||||||
Channels = 2
|
Channels = 2,
|
||||||
|
Language = "English"
|
||||||
};
|
};
|
||||||
var chapterName = "A Flight for Life";
|
var chapterName = "A Flight for Life";
|
||||||
var chapterNumber = 4;
|
var chapterNumber = 4;
|
||||||
|
|||||||
@ -27,7 +27,7 @@ namespace LibationFileManager
|
|||||||
public int Channels { get; set; }
|
public int Channels { get; set; }
|
||||||
public DateTime FileDate { get; set; } = DateTime.Now;
|
public DateTime FileDate { get; set; } = DateTime.Now;
|
||||||
public DateTime? DatePublished { get; set; }
|
public DateTime? DatePublished { get; set; }
|
||||||
|
public string Language { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LibraryBookDto : BookDto
|
public class LibraryBookDto : BookDto
|
||||||
|
|||||||
@ -41,8 +41,10 @@ namespace LibationFileManager
|
|||||||
public static TemplateTags SampleRate { get; } = new TemplateTags("samplerate", "File's orig. sample rate");
|
public static TemplateTags SampleRate { get; } = new TemplateTags("samplerate", "File's orig. sample rate");
|
||||||
public static TemplateTags Channels { get; } = new TemplateTags("channels", "Number of audio channels");
|
public static TemplateTags Channels { get; } = new TemplateTags("channels", "Number of audio channels");
|
||||||
public static TemplateTags Account { get; } = new TemplateTags("account", "Audible account of this book");
|
public static TemplateTags Account { get; } = new TemplateTags("account", "Audible account of this book");
|
||||||
public static TemplateTags Locale { get; } = new TemplateTags("locale", "Region/country");
|
public static TemplateTags Locale { get; } = new("locale", "Region/country");
|
||||||
public static TemplateTags YearPublished { get; } = new TemplateTags("year", "Year published");
|
public static TemplateTags YearPublished { get; } = new("year", "Year published");
|
||||||
|
public static TemplateTags Language { get; } = new("language", "Book's language");
|
||||||
|
public static TemplateTags LanguageShort { get; } = new("language short", "Book's language abbreviated. Eg: ENG");
|
||||||
|
|
||||||
// Special cases. Aren't mapped to replacements in Templates.cs
|
// Special cases. Aren't mapped to replacements in Templates.cs
|
||||||
// Included here for display by EditTemplateDialog
|
// Included here for display by EditTemplateDialog
|
||||||
|
|||||||
@ -112,6 +112,17 @@ namespace LibationFileManager
|
|||||||
private static Regex datePublishedTagRegex { get; } = new Regex(@"<pub\s*?date\s*?(?:\[([^\[\]]*?)\]\s*?)?>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static Regex datePublishedTagRegex { get; } = new Regex(@"<pub\s*?date\s*?(?:\[([^\[\]]*?)\]\s*?)?>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
private static Regex ifSeriesRegex { get; } = new Regex("<if series->(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static Regex ifSeriesRegex { get; } = new Regex("<if series->(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
private static string getLanguageShort(string language)
|
||||||
|
{
|
||||||
|
if (language is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
language = language.Trim();
|
||||||
|
if (language.Length <= 3)
|
||||||
|
return language.ToUpper();
|
||||||
|
return language[..3].ToUpper();
|
||||||
|
}
|
||||||
|
|
||||||
internal static FileNamingTemplate getFileNamingTemplate(LibraryBookDto libraryBookDto, string template, string dirFullPath, string extension, ReplacementCharacters replacements)
|
internal static FileNamingTemplate getFileNamingTemplate(LibraryBookDto libraryBookDto, string template, string dirFullPath, string extension, ReplacementCharacters replacements)
|
||||||
{
|
{
|
||||||
ArgumentValidator.EnsureNotNullOrWhiteSpace(template, nameof(template));
|
ArgumentValidator.EnsureNotNullOrWhiteSpace(template, nameof(template));
|
||||||
@ -155,6 +166,8 @@ namespace LibationFileManager
|
|||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.Account, libraryBookDto.Account);
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.Account, libraryBookDto.Account);
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.Locale, libraryBookDto.Locale);
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.Locale, libraryBookDto.Locale);
|
||||||
fileNamingTemplate.AddParameterReplacement(TemplateTags.YearPublished, libraryBookDto.YearPublished?.ToString() ?? "1900");
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.YearPublished, libraryBookDto.YearPublished?.ToString() ?? "1900");
|
||||||
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.Language, libraryBookDto.Language);
|
||||||
|
fileNamingTemplate.AddParameterReplacement(TemplateTags.LanguageShort, getLanguageShort(libraryBookDto.Language));
|
||||||
|
|
||||||
//Add the sanitized replacement parameters
|
//Add the sanitized replacement parameters
|
||||||
foreach (var param in fileDateParams)
|
foreach (var param in fileDateParams)
|
||||||
|
|||||||
@ -52,6 +52,7 @@ Length: {(Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Boo
|
|||||||
Audio Bitrate: {Book.AudioFormat}
|
Audio Bitrate: {Book.AudioFormat}
|
||||||
Category: {string.Join(" > ", Book.CategoriesNames())}
|
Category: {string.Join(" > ", Book.CategoriesNames())}
|
||||||
Purchase Date: {_libraryBook.DateAdded:d}
|
Purchase Date: {_libraryBook.DateAdded:d}
|
||||||
|
Language: {Book.Language}
|
||||||
Audible ID: {Book.AudibleProductId}
|
Audible ID: {Book.AudibleProductId}
|
||||||
".Trim();
|
".Trim();
|
||||||
|
|
||||||
|
|||||||
@ -85,7 +85,8 @@ namespace LibationWinForms.Dialogs
|
|||||||
SeriesNumber = "1",
|
SeriesNumber = "1",
|
||||||
BitRate = 128,
|
BitRate = 128,
|
||||||
SampleRate = 44100,
|
SampleRate = 44100,
|
||||||
Channels = 2
|
Channels = 2,
|
||||||
|
Language = "English"
|
||||||
};
|
};
|
||||||
var chapterName = "A Flight for Life";
|
var chapterName = "A Flight for Life";
|
||||||
var chapterNumber = 4;
|
var chapterNumber = 4;
|
||||||
|
|||||||
@ -39,7 +39,8 @@ namespace TemplatesTests
|
|||||||
SeriesNumber = "1",
|
SeriesNumber = "1",
|
||||||
BitRate = 128,
|
BitRate = 128,
|
||||||
SampleRate = 44100,
|
SampleRate = 44100,
|
||||||
Channels = 2
|
Channels = 2,
|
||||||
|
Language = "English"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static LibraryBookDto GetLibraryBookWithNullDates(string seriesName = "Sherlock Holmes")
|
public static LibraryBookDto GetLibraryBookWithNullDates(string seriesName = "Sherlock Holmes")
|
||||||
@ -57,7 +58,8 @@ namespace TemplatesTests
|
|||||||
SeriesNumber = "1",
|
SeriesNumber = "1",
|
||||||
BitRate = 128,
|
BitRate = 128,
|
||||||
SampleRate = 44100,
|
SampleRate = 44100,
|
||||||
Channels = 2
|
Channels = 2,
|
||||||
|
Language = "English"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user