Infrastructure upgrades
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DeepDrftWeb\DeepDrftWeb.csproj" />
|
||||
<ProjectReference Include="..\DeepDrftContent\DeepDrftContent.csproj" />
|
||||
<ProjectReference Include="..\DeepDrftModels\DeepDrftModels.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,69 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DeepDrftWeb.Data;
|
||||
using DeepDrftWeb.Data.Repositories;
|
||||
using DeepDrftContent.FileDatabase.Services;
|
||||
using DeepDrftContent.Processors;
|
||||
using DeepDrftContent.Services;
|
||||
using DeepDrftCli.Services;
|
||||
|
||||
var builder = Host.CreateApplicationBuilder(args);
|
||||
|
||||
// Add configuration
|
||||
var appDirectory = AppContext.BaseDirectory;
|
||||
var configPath = Path.Combine(appDirectory, "appsettings.json");
|
||||
builder.Configuration.AddJsonFile(configPath, optional: false, reloadOnChange: true);
|
||||
|
||||
// Add logging
|
||||
builder.Services.AddLogging(configure => configure.AddConsole());
|
||||
|
||||
// Add database context
|
||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
throw new InvalidOperationException("DefaultConnection not found in configuration");
|
||||
|
||||
builder.Services.AddDbContext<DeepDrftContext>(options =>
|
||||
options.UseSqlite(connectionString));
|
||||
|
||||
// Add FileDatabase
|
||||
builder.Services.AddSingleton<FileDatabase>(provider =>
|
||||
{
|
||||
var logger = provider.GetRequiredService<ILogger<Program>>();
|
||||
var configuration = provider.GetRequiredService<IConfiguration>();
|
||||
try
|
||||
{
|
||||
var vaultPath = configuration["FileDatabaseSettings:VaultPath"];
|
||||
if (string.IsNullOrEmpty(vaultPath))
|
||||
throw new InvalidOperationException("FileDatabaseSettings:VaultPath not found in configuration");
|
||||
|
||||
var fileDatabase = FileDatabase.FromAsync(vaultPath).GetAwaiter().GetResult();
|
||||
if (fileDatabase == null)
|
||||
{
|
||||
logger.LogError("Failed to initialize FileDatabase");
|
||||
throw new InvalidOperationException("FileDatabase initialization failed");
|
||||
}
|
||||
return fileDatabase;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Error initializing FileDatabase");
|
||||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
// Add services
|
||||
builder.Services.AddScoped<TrackRepository>();
|
||||
builder.Services.AddScoped<DeepDrftWeb.Services.TrackService>();
|
||||
builder.Services.AddScoped<AudioProcessor>();
|
||||
builder.Services.AddScoped<DeepDrftContent.Services.TrackService>();
|
||||
builder.Services.AddScoped<CliService>();
|
||||
|
||||
// Build and run
|
||||
var app = builder.Build();
|
||||
|
||||
// Get the CLI service and run
|
||||
var cliService = app.Services.GetRequiredService<CliService>();
|
||||
await cliService.RunAsync(args);
|
||||
@@ -0,0 +1,438 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DeepDrftWeb.Data.Repositories;
|
||||
using DeepDrftContent.Services;
|
||||
using DeepDrftModels.Entities;
|
||||
using NetBlocks.Models;
|
||||
|
||||
namespace DeepDrftCli.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Main CLI service for handling command-line operations
|
||||
/// </summary>
|
||||
public class CliService
|
||||
{
|
||||
private readonly ILogger<CliService> _logger;
|
||||
private readonly TrackRepository _trackRepository;
|
||||
private readonly DeepDrftWeb.Services.TrackService _webTrackService;
|
||||
private readonly DeepDrftContent.Services.TrackService _contentTrackService;
|
||||
|
||||
public CliService(
|
||||
ILogger<CliService> logger,
|
||||
TrackRepository trackRepository,
|
||||
DeepDrftWeb.Services.TrackService webTrackService,
|
||||
DeepDrftContent.Services.TrackService contentTrackService)
|
||||
{
|
||||
_logger = logger;
|
||||
_trackRepository = trackRepository;
|
||||
_webTrackService = webTrackService;
|
||||
_contentTrackService = contentTrackService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main entry point for CLI operations
|
||||
/// </summary>
|
||||
public async Task RunAsync(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
ShowHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
var command = args[0].ToLowerInvariant();
|
||||
switch (command)
|
||||
{
|
||||
case "add":
|
||||
await HandleAddCommand(args);
|
||||
break;
|
||||
case "list":
|
||||
await HandleListCommand();
|
||||
break;
|
||||
case "help":
|
||||
case "--help":
|
||||
case "-h":
|
||||
ShowHelp();
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Unknown command: {command}");
|
||||
ShowHelp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "CLI operation failed");
|
||||
Console.WriteLine($"Error: {ex.Message}");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the add command to add a new track
|
||||
/// </summary>
|
||||
private async Task HandleAddCommand(string[] args)
|
||||
{
|
||||
// Check if we have at least the command and file path
|
||||
if (args.Length < 2)
|
||||
{
|
||||
Console.WriteLine("Error: WAV file path is required.");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage: DeepDrftCli add <wav-file-path> [-i|--interactive] [track-name] [artist] [album] [genre] [release-date]");
|
||||
Console.WriteLine(" DeepDrftCli add <wav-file-path> -i (interactive mode)");
|
||||
Console.WriteLine("Example: DeepDrftCli add \"song.wav\" \"My Song\" \"Artist Name\" \"Album Name\" \"Rock\" \"2024-01-01\"");
|
||||
Console.WriteLine("Example: DeepDrftCli add \"song.wav\" --interactive");
|
||||
return;
|
||||
}
|
||||
|
||||
var wavFilePath = args[1];
|
||||
|
||||
// Validate that the file path is not a flag
|
||||
if (wavFilePath.StartsWith("-"))
|
||||
{
|
||||
Console.WriteLine("Error: WAV file path is required and cannot be a flag.");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage: DeepDrftCli add <wav-file-path> [-i|--interactive] [track-name] [artist] [album] [genre] [release-date]");
|
||||
Console.WriteLine(" DeepDrftCli add <wav-file-path> -i (interactive mode)");
|
||||
Console.WriteLine("Example: DeepDrftCli add \"song.wav\" \"My Song\" \"Artist Name\" \"Album Name\" \"Rock\" \"2024-01-01\"");
|
||||
Console.WriteLine("Example: DeepDrftCli add \"song.wav\" --interactive");
|
||||
return;
|
||||
}
|
||||
|
||||
var isInteractive = args.Contains("-i") || args.Contains("--interactive");
|
||||
|
||||
// Filter out the interactive flags from args for processing
|
||||
var filteredArgs = args.Where(arg => arg != "-i" && arg != "--interactive").ToArray();
|
||||
|
||||
string trackName;
|
||||
string artist;
|
||||
string? album;
|
||||
string? genre;
|
||||
DateOnly? releaseDate = null;
|
||||
|
||||
if (isInteractive)
|
||||
{
|
||||
// Interactive mode - prompt for metadata
|
||||
var metadata = PromptForMetadata(wavFilePath, filteredArgs);
|
||||
trackName = metadata.TrackName;
|
||||
artist = metadata.Artist;
|
||||
album = metadata.Album;
|
||||
genre = metadata.Genre;
|
||||
releaseDate = metadata.ReleaseDate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Traditional command-line mode
|
||||
if (filteredArgs.Length < 4)
|
||||
{
|
||||
Console.WriteLine("Usage: DeepDrftCli add <wav-file-path> <track-name> <artist> [album] [genre] [release-date]");
|
||||
Console.WriteLine(" DeepDrftCli add <wav-file-path> -i (interactive mode)");
|
||||
Console.WriteLine("Example: DeepDrftCli add \"song.wav\" \"My Song\" \"Artist Name\" \"Album Name\" \"Rock\" \"2024-01-01\"");
|
||||
Console.WriteLine("Example: DeepDrftCli add \"song.wav\" --interactive");
|
||||
return;
|
||||
}
|
||||
|
||||
trackName = filteredArgs[2];
|
||||
artist = filteredArgs[3];
|
||||
album = filteredArgs.Length > 4 ? filteredArgs[4] : null;
|
||||
genre = filteredArgs.Length > 5 ? filteredArgs[5] : null;
|
||||
|
||||
if (filteredArgs.Length > 6 && DateOnly.TryParse(filteredArgs[6], out var parsedDate))
|
||||
{
|
||||
releaseDate = parsedDate;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Adding track: {trackName} by {artist}");
|
||||
Console.WriteLine($"Processing WAV file: {wavFilePath}");
|
||||
|
||||
try
|
||||
{
|
||||
// Initialize tracks vault if needed
|
||||
await _contentTrackService.InitializeTracksVaultAsync();
|
||||
|
||||
// Add track to FileDatabase and get entity
|
||||
var trackEntity = await _contentTrackService.AddTrackFromWavAsync(
|
||||
wavFilePath, trackName, artist, album, genre, releaseDate);
|
||||
|
||||
if (trackEntity == null)
|
||||
{
|
||||
Console.WriteLine("Failed to process audio file");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add track to SQL database
|
||||
var result = await _webTrackService.Create(trackEntity);
|
||||
if (result.Success && result.Value != null)
|
||||
{
|
||||
Console.WriteLine($"✓ Track added successfully!");
|
||||
Console.WriteLine($" ID: {result.Value.Id}");
|
||||
Console.WriteLine($" Name: {result.Value.TrackName}");
|
||||
Console.WriteLine($" Artist: {result.Value.Artist}");
|
||||
Console.WriteLine($" Album: {result.Value.Album ?? "N/A"}");
|
||||
Console.WriteLine($" Genre: {result.Value.Genre ?? "N/A"}");
|
||||
Console.WriteLine($" Release Date: {result.Value.ReleaseDate?.ToString() ?? "N/A"}");
|
||||
Console.WriteLine($" Entry Key: {result.Value.EntryKey}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorMessage = result.Messages.FirstOrDefault()?.Message ?? "Unknown error";
|
||||
Console.WriteLine($"Failed to save track to database: {errorMessage}");
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
Console.WriteLine($"Error: WAV file not found: {wavFilePath}");
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Console.WriteLine($"Error: {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error adding track: {ex.Message}");
|
||||
_logger.LogError(ex, "Failed to add track");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the list command to show all tracks
|
||||
/// </summary>
|
||||
private async Task HandleListCommand()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Retrieving tracks from database...");
|
||||
|
||||
var result = await _webTrackService.GetAll();
|
||||
if (!result.Success || result.Value == null)
|
||||
{
|
||||
var errorMessage = result.Messages.FirstOrDefault()?.Message ?? "Unknown error";
|
||||
Console.WriteLine($"Failed to retrieve tracks: {errorMessage}");
|
||||
return;
|
||||
}
|
||||
|
||||
var tracks = result.Value;
|
||||
if (tracks.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No tracks found in database.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"\nFound {tracks.Count} tracks:");
|
||||
Console.WriteLine(new string('-', 80));
|
||||
Console.WriteLine($"{"ID",-5} {"Name",-25} {"Artist",-20} {"Album",-15} {"Genre",-10}");
|
||||
Console.WriteLine(new string('-', 80));
|
||||
|
||||
foreach (var track in tracks)
|
||||
{
|
||||
Console.WriteLine($"{track.Id,-5} {TruncateString(track.TrackName, 25),-25} {TruncateString(track.Artist, 20),-20} {TruncateString(track.Album ?? "", 15),-15} {TruncateString(track.Genre ?? "", 10),-10}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error listing tracks: {ex.Message}");
|
||||
_logger.LogError(ex, "Failed to list tracks");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows help information
|
||||
/// </summary>
|
||||
private void ShowHelp()
|
||||
{
|
||||
Console.WriteLine("DeepDrft CLI - Audio Track Management Tool");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Commands:");
|
||||
Console.WriteLine(" add <wav-file> <track-name> <artist> [album] [genre] [release-date]");
|
||||
Console.WriteLine(" - Adds a WAV file to both SQL and FileDatabase");
|
||||
Console.WriteLine(" - Example: DeepDrftCli add \"song.wav\" \"My Song\" \"Artist\" \"Album\" \"Rock\" \"2024-01-01\"");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" add <wav-file> -i|--interactive [track-name] [artist] [album] [genre] [release-date]");
|
||||
Console.WriteLine(" - Adds a WAV file with interactive metadata prompts");
|
||||
Console.WriteLine(" - Any provided command-line arguments will be used as defaults");
|
||||
Console.WriteLine(" - Example: DeepDrftCli add \"song.wav\" -i");
|
||||
Console.WriteLine(" - Example: DeepDrftCli add \"song.wav\" --interactive \"My Song\"");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" list");
|
||||
Console.WriteLine(" - Lists all tracks in the database");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" help");
|
||||
Console.WriteLine(" - Shows this help information");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Interactive Mode Features:");
|
||||
Console.WriteLine(" - Prompts for each metadata field individually");
|
||||
Console.WriteLine(" - Shows file name being processed");
|
||||
Console.WriteLine(" - Supports default values and fallback to command-line args");
|
||||
Console.WriteLine(" - Required fields: Track Name, Artist");
|
||||
Console.WriteLine(" - Optional fields: Album, Genre, Release Date");
|
||||
Console.WriteLine(" - Summary confirmation before proceeding");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Notes:");
|
||||
Console.WriteLine(" - Only WAV files are supported");
|
||||
Console.WriteLine(" - Release date format: YYYY-MM-DD");
|
||||
Console.WriteLine(" - Arguments with spaces should be quoted");
|
||||
Console.WriteLine(" - Use * to indicate required fields in interactive mode");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Truncates a string to fit within specified length
|
||||
/// </summary>
|
||||
private string TruncateString(string input, int maxLength)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return string.Empty;
|
||||
|
||||
return input.Length <= maxLength ? input : input.Substring(0, maxLength - 3) + "...";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts user for track metadata interactively
|
||||
/// </summary>
|
||||
private TrackMetadata PromptForMetadata(string wavFilePath, string[] args)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("=== Interactive Metadata Entry ===");
|
||||
Console.WriteLine($"Processing file: {Path.GetFileName(wavFilePath)}");
|
||||
Console.WriteLine("Press Enter to use default values or skip optional fields.");
|
||||
Console.WriteLine();
|
||||
|
||||
// Check if any metadata was provided via command line (fallback support)
|
||||
var trackName = args.Length > 2 ? args[2] : null;
|
||||
var artist = args.Length > 3 ? args[3] : null;
|
||||
var album = args.Length > 4 ? args[4] : null;
|
||||
var genre = args.Length > 5 ? args[5] : null;
|
||||
DateOnly? releaseDate = null;
|
||||
if (args.Length > 6 && DateOnly.TryParse(args[6], out var parsedDate))
|
||||
releaseDate = parsedDate;
|
||||
|
||||
// Prompt for track name (required)
|
||||
trackName ??= PromptForInput("Track Name", required: true);
|
||||
|
||||
// Prompt for artist (required)
|
||||
artist ??= PromptForInput("Artist", required: true);
|
||||
|
||||
// Prompt for album (optional)
|
||||
album ??= PromptForInput("Album", defaultValue: album);
|
||||
|
||||
// Prompt for genre (optional)
|
||||
genre ??= PromptForInput("Genre", defaultValue: genre);
|
||||
|
||||
// Prompt for release date (optional)
|
||||
if (releaseDate == null)
|
||||
{
|
||||
var releaseDateInput = PromptForInput("Release Date (YYYY-MM-DD)", defaultValue: releaseDate?.ToString());
|
||||
if (!string.IsNullOrWhiteSpace(releaseDateInput) && DateOnly.TryParse(releaseDateInput, out var newReleaseDate))
|
||||
{
|
||||
releaseDate = newReleaseDate;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("=== Summary ===");
|
||||
Console.WriteLine($"Track Name: {trackName}");
|
||||
Console.WriteLine($"Artist: {artist}");
|
||||
Console.WriteLine($"Album: {album ?? "N/A"}");
|
||||
Console.WriteLine($"Genre: {genre ?? "N/A"}");
|
||||
Console.WriteLine($"Release Date: {releaseDate?.ToString() ?? "N/A"}");
|
||||
Console.WriteLine();
|
||||
|
||||
if (!ConfirmProceed("Proceed with these details?"))
|
||||
{
|
||||
Console.WriteLine("Operation cancelled.");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
return new TrackMetadata
|
||||
{
|
||||
TrackName = trackName,
|
||||
Artist = artist,
|
||||
Album = album,
|
||||
Genre = genre,
|
||||
ReleaseDate = releaseDate
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts user for a single input field
|
||||
/// </summary>
|
||||
private string PromptForInput(string fieldName, bool required = false, string? defaultValue = null)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var prompt = $"{fieldName}";
|
||||
if (!string.IsNullOrWhiteSpace(defaultValue))
|
||||
prompt += $" [{defaultValue}]";
|
||||
if (required)
|
||||
prompt += " *";
|
||||
prompt += ": ";
|
||||
|
||||
Console.Write(prompt);
|
||||
var input = Console.ReadLine();
|
||||
|
||||
// Handle null input (Ctrl+C scenario)
|
||||
if (input == null)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Operation cancelled.");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
input = input.Trim();
|
||||
|
||||
// Use default value if input is empty and default exists
|
||||
if (string.IsNullOrWhiteSpace(input) && !string.IsNullOrWhiteSpace(defaultValue))
|
||||
return defaultValue;
|
||||
|
||||
// If not required and input is empty, return empty string
|
||||
if (!required && string.IsNullOrWhiteSpace(input))
|
||||
return string.Empty;
|
||||
|
||||
// Check if required field is provided
|
||||
if (required && string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
Console.WriteLine($"Error: {fieldName} is required. Please provide a value.");
|
||||
continue;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts user for yes/no confirmation
|
||||
/// </summary>
|
||||
private bool ConfirmProceed(string message)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Console.Write($"{message} (y/n): ");
|
||||
var input = Console.ReadKey();
|
||||
Console.WriteLine();
|
||||
|
||||
switch (input.KeyChar.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "y":
|
||||
return true;
|
||||
case "n":
|
||||
return false;
|
||||
default:
|
||||
Console.WriteLine("Please enter 'y' for yes or 'n' for no.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents track metadata for interactive input
|
||||
/// </summary>
|
||||
private record TrackMetadata
|
||||
{
|
||||
public required string TrackName { get; init; }
|
||||
public required string Artist { get; init; }
|
||||
public string? Album { get; init; }
|
||||
public string? Genre { get; init; }
|
||||
public DateOnly? ReleaseDate { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"System": "Warning"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Data Source=F:\\Development\\DeepDrftHome\\Database\\deepdrft.db"
|
||||
},
|
||||
"FileDatabaseSettings": {
|
||||
"VaultPath": "F:\\Development\\DeepDrftHome\\Database\\Vaults"
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
public class TrackDto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string MediaPath { get; set; }
|
||||
public required string EntryKey { get; set; }
|
||||
public string TrackName { get; set; }
|
||||
public string Artist { get; set; }
|
||||
public string? Album { get; set; }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
public class TrackEntity
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public required string MediaPath { get; set; }
|
||||
public required string EntryKey { get; set; }
|
||||
public required string TrackName { get; set; }
|
||||
public required string Artist { get; set; }
|
||||
public string? Album { get; set; }
|
||||
|
||||
@@ -16,10 +16,10 @@ public class TrackConfiguration : IEntityTypeConfiguration<TrackEntity>
|
||||
.HasColumnName("id")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(x => x.MediaPath)
|
||||
.HasColumnName("media_path")
|
||||
builder.Property(x => x.EntryKey)
|
||||
.HasColumnName("entry_key")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500);
|
||||
.HasMaxLength(100);
|
||||
|
||||
builder.Property(x => x.TrackName)
|
||||
.HasColumnName("track_name")
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using DeepDrftWeb.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DeepDrftWeb.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(DeepDrftContext))]
|
||||
[Migration("20250831000622_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.8");
|
||||
|
||||
modelBuilder.Entity("DeepDrftModels.Entities.TrackEntity", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Album")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("album");
|
||||
|
||||
b.Property<string>("Artist")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("artist");
|
||||
|
||||
b.Property<string>("Genre")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("genre");
|
||||
|
||||
b.Property<string>("ImagePath")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("image_path");
|
||||
|
||||
b.Property<string>("MediaPath")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("media_path");
|
||||
|
||||
b.Property<DateOnly?>("ReleaseDate")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("release_date");
|
||||
|
||||
b.Property<string>("TrackName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("track_name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("track", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DeepDrftWeb.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Initial : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "track",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
media_path = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false),
|
||||
track_name = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
|
||||
artist = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
|
||||
album = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
|
||||
genre = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
|
||||
release_date = table.Column<DateOnly>(type: "TEXT", nullable: true),
|
||||
image_path = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_track", x => x.id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "track");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using DeepDrftWeb.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DeepDrftWeb.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(DeepDrftContext))]
|
||||
partial class DeepDrftContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.8");
|
||||
|
||||
modelBuilder.Entity("DeepDrftModels.Entities.TrackEntity", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Album")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("album");
|
||||
|
||||
b.Property<string>("Artist")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("artist");
|
||||
|
||||
b.Property<string>("Genre")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("genre");
|
||||
|
||||
b.Property<string>("ImagePath")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("image_path");
|
||||
|
||||
b.Property<string>("MediaPath")
|
||||
.IsRequired()
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("media_path");
|
||||
|
||||
b.Property<DateOnly?>("ReleaseDate")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("release_date");
|
||||
|
||||
b.Property<string>("TrackName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("track_name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("track", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class TrackRepository
|
||||
trackEntity.Artist = track.Artist;
|
||||
trackEntity.Genre = track.Genre;
|
||||
trackEntity.ImagePath = track.ImagePath;
|
||||
trackEntity.MediaPath = track.MediaPath;
|
||||
trackEntity.EntryKey = track.EntryKey;
|
||||
trackEntity.ReleaseDate = track.ReleaseDate;
|
||||
trackEntity.TrackName = track.TrackName;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user