[CHANGE] Library service, db migrations, ui blazor
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -482,3 +482,6 @@ $RECYCLE.BIN/
|
|||||||
|
|
||||||
# Vim temporary swap files
|
# Vim temporary swap files
|
||||||
*.swp
|
*.swp
|
||||||
|
/Manager.App/Library/Library.db
|
||||||
|
/Manager.App/Library/Library.db-shm
|
||||||
|
/Manager.App/Library/Library.db-wal
|
||||||
|
@@ -0,0 +1,23 @@
|
|||||||
|
<MudOverlay Absolute="Absolute" DarkBackground LockScroll @bind-Visible="Visible" ZIndex="ZIndex">
|
||||||
|
<MudStack AlignItems="AlignItems.Center">
|
||||||
|
<MudProgressCircular Indeterminate/>
|
||||||
|
<MudText>@Message</MudText>
|
||||||
|
@if (CancellationTokenSource != null)
|
||||||
|
{
|
||||||
|
<MudButton OnClick="() => CancellationTokenSource.Cancel()" Disabled="CancellationTokenSource.IsCancellationRequested">Cancel operation</MudButton>
|
||||||
|
}
|
||||||
|
</MudStack>
|
||||||
|
</MudOverlay>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public bool Visible { get; set; }
|
||||||
|
[Parameter]
|
||||||
|
public string Message { get; set; } = "Loading...";
|
||||||
|
[Parameter]
|
||||||
|
public bool Absolute { get; set; }
|
||||||
|
[Parameter]
|
||||||
|
public int ZIndex { get; set; } = 9999;
|
||||||
|
[Parameter]
|
||||||
|
public CancellationTokenSource? CancellationTokenSource { get; set; }
|
||||||
|
}
|
@@ -16,5 +16,7 @@
|
|||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
</MudAppBar>
|
</MudAppBar>
|
||||||
@Body
|
<div style="margin: 20px">
|
||||||
|
@Body
|
||||||
|
</div>
|
||||||
</CascadingValue>
|
</CascadingValue>
|
@@ -1,9 +1,9 @@
|
|||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
|
|
||||||
<MudThemeProvider @ref="@_themeProvider" IsDarkModeChanged="@OnDarkThemeChanged" Theme="@_mudTheme" IsDarkMode="@DarkTheme"/>
|
<MudThemeProvider @ref="@_themeProvider" IsDarkModeChanged="@OnDarkThemeChanged" Theme="@_mudTheme" IsDarkMode="@DarkTheme"/>
|
||||||
<MudPopoverProvider />
|
<MudPopoverProvider @rendermode="InteractiveServer"/>
|
||||||
<MudDialogProvider/>
|
<MudDialogProvider @rendermode="InteractiveServer"/>
|
||||||
<MudSnackbarProvider/>
|
<MudSnackbarProvider @rendermode="InteractiveServer"/>
|
||||||
|
|
||||||
<CascadingValue Value="this">
|
<CascadingValue Value="this">
|
||||||
<MudLayout>
|
<MudLayout>
|
||||||
|
6
Manager.App/Components/Pages/Accounts.razor
Normal file
6
Manager.App/Components/Pages/Accounts.razor
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@page "/Accounts"
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
7
Manager.App/Components/Pages/Accounts.razor.cs
Normal file
7
Manager.App/Components/Pages/Accounts.razor.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace Manager.App.Components.Pages;
|
||||||
|
|
||||||
|
public partial class Accounts : ComponentBase
|
||||||
|
{
|
||||||
|
}
|
40
Manager.App/Components/Pages/Library.razor
Normal file
40
Manager.App/Components/Pages/Library.razor
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
@page "/Library"
|
||||||
|
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
@inject ILibraryService LibraryService
|
||||||
|
|
||||||
|
<PageTitle>Library information</PageTitle>
|
||||||
|
<ForcedLoadingOverlay Visible="_loading" CancellationTokenSource="@_cancellationTokenSource"/>
|
||||||
|
|
||||||
|
@if (_libraryInformation != null)
|
||||||
|
{
|
||||||
|
<MudSimpleTable Bordered Dense Elevation="0" Outlined Square Hover>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Library path:</td>
|
||||||
|
<td>@_libraryInformation.LibraryPath</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Created at (UTC):</td>
|
||||||
|
<td>@_libraryInformation.CreatedAtUtc</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Last modified (UTC):</td>
|
||||||
|
<td>@_libraryInformation.LastModifiedUtc</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Library size:</td>
|
||||||
|
<td>@Suffix.BytesToSizeSuffix(_libraryInformation.TotalSizeBytes)</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Total media:</td>
|
||||||
|
<td>@_libraryInformation.TotalMedia</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Total channels:</td>
|
||||||
|
<td>@_libraryInformation.TotalChannels</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</MudSimpleTable>
|
||||||
|
}
|
36
Manager.App/Components/Pages/Library.razor.cs
Normal file
36
Manager.App/Components/Pages/Library.razor.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Manager.App.Models.Library;
|
||||||
|
using MudBlazor;
|
||||||
|
|
||||||
|
namespace Manager.App.Components.Pages;
|
||||||
|
|
||||||
|
public partial class Library
|
||||||
|
{
|
||||||
|
private LibraryInformation? _libraryInformation;
|
||||||
|
private bool _loading;
|
||||||
|
private CancellationTokenSource _cancellationTokenSource = new();
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
if (_cancellationTokenSource.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
_loading = true;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
var result = await LibraryService.GetLibraryInfoAsync(_cancellationTokenSource.Token);
|
||||||
|
if (result is { IsSuccess: true, Value: not null })
|
||||||
|
{
|
||||||
|
_libraryInformation = result.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Snackbar.Add($"Failed to get library info. Error: {result.Error?.Description}", Severity.Error);
|
||||||
|
}
|
||||||
|
_loading = false;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,8 +6,11 @@
|
|||||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
|
@using DotBased.Utilities
|
||||||
@using Manager.App
|
@using Manager.App
|
||||||
@using Manager.App.Components
|
@using Manager.App.Components
|
||||||
|
@using Manager.App.Components.Application
|
||||||
|
@using Manager.App.Services
|
||||||
|
|
||||||
@* MudBlazor *@
|
@* MudBlazor *@
|
||||||
@using MudBlazor
|
@using MudBlazor
|
@@ -10,7 +10,11 @@
|
|||||||
<PackageReference Include="DotBased" Version="1.0.0" />
|
<PackageReference Include="DotBased" Version="1.0.0" />
|
||||||
<PackageReference Include="DotBased.Logging.MEL" Version="1.0.0" />
|
<PackageReference Include="DotBased.Logging.MEL" Version="1.0.0" />
|
||||||
<PackageReference Include="DotBased.Logging.Serilog" Version="1.0.0" />
|
<PackageReference Include="DotBased.Logging.Serilog" Version="1.0.0" />
|
||||||
<PackageReference Include="MudBlazor" Version="8.10.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.19">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="MudBlazor" Version="8.11.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -26,4 +30,8 @@
|
|||||||
<ProjectReference Include="..\Manager.YouTube\Manager.YouTube.csproj" />
|
<ProjectReference Include="..\Manager.YouTube\Manager.YouTube.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Logs\Debug\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
|
using DotBased.Monads;
|
||||||
|
using Manager.App.Models.Library;
|
||||||
|
|
||||||
namespace Manager.App.Services;
|
namespace Manager.App.Services;
|
||||||
|
|
||||||
public interface ILibraryService
|
public interface ILibraryService
|
||||||
{
|
{
|
||||||
|
public Task<Result<LibraryInformation>> GetLibraryInfoAsync(CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
@@ -21,14 +21,51 @@ public class LibraryService : ILibraryService
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_librarySettings = librarySettings.Value;
|
_librarySettings = librarySettings.Value;
|
||||||
_dbContextFactory = contextFactory;
|
_dbContextFactory = contextFactory;
|
||||||
_libraryDirectory = Directory.CreateDirectory(Path.Combine(_librarySettings.Path, SubDirMedia));
|
_libraryDirectory = Directory.CreateDirectory(_librarySettings.Path);
|
||||||
_libraryDirectory = Directory.CreateDirectory(Path.Combine(_librarySettings.Path, SubDirChannels));
|
logger.LogDebug("Working dir for library: {LibraryWorkingDir}", _libraryDirectory.FullName);
|
||||||
|
Directory.CreateDirectory(Path.Combine(_librarySettings.Path, SubDirMedia));
|
||||||
|
Directory.CreateDirectory(Path.Combine(_librarySettings.Path, SubDirChannels));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Result<LibraryInformation>> GetLibraryInfoAsync()
|
public async Task<Result<LibraryInformation>> GetLibraryInfoAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
try
|
||||||
//TODO: Get library info
|
{
|
||||||
return ResultError.Fail("Not implemented!");
|
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
|
var libInfo = new LibraryInformation
|
||||||
|
{
|
||||||
|
LibraryPath = _libraryDirectory.FullName,
|
||||||
|
CreatedAtUtc = _libraryDirectory.CreationTimeUtc,
|
||||||
|
LastModifiedUtc = _libraryDirectory.LastWriteTimeUtc,
|
||||||
|
TotalChannels = await context.Channels.CountAsync(cancellationToken: cancellationToken),
|
||||||
|
TotalMedia = await context.Media.CountAsync(cancellationToken: cancellationToken),
|
||||||
|
TotalSizeBytes = GetDirectorySize(_libraryDirectory)
|
||||||
|
};
|
||||||
|
return libInfo;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (e is OperationCanceledException)
|
||||||
|
{
|
||||||
|
return ResultError.Fail("Library service operation cancelled");
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogError(e, "Failed to get library information");
|
||||||
|
return ResultError.Fail("Failed to get library information");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long GetDirectorySize(DirectoryInfo dir)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var size = dir.EnumerateFiles("", SearchOption.AllDirectories).Select(f => f.Length).Sum();
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogError(e, "Error while getting directory size.");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -32,17 +32,25 @@ public sealed class LibraryDbContext : DbContext
|
|||||||
{
|
{
|
||||||
channel.ToTable("channels");
|
channel.ToTable("channels");
|
||||||
channel.HasKey(x => x.Id);
|
channel.HasKey(x => x.Id);
|
||||||
|
//TODO: Link media from channel
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<ClientAccountEntity>(cae =>
|
modelBuilder.Entity<ClientAccountEntity>(cae =>
|
||||||
{
|
{
|
||||||
cae.ToTable("client_accounts");
|
cae.ToTable("client_accounts");
|
||||||
cae.HasKey(x => x.Id);
|
cae.HasKey(x => x.Id);
|
||||||
|
cae.HasMany(x => x.Playlists)
|
||||||
|
.WithOne()
|
||||||
|
.HasForeignKey(x => x.ChannelId);
|
||||||
|
cae.HasMany(x => x.HttpCookies)
|
||||||
|
.WithOne()
|
||||||
|
.HasForeignKey(x => x.ClientId);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<HttpCookieEntity>(httpce =>
|
modelBuilder.Entity<HttpCookieEntity>(httpce =>
|
||||||
{
|
{
|
||||||
httpce.ToTable("http_cookies");
|
httpce.ToTable("http_cookies");
|
||||||
|
httpce.HasKey(x => x.Name);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<MediaEntity>(me =>
|
modelBuilder.Entity<MediaEntity>(me =>
|
||||||
|
@@ -4,7 +4,8 @@ namespace Manager.Data.Entities.LibraryContext;
|
|||||||
|
|
||||||
public class ClientAccountEntity : DateTimeBase
|
public class ClientAccountEntity : DateTimeBase
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
[MaxLength(DataConstants.DbContext.DefaultDbStringSize)]
|
||||||
|
public required string Id { get; set; }
|
||||||
[MaxLength(DataConstants.DbContext.DefaultDbStringSize)]
|
[MaxLength(DataConstants.DbContext.DefaultDbStringSize)]
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
public List<PlaylistEntity> Playlists { get; set; } = [];
|
public List<PlaylistEntity> Playlists { get; set; } = [];
|
||||||
|
@@ -11,8 +11,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.19" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.19">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.19" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
386
Manager.Data/Migrations/20250831150411_initialLib.Designer.cs
generated
Normal file
386
Manager.Data/Migrations/20250831150411_initialLib.Designer.cs
generated
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Manager.Data.Contexts;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Manager.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(LibraryDbContext))]
|
||||||
|
[Migration("20250831150411_initialLib")]
|
||||||
|
partial class initialLib
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.19");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.CaptionEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("MediaId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LanguageCode")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("MediaId", "LanguageCode");
|
||||||
|
|
||||||
|
b.ToTable("captions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.ChannelEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("JoinedDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("Subscribers")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("TotalVideos")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("TotalViews")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("channels", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.ClientAccountEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("client_accounts", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.HttpCookieEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClientId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Domain")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("ExpiresUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("HttpOnly")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("SameSite")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Secure")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Name");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("http_cookies", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.Join.PlaylistMedia", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("PlaylistId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("MediaId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAddedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("PlaylistId", "MediaId");
|
||||||
|
|
||||||
|
b.HasIndex("MediaId");
|
||||||
|
|
||||||
|
b.ToTable("join_playlist_media", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("ExternalState")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDownloaded")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("State")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UploadDateUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("media", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaFormatEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("MediaId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Itag")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ApproxDurationMs")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("AudioChannels")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AudioSampleRate")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("AverageBitrate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("Bitrate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ContentLengthBytes")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double?>("Framerate")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int?>("Height")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAdaptive")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("LastModifiedUnixEpoch")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double?>("LoudnessDb")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("MimeType")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Quality")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("QualityLabel")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Width")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("MediaId", "Itag");
|
||||||
|
|
||||||
|
b.ToTable("media_formats", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.PlaylistEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ChannelId");
|
||||||
|
|
||||||
|
b.ToTable("playlists", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.CaptionEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.MediaEntity", null)
|
||||||
|
.WithMany("Captions")
|
||||||
|
.HasForeignKey("MediaId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.HttpCookieEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.ClientAccountEntity", null)
|
||||||
|
.WithMany("HttpCookies")
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.Join.PlaylistMedia", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.MediaEntity", null)
|
||||||
|
.WithMany("PlaylistMedias")
|
||||||
|
.HasForeignKey("MediaId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.PlaylistEntity", null)
|
||||||
|
.WithMany("PlaylistMedias")
|
||||||
|
.HasForeignKey("PlaylistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaFormatEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.MediaEntity", null)
|
||||||
|
.WithMany("Formats")
|
||||||
|
.HasForeignKey("MediaId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.PlaylistEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.ClientAccountEntity", null)
|
||||||
|
.WithMany("Playlists")
|
||||||
|
.HasForeignKey("ChannelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.ClientAccountEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("HttpCookies");
|
||||||
|
|
||||||
|
b.Navigation("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Captions");
|
||||||
|
|
||||||
|
b.Navigation("Formats");
|
||||||
|
|
||||||
|
b.Navigation("PlaylistMedias");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.PlaylistEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PlaylistMedias");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
238
Manager.Data/Migrations/20250831150411_initialLib.cs
Normal file
238
Manager.Data/Migrations/20250831150411_initialLib.cs
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Manager.Data.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class initialLib : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "channels",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
|
||||||
|
JoinedDate = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
Subscribers = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
TotalVideos = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
TotalViews = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
CreatedAtUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
LastModifiedUtc = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_channels", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "client_accounts",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
CreatedAtUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
LastModifiedUtc = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_client_accounts", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "media",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Title = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
|
||||||
|
UploadDateUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
ChannelId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
ExternalState = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
IsDownloaded = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
State = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
CreatedAtUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
LastModifiedUtc = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_media", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "http_cookies",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Value = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
Domain = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
Path = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
ExpiresUtc = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
|
||||||
|
Secure = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
HttpOnly = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
SameSite = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
ClientId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
CreatedAtUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
LastModifiedUtc = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_http_cookies", x => x.Name);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_http_cookies_client_accounts_ClientId",
|
||||||
|
column: x => x.ClientId,
|
||||||
|
principalTable: "client_accounts",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "playlists",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
|
||||||
|
ChannelId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
CreatedAtUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
LastModifiedUtc = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_playlists", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_playlists_client_accounts_ChannelId",
|
||||||
|
column: x => x.ChannelId,
|
||||||
|
principalTable: "client_accounts",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "captions",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
MediaId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
LanguageCode = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_captions", x => new { x.MediaId, x.LanguageCode });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_captions_media_MediaId",
|
||||||
|
column: x => x.MediaId,
|
||||||
|
principalTable: "media",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "media_formats",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
MediaId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
Itag = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
Quality = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
IsAdaptive = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
MimeType = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
Bitrate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
AverageBitrate = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
LastModifiedUnixEpoch = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
ContentLengthBytes = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
ApproxDurationMs = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
Width = table.Column<int>(type: "INTEGER", nullable: true),
|
||||||
|
Height = table.Column<int>(type: "INTEGER", nullable: true),
|
||||||
|
Framerate = table.Column<double>(type: "REAL", nullable: true),
|
||||||
|
QualityLabel = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
AudioChannels = table.Column<int>(type: "INTEGER", nullable: true),
|
||||||
|
AudioSampleRate = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||||
|
LoudnessDb = table.Column<double>(type: "REAL", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_media_formats", x => new { x.MediaId, x.Itag });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_media_formats_media_MediaId",
|
||||||
|
column: x => x.MediaId,
|
||||||
|
principalTable: "media",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "join_playlist_media",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
PlaylistId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
MediaId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
|
||||||
|
DateAddedUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||||
|
DateModifiedUtc = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_join_playlist_media", x => new { x.PlaylistId, x.MediaId });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_join_playlist_media_media_MediaId",
|
||||||
|
column: x => x.MediaId,
|
||||||
|
principalTable: "media",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_join_playlist_media_playlists_PlaylistId",
|
||||||
|
column: x => x.PlaylistId,
|
||||||
|
principalTable: "playlists",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_http_cookies_ClientId",
|
||||||
|
table: "http_cookies",
|
||||||
|
column: "ClientId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_join_playlist_media_MediaId",
|
||||||
|
table: "join_playlist_media",
|
||||||
|
column: "MediaId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_playlists_ChannelId",
|
||||||
|
table: "playlists",
|
||||||
|
column: "ChannelId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "captions");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "channels");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "http_cookies");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "join_playlist_media");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "media_formats");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "playlists");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "media");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "client_accounts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
383
Manager.Data/Migrations/LibraryDbContextModelSnapshot.cs
Normal file
383
Manager.Data/Migrations/LibraryDbContextModelSnapshot.cs
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Manager.Data.Contexts;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Manager.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(LibraryDbContext))]
|
||||||
|
partial class LibraryDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.19");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.CaptionEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("MediaId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LanguageCode")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("MediaId", "LanguageCode");
|
||||||
|
|
||||||
|
b.ToTable("captions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.ChannelEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("JoinedDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("Subscribers")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("TotalVideos")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("TotalViews")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("channels", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.ClientAccountEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("client_accounts", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.HttpCookieEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClientId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Domain")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("ExpiresUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("HttpOnly")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("SameSite")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Secure")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Name");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("http_cookies", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.Join.PlaylistMedia", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("PlaylistId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("MediaId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAddedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("PlaylistId", "MediaId");
|
||||||
|
|
||||||
|
b.HasIndex("MediaId");
|
||||||
|
|
||||||
|
b.ToTable("join_playlist_media", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("ExternalState")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDownloaded")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("State")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UploadDateUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("media", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaFormatEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("MediaId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Itag")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ApproxDurationMs")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("AudioChannels")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AudioSampleRate")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("AverageBitrate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("Bitrate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ContentLengthBytes")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double?>("Framerate")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int?>("Height")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAdaptive")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("LastModifiedUnixEpoch")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double?>("LoudnessDb")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("MimeType")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Quality")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("QualityLabel")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Width")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("MediaId", "Itag");
|
||||||
|
|
||||||
|
b.ToTable("media_formats", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.PlaylistEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAtUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModifiedUtc")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ChannelId");
|
||||||
|
|
||||||
|
b.ToTable("playlists", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.CaptionEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.MediaEntity", null)
|
||||||
|
.WithMany("Captions")
|
||||||
|
.HasForeignKey("MediaId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.HttpCookieEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.ClientAccountEntity", null)
|
||||||
|
.WithMany("HttpCookies")
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.Join.PlaylistMedia", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.MediaEntity", null)
|
||||||
|
.WithMany("PlaylistMedias")
|
||||||
|
.HasForeignKey("MediaId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.PlaylistEntity", null)
|
||||||
|
.WithMany("PlaylistMedias")
|
||||||
|
.HasForeignKey("PlaylistId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaFormatEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.MediaEntity", null)
|
||||||
|
.WithMany("Formats")
|
||||||
|
.HasForeignKey("MediaId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.PlaylistEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Manager.Data.Entities.LibraryContext.ClientAccountEntity", null)
|
||||||
|
.WithMany("Playlists")
|
||||||
|
.HasForeignKey("ChannelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.ClientAccountEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("HttpCookies");
|
||||||
|
|
||||||
|
b.Navigation("Playlists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.MediaEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Captions");
|
||||||
|
|
||||||
|
b.Navigation("Formats");
|
||||||
|
|
||||||
|
b.Navigation("PlaylistMedias");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Manager.Data.Entities.LibraryContext.PlaylistEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PlaylistMedias");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -4,12 +4,12 @@ Server application for managing YouTube content and managing a local library.
|
|||||||
### Migrations
|
### Migrations
|
||||||
Using migrations using the .NET CLI
|
Using migrations using the .NET CLI
|
||||||
|
|
||||||
Add migration
|
Add migration (library)
|
||||||
```shell
|
```shell
|
||||||
dotnet ef migrations add <MigrationName> --project Manager.Data --context Manager.Data.Contexts.AppDbContext
|
dotnet ef migrations add <migration-name> --project Manager.Data --startup-project Manager.App --context Manager.Data.Contexts.LibraryDbContext
|
||||||
```
|
```
|
||||||
Update the database
|
Update the database
|
||||||
```shell
|
```shell
|
||||||
dotnet ef database update --project Manager.Data --context Manager.Data.Contexts.AppDbContext
|
dotnet ef database update --project Manager.Data --startup-project Manager.App --context Manager.Data.Contexts.LibraryDbContext
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user