postit and them also

This commit is contained in:
Paul Schneider 2026-06-10 00:23:17 +01:00
commit fa7d6242f1
18 changed files with 5322 additions and 121 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class AddBlogFileAttachments : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "UploadedFiles",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Path = table.Column<string>(type: "text", nullable: true),
Length = table.Column<long>(type: "bigint", nullable: false),
ContentType = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_UploadedFiles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "BlogAttachedFiles",
columns: table => new
{
FileId = table.Column<long>(type: "bigint", nullable: false),
PostId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BlogAttachedFiles", x => new { x.FileId, x.PostId });
table.ForeignKey(
name: "FK_BlogAttachedFiles_BlogSpot_PostId",
column: x => x.PostId,
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_BlogAttachedFiles_UploadedFiles_FileId",
column: x => x.FileId,
principalTable: "UploadedFiles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_BlogAttachedFiles_PostId",
table: "BlogAttachedFiles",
column: "PostId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BlogAttachedFiles");
migrationBuilder.DropTable(
name: "UploadedFiles");
}
}
}

View file

@ -1413,6 +1413,21 @@ namespace Yavsc.Migrations
b.ToTable("ExceptionsSIREN");
});
modelBuilder.Entity("Yavsc.Models.Blog.BlogAttachedFile", b =>
{
b.Property<long>("FileId")
.HasColumnType("bigint");
b.Property<long>("PostId")
.HasColumnType("bigint");
b.HasKey("FileId", "PostId");
b.HasIndex("PostId");
b.ToTable("BlogAttachedFiles");
});
modelBuilder.Entity("Yavsc.Models.Blog.BlogPost", b =>
{
b.Property<long>("Id")
@ -1518,6 +1533,28 @@ namespace Yavsc.Migrations
b.ToTable("Comment");
});
modelBuilder.Entity("Yavsc.Models.Blog.UploadedFile", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<string>("ContentType")
.HasColumnType("text");
b.Property<long>("Length")
.HasColumnType("bigint");
b.Property<string>("Path")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("UploadedFiles");
});
modelBuilder.Entity("Yavsc.Models.BlogSpotPublication", b =>
{
b.Property<long>("BlogpostId")
@ -3700,6 +3737,25 @@ namespace Yavsc.Migrations
b.Navigation("Query");
});
modelBuilder.Entity("Yavsc.Models.Blog.BlogAttachedFile", b =>
{
b.HasOne("Yavsc.Models.Blog.UploadedFile", "File")
.WithMany()
.HasForeignKey("FileId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Yavsc.Models.Blog.BlogPost", "Post")
.WithMany()
.HasForeignKey("PostId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("File");
b.Navigation("Post");
});
modelBuilder.Entity("Yavsc.Models.Blog.BlogPost", b =>
{
b.HasOne("Yavsc.Models.ApplicationUser", "Author")

View file

@ -1,29 +0,0 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://localhost:5001",
"sslPort": 5001
}
},
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View file

@ -11,6 +11,8 @@ using Yavsc.Server.Exceptions;
using Yavsc.Server.Helpers;
using Yavsc.Services;
using Yavsc.ViewModels.Auth;
using Yavsc.Abstract.Helpers;
using Microsoft.AspNetCore.Http;
public class BlogSpotService
{
@ -29,11 +31,63 @@ public class BlogSpotService
public BlogPost Create(string userId, BlogPost post, IFormFileCollection files)
{
foreach (var file in files)
{
}
// Sauvegarder le post d'abord pour obtenir son ID
_context.BlogSpot.Add(post);
_context.SaveChanges(userId);
// Traiter les fichiers attachés s'il y en a
if (files != null && files.Count > 0)
{
var user = _context.Users.FirstOrDefault(u => u.Id == userId);
if (user != null)
{
try
{
// Créer un répertoire pour les fichiers du blog
string blogFilesSubdir = $"blogs/{post.Id}";
string destDir = Path.Combine(
AbstractFileSystemHelpers.UserFilesDirName,
user.UserName,
blogFilesSubdir
);
var di = new DirectoryInfo(destDir);
if (!di.Exists) di.Create();
// Traiter chaque fichier
foreach (var formFile in files)
{
var fileInfo = user.ReceiveUserFile(destDir, formFile);
if (fileInfo != null && !fileInfo.QuotaOffense)
{
// Créer une entrée UploadedFile si nécessaire
var uploadedFile = new UploadedFile
{
Path = fileInfo.FileName,
ContentType = formFile.ContentType,
Length = formFile.Length
};
_context.UploadedFiles.Add(uploadedFile);
_context.SaveChanges(userId);
// Lier le fichier au post
var attachment = new BlogAttachedFile
{
PostId = post.Id,
FileId = uploadedFile.Id
};
_context.BlogAttachedFiles.Add(attachment);
}
}
_context.SaveChanges(userId);
}
catch (Exception ex)
{
// Logger l'erreur mais ne pas échouer la création du post
System.Diagnostics.Debug.WriteLine($"Erreur lors du traitement des fichiers : {ex.Message}");
}
}
}
return post;
}
public async Task<BlogPostEditViewModel> GetPostForEdition(ClaimsPrincipal user, long blogPostId)
@ -112,6 +166,29 @@ public class BlogSpotService
_context.SaveChanges(user.GetUserId());
}
public async Task Modify(ClaimsPrincipal user, BlogPost blog)
{
var existing = await _context.BlogSpot.Include(b => b.ACL).SingleOrDefaultAsync(b => b.Id == blog.Id);
if (existing == null)
{
throw new InvalidOperationException($"Blog post {blog.Id} not found.");
}
var auth = await _authorizationService.AuthorizeAsync(user, existing, new EditPermission());
if (!auth.Succeeded)
{
throw new AuthorizationFailureException(auth);
}
existing.Title = blog.Title;
existing.Article = blog.Article;
existing.Photo = blog.Photo;
existing.ACL = blog.ACL;
_context.Update(existing);
_context.SaveChanges(user.GetUserId());
}
public async Task<IEnumerable<IBlogPost>> Index(ClaimsPrincipal user, string id, int skip = 0, int take = 25)
{
IEnumerable<IBlogPost> posts;
@ -148,7 +225,9 @@ public class BlogSpotService
.Select(p => p.BlogPost).ToArray();
}
var data = posts.OrderByDescending(p => p.DateModified);
var data = posts.OrderByDescending(p => p.DateModified)
.Skip(skip)
.Take(take);
return data;
}