makes file system indexer work and create local entries for albums and images
This commit is contained in:
parent
0a25ce2cc0
commit
7e528cd25d
@ -1,11 +1,15 @@
|
|||||||
using System.Threading.Channels;
|
using System.Security.Cryptography;
|
||||||
|
using System.Threading.Channels;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
namespace PiwigoDirectorySync.Commands.Scan;
|
namespace PiwigoDirectorySync.Commands.Scan;
|
||||||
|
|
||||||
public class FileIndexer
|
public class FileIndexer
|
||||||
{
|
{
|
||||||
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
private readonly IList<string> _failedFiles = new List<string>();
|
||||||
|
|
||||||
private readonly Channel<string> _fileQueue;
|
private readonly Channel<string> _fileQueue;
|
||||||
private readonly int _piwigoServerId;
|
private readonly int _piwigoServerId;
|
||||||
@ -17,20 +21,119 @@ public class FileIndexer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int TotalFilesScanned { get; private set; }
|
public int TotalFilesScanned { get; private set; }
|
||||||
|
public IReadOnlyCollection<string> FailedFiles => _failedFiles.AsReadOnly();
|
||||||
|
|
||||||
public async Task StartProcessingAsync(CancellationToken ct)
|
public async Task StartProcessingAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
await foreach (var filePath in _fileQueue.Reader.ReadAllAsync(ct))
|
await using var db = new PersistenceContext();
|
||||||
|
var piwigoServer = await db.PiwigoServers.GetByIdAsync(_piwigoServerId, ct);
|
||||||
|
|
||||||
|
await foreach (var fullFilePath in _fileQueue.Reader.ReadAllAsync(ct))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Info($"Indexing file {filePath}");
|
if (ct.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
Logger.Warn("Indexing cancelled");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info($"Indexing file {fullFilePath}");
|
||||||
|
var fileInfo = new FileInfo(fullFilePath);
|
||||||
|
|
||||||
|
if (!fileInfo.Exists)
|
||||||
|
{
|
||||||
|
Logger.Warn($"File {fullFilePath} not found");
|
||||||
|
_failedFiles.Add(fullFilePath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativePath = Path.GetRelativePath(piwigoServer.RootDirectory, fullFilePath);
|
||||||
|
|
||||||
|
var album = await GetOrAddAlbumAsync(db, piwigoServer, fileInfo.Directory!, ct);
|
||||||
|
|
||||||
|
var image = await GetOrAddImageAsync(db, album, relativePath, ct);
|
||||||
|
|
||||||
|
if (image.LastChange != fileInfo.LastWriteTimeUtc)
|
||||||
|
{
|
||||||
|
image.UploadRequired = true;
|
||||||
|
image.Md5Sum = await CalculateMd5SumAsync(fullFilePath, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.DeleteRequired = false;
|
||||||
|
image.LastChange = fileInfo.LastWriteTimeUtc;
|
||||||
|
|
||||||
|
await db.SaveChangesAsync(ct);
|
||||||
|
|
||||||
TotalFilesScanned++;
|
TotalFilesScanned++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error(ex, $"could not delete file {filePath}");
|
_failedFiles.Add(fullFilePath);
|
||||||
|
Logger.Error(ex, $"could not delete file {fullFilePath}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<ImageEntity> GetOrAddImageAsync(PersistenceContext db, AlbumEntity album, string relativePath, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var imageEntity = await db.PiwigoImages.Where(i => i.AlbumId == album.Id && i.FilePath == relativePath).FirstOrDefaultAsync(ct);
|
||||||
|
if (imageEntity is null)
|
||||||
|
{
|
||||||
|
imageEntity = new ImageEntity
|
||||||
|
{
|
||||||
|
AlbumId = album.Id,
|
||||||
|
Album = album,
|
||||||
|
FilePath = relativePath,
|
||||||
|
UploadRequired = true,
|
||||||
|
DeleteRequired = false
|
||||||
|
};
|
||||||
|
db.PiwigoImages.Add(imageEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<AlbumEntity> GetOrAddAlbumAsync(PersistenceContext db, ServerEntity server, DirectoryInfo directory, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var albumPath = Path.GetRelativePath(server.RootDirectory, directory.FullName);
|
||||||
|
var album = await db.PiwigoAlbums.FindByServerAndPathAsync(server.Id, albumPath, ct);
|
||||||
|
if (album != null)
|
||||||
|
{
|
||||||
|
return album;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlbumEntity? parentAlbum;
|
||||||
|
if (string.Equals(new DirectoryInfo(server.RootDirectory).FullName, directory.Parent!.FullName))
|
||||||
|
{
|
||||||
|
parentAlbum = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parentAlbum = await GetOrAddAlbumAsync(db, server, directory.Parent!, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
album = new AlbumEntity
|
||||||
|
{
|
||||||
|
ServerId = server.Id,
|
||||||
|
Server = server,
|
||||||
|
Name = directory.Name,
|
||||||
|
Path = albumPath,
|
||||||
|
ParentId = parentAlbum?.Id,
|
||||||
|
Parent = parentAlbum
|
||||||
|
};
|
||||||
|
db.PiwigoAlbums.Add(album);
|
||||||
|
|
||||||
|
await db.SaveChangesAsync(ct);
|
||||||
|
|
||||||
|
return album;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> CalculateMd5SumAsync(string imageFileFullPath, CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
using var md5 = MD5.Create();
|
||||||
|
await using var stream = File.OpenRead(imageFileFullPath);
|
||||||
|
var hash = await md5.ComputeHashAsync(stream, stoppingToken);
|
||||||
|
return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,6 +11,8 @@ public class ScanCommand : AsyncCommand<ScanSettings>
|
|||||||
|
|
||||||
public override async Task<int> ExecuteAsync(CommandContext context, ScanSettings settings)
|
public override async Task<int> ExecuteAsync(CommandContext context, ScanSettings settings)
|
||||||
{
|
{
|
||||||
|
//TODO: check files for deletion -> files in db but no longer exist
|
||||||
|
|
||||||
Logger.Info("Starting scanner and remover");
|
Logger.Info("Starting scanner and remover");
|
||||||
var stopWatch = Stopwatch.StartNew();
|
var stopWatch = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
152
PiwigoDirectorySync/Migrations/20230830212128_Update_path_handling.Designer.cs
generated
Normal file
152
PiwigoDirectorySync/Migrations/20230830212128_Update_path_handling.Designer.cs
generated
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PiwigoDirectorySync.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PersistenceContext))]
|
||||||
|
[Migration("20230830212128_Update_path_handling")]
|
||||||
|
partial class Update_path_handling
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.10");
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.AlbumEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("ParentId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("PiwigoAlbumId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
|
b.HasIndex("PiwigoAlbumId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("PiwigoAlbums");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ImageEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AlbumId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("DeleteRequired")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("FilePath")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Md5Sum")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerImageId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("UploadRequired")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AlbumId");
|
||||||
|
|
||||||
|
b.ToTable("PiwigoImages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ServerEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RootDirectory")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Url")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("PiwigoServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.AlbumEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.AlbumEntity", "Parent")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ParentId");
|
||||||
|
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.ServerEntity", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Parent");
|
||||||
|
|
||||||
|
b.Navigation("Server");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ImageEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.AlbumEntity", "Album")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AlbumId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Album");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PiwigoDirectorySync.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Update_path_handling : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "DirectoryName",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
newName: "Path");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "Path",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
newName: "DirectoryName");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
154
PiwigoDirectorySync/Migrations/20230830212412_Update_indices_and_rename_piwigoServerAlbumId.Designer.cs
generated
Normal file
154
PiwigoDirectorySync/Migrations/20230830212412_Update_indices_and_rename_piwigoServerAlbumId.Designer.cs
generated
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PiwigoDirectorySync.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PersistenceContext))]
|
||||||
|
[Migration("20230830212412_Update_indices_and_rename_piwigoServerAlbumId")]
|
||||||
|
partial class Update_indices_and_rename_piwigoServerAlbumId
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.10");
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.AlbumEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("ParentId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerAlbumId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerAlbumId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("PiwigoAlbums");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ImageEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AlbumId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("DeleteRequired")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("FilePath")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Md5Sum")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerImageId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("UploadRequired")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerImageId");
|
||||||
|
|
||||||
|
b.HasIndex("AlbumId", "FilePath");
|
||||||
|
|
||||||
|
b.ToTable("PiwigoImages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ServerEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RootDirectory")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Url")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("PiwigoServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.AlbumEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.AlbumEntity", "Parent")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ParentId");
|
||||||
|
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.ServerEntity", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Parent");
|
||||||
|
|
||||||
|
b.Navigation("Server");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ImageEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.AlbumEntity", "Album")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AlbumId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Album");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PiwigoDirectorySync.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Update_indices_and_rename_piwigoServerAlbumId : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_PiwigoImages_AlbumId",
|
||||||
|
table: "PiwigoImages");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "PiwigoAlbumId",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
newName: "ServerAlbumId");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_PiwigoAlbums_PiwigoAlbumId",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
newName: "IX_PiwigoAlbums_ServerAlbumId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PiwigoImages_AlbumId_FilePath",
|
||||||
|
table: "PiwigoImages",
|
||||||
|
columns: new[] { "AlbumId", "FilePath" });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PiwigoImages_ServerImageId",
|
||||||
|
table: "PiwigoImages",
|
||||||
|
column: "ServerImageId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_PiwigoImages_AlbumId_FilePath",
|
||||||
|
table: "PiwigoImages");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_PiwigoImages_ServerImageId",
|
||||||
|
table: "PiwigoImages");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "ServerAlbumId",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
newName: "PiwigoAlbumId");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "IX_PiwigoAlbums_ServerAlbumId",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
newName: "IX_PiwigoAlbums_PiwigoAlbumId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PiwigoImages_AlbumId",
|
||||||
|
table: "PiwigoImages",
|
||||||
|
column: "AlbumId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
158
PiwigoDirectorySync/Migrations/20230830213341_Adds_directory_name_to_Album.Designer.cs
generated
Normal file
158
PiwigoDirectorySync/Migrations/20230830213341_Adds_directory_name_to_Album.Designer.cs
generated
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PiwigoDirectorySync.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PersistenceContext))]
|
||||||
|
[Migration("20230830213341_Adds_directory_name_to_Album")]
|
||||||
|
partial class Adds_directory_name_to_Album
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.10");
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.AlbumEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ParentId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerAlbumId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerAlbumId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("PiwigoAlbums");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ImageEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AlbumId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("DeleteRequired")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("FilePath")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Md5Sum")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerImageId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("UploadRequired")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerImageId");
|
||||||
|
|
||||||
|
b.HasIndex("AlbumId", "FilePath");
|
||||||
|
|
||||||
|
b.ToTable("PiwigoImages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ServerEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RootDirectory")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Url")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("PiwigoServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.AlbumEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.AlbumEntity", "Parent")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ParentId");
|
||||||
|
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.ServerEntity", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Parent");
|
||||||
|
|
||||||
|
b.Navigation("Server");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ImageEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PiwigoDirectorySync.Persistence.AlbumEntity", "Album")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AlbumId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Album");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PiwigoDirectorySync.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Adds_directory_name_to_Album : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Name",
|
||||||
|
table: "PiwigoAlbums",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Name",
|
||||||
|
table: "PiwigoAlbums");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,14 +23,18 @@ namespace PiwigoDirectorySync.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<string>("DirectoryName")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int?>("ParentId")
|
b.Property<int?>("ParentId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int?>("PiwigoAlbumId")
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerAlbumId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int>("ServerId")
|
b.Property<int>("ServerId")
|
||||||
@ -40,7 +44,7 @@ namespace PiwigoDirectorySync.Migrations
|
|||||||
|
|
||||||
b.HasIndex("ParentId");
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
b.HasIndex("PiwigoAlbumId");
|
b.HasIndex("ServerAlbumId");
|
||||||
|
|
||||||
b.HasIndex("ServerId");
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
@ -77,12 +81,14 @@ namespace PiwigoDirectorySync.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("AlbumId");
|
b.HasIndex("ServerImageId");
|
||||||
|
|
||||||
|
b.HasIndex("AlbumId", "FilePath");
|
||||||
|
|
||||||
b.ToTable("PiwigoImages");
|
b.ToTable("PiwigoImages");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("PiwigoDirectorySync.Persistence.PiwigoServerEntity", b =>
|
modelBuilder.Entity("PiwigoDirectorySync.Persistence.ServerEntity", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -122,7 +128,7 @@ namespace PiwigoDirectorySync.Migrations
|
|||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ParentId");
|
.HasForeignKey("ParentId");
|
||||||
|
|
||||||
b.HasOne("PiwigoDirectorySync.Persistence.PiwigoServerEntity", "Server")
|
b.HasOne("PiwigoDirectorySync.Persistence.ServerEntity", "Server")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ServerId")
|
.HasForeignKey("ServerId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
@ -5,22 +5,21 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
namespace PiwigoDirectorySync.Persistence;
|
namespace PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
[Index(nameof(ParentId))]
|
[Index(nameof(ParentId))]
|
||||||
[Index(nameof(PiwigoAlbumId))]
|
[Index(nameof(ServerAlbumId))]
|
||||||
public class AlbumEntity
|
public class AlbumEntity
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
public int? PiwigoAlbumId { get; set; }
|
public int? ServerAlbumId { get; set; }
|
||||||
public required string DirectoryName { get; set; }
|
public required string Name { get; set; }
|
||||||
|
public required string Path { get; set; }
|
||||||
|
|
||||||
public int? ParentId { get; set; }
|
public int? ParentId { get; set; }
|
||||||
public AlbumEntity? Parent { get; set; }
|
public AlbumEntity? Parent { get; set; }
|
||||||
|
|
||||||
public required int ServerId { get; set; }
|
public required int ServerId { get; set; }
|
||||||
public PiwigoServerEntity Server { get; set; } = null!;
|
public ServerEntity Server { get; set; } = null!;
|
||||||
|
|
||||||
public string FullPath =>
|
|
||||||
Parent is not null ? $"{Parent.FullPath}{Path.DirectorySeparatorChar}{DirectoryName}" : $"{Server.RootDirectory}{Path.DirectorySeparatorChar}{DirectoryName}";
|
|
||||||
}
|
}
|
@ -4,8 +4,13 @@ namespace PiwigoDirectorySync.Persistence;
|
|||||||
|
|
||||||
public static class ExtensionMethods
|
public static class ExtensionMethods
|
||||||
{
|
{
|
||||||
public static Task<PiwigoServerEntity> GetByIdAsync(this DbSet<PiwigoServerEntity> dbSet, int serverId, CancellationToken ct)
|
public static Task<ServerEntity> GetByIdAsync(this DbSet<ServerEntity> dbSet, int serverId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
return dbSet.Where(a => a.Id == serverId).FirstAsync(ct);
|
return dbSet.Where(a => a.Id == serverId).FirstAsync(ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<AlbumEntity?> FindByServerAndPathAsync(this DbSet<AlbumEntity> dbSet, int serverId, string relativePath, CancellationToken ct)
|
||||||
|
{
|
||||||
|
return await dbSet.Where(a => a.ServerId == serverId && a.Path == relativePath).FirstOrDefaultAsync(ct);
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,7 +4,8 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace PiwigoDirectorySync.Persistence;
|
namespace PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
[Index(nameof(AlbumId))]
|
[Index(nameof(AlbumId), nameof(FilePath))]
|
||||||
|
[Index(nameof(ServerImageId))]
|
||||||
public class ImageEntity
|
public class ImageEntity
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
|
@ -4,7 +4,7 @@ namespace PiwigoDirectorySync.Persistence;
|
|||||||
|
|
||||||
public class PersistenceContext : DbContext
|
public class PersistenceContext : DbContext
|
||||||
{
|
{
|
||||||
public DbSet<PiwigoServerEntity> PiwigoServers { get; set; } = null!;
|
public DbSet<ServerEntity> PiwigoServers { get; set; } = null!;
|
||||||
public DbSet<AlbumEntity> PiwigoAlbums { get; set; } = null!;
|
public DbSet<AlbumEntity> PiwigoAlbums { get; set; } = null!;
|
||||||
public DbSet<ImageEntity> PiwigoImages { get; set; } = null!;
|
public DbSet<ImageEntity> PiwigoImages { get; set; } = null!;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
namespace PiwigoDirectorySync.Persistence;
|
namespace PiwigoDirectorySync.Persistence;
|
||||||
|
|
||||||
[Index(nameof(Name), IsUnique = true)]
|
[Index(nameof(Name), IsUnique = true)]
|
||||||
public class PiwigoServerEntity
|
public class ServerEntity
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
@ -6,6 +6,12 @@
|
|||||||
"commandLineArgs": "scan 1",
|
"commandLineArgs": "scan 1",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"PiwigoDirectorySyncPng": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"commandLineArgs": "scan 2",
|
||||||
|
"environmentVariables": {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user