TourIAm/TIAMWebApp/Server/Controllers/BlogAPIController.cs

214 lines
7.7 KiB
C#

using GoogleApi.Entities.Search.Video.Common;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
using System.Text.RegularExpressions;
using TIAMWebApp.Shared.Application.Models;
namespace TIAMWebApp.Server.Controllers
{
[ApiController]
[Route("api/blog")]
public class BlogAPIController : ControllerBase
{
private readonly IWebHostEnvironment _env;
private readonly string _dataPath;
private readonly string _coverPath;
public BlogAPIController(IWebHostEnvironment env)
{
_env = env;
_dataPath = Path.Combine(_env.WebRootPath, "data");
_coverPath = Path.Combine(_env.WebRootPath, "uploads", "covers");
Directory.CreateDirectory(_dataPath);
Directory.CreateDirectory(_coverPath);
}
// ✅ Get All Posts
[HttpGet]
public IActionResult GetAll()
{
var files = Directory.GetFiles(_dataPath, "*.json");
var posts = files.Select(file =>
{
var json = System.IO.File.ReadAllText(file);
return JsonSerializer.Deserialize<BlogPostMetadata>(json);
}).ToList();
return Ok(posts);
}
// ✅ Get Single Post
[HttpGet("{id}")]
public IActionResult GetById(string id)
{
var file = Path.Combine(_dataPath, $"{id}.json");
if (!System.IO.File.Exists(file))
return NotFound();
var json = System.IO.File.ReadAllText(file);
var post = JsonSerializer.Deserialize<BlogPostMetadata>(json);
return Ok(post);
}
// ✅ Create Post (with optional cover upload)
[HttpPost]
public async Task<IActionResult> Create([FromForm] BlogPostForm form)
{
var post = new BlogPostMetadata
{
Title = form.Title,
Lead = form.Lead,
DriveLink = form.DriveLink,
Tags = form.Tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList()
};
if (form.CoverImage != null)
{
string fileName = $"{post.Id}{Path.GetExtension(form.CoverImage.FileName)}";
string filePath = Path.Combine(_coverPath, fileName);
await using var fs = System.IO.File.Create(filePath);
await form.CoverImage.CopyToAsync(fs);
post.CoverImage = $"/uploads/covers/{fileName}";
}
string jsonPath = Path.Combine(_dataPath, $"{post.Id}.json");
await System.IO.File.WriteAllTextAsync(jsonPath, JsonSerializer.Serialize(post));
return Ok(post);
}
//// ✅ Update Post
//[HttpPut("{id}")]
//public async Task<IActionResult> Update(string id, [FromBody] BlogPostMetadata post)
//{
// string jsonPath = Path.Combine(_dataPath, $"{id}.json");
// if (!System.IO.File.Exists(jsonPath))
// return NotFound();
// post.Id = id; // Ensure correct ID
// await System.IO.File.WriteAllTextAsync(jsonPath, JsonSerializer.Serialize(post));
// return Ok(post);
//}
[HttpPut("{id}")]
public async Task<IActionResult> Update(string id)
{
var form = await Request.ReadFormAsync();
// Parse metadata fields
var title = form["Title"].ToString();
var lead = form["Lead"].ToString();
var tags = form["Tags"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();
var driveLink = form["DriveLink"].ToString();
string coverImagePath = null;
var file = form.Files.GetFile("CoverImage");
if (file != null)
{
var ext = Path.GetExtension(file.FileName);
var fileName = $"{id}{ext}";
var filePath = Path.Combine(_coverPath, fileName);
using var stream = System.IO.File.Create(filePath);
await file.CopyToAsync(stream);
// Save relative path
coverImagePath = $"/uploads/covers/{fileName}";
}
// Load existing metadata
string jsonPath = Path.Combine(_dataPath, $"{id}.json");
if (!System.IO.File.Exists(jsonPath))
return NotFound();
var existingJson = await System.IO.File.ReadAllTextAsync(jsonPath);
var existing = JsonSerializer.Deserialize<BlogPostMetadata>(existingJson);
// Update values
existing.Title = title;
existing.Lead = lead;
existing.Tags = tags;
existing.DriveLink = driveLink;
existing.CoverImage = coverImagePath;
if (!string.IsNullOrWhiteSpace(coverImagePath))
existing.CoverImage = coverImagePath;
await System.IO.File.WriteAllTextAsync(jsonPath, JsonSerializer.Serialize(existing));
return Ok(existing);
}
// ✅ Delete Post
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
string jsonPath = Path.Combine(_dataPath, $"{id}.json");
if (!System.IO.File.Exists(jsonPath))
return NotFound();
var post = JsonSerializer.Deserialize<BlogPostMetadata>(System.IO.File.ReadAllText(jsonPath));
if (!string.IsNullOrEmpty(post?.CoverImage))
{
var coverPath = Path.Combine(_env.WebRootPath, post.CoverImage.TrimStart('/').Replace("/", Path.DirectorySeparatorChar.ToString()));
if (System.IO.File.Exists(coverPath))
System.IO.File.Delete(coverPath);
}
System.IO.File.Delete(jsonPath);
return NoContent();
}
[HttpGet("postcontent/{postId}")]
public async Task<IActionResult> GetPostContent(string postId)
{
// Load metadata (adjust this to your actual metadata loading logic)
var metadataPath = Path.Combine(_dataPath, $"{postId}.json");
if (!System.IO.File.Exists(metadataPath))
{
return NotFound("Post metadata not found.");
}
var metadataJson = await System.IO.File.ReadAllTextAsync(metadataPath);
var metadata = System.Text.Json.JsonSerializer.Deserialize<BlogPostMetadata>(metadataJson);
if (metadata == null || string.IsNullOrEmpty(metadata.DriveLink))
{
return BadRequest("Invalid post metadata.");
}
// Extract file ID from Google Drive link
string? fileId = ExtractGoogleDriveFileId(metadata.DriveLink);
if (string.IsNullOrEmpty(fileId))
{
return BadRequest("Invalid Drive link.");
}
// Download blog content from Drive
string downloadUrl = $"https://drive.google.com/uc?export=download&id={fileId}";
using var httpClient = new HttpClient();
var content = await httpClient.GetStringAsync(downloadUrl);
return Content(content, "text/html");
}
private string? ExtractGoogleDriveFileId(string driveLink)
{
var match = Regex.Match(driveLink, @"\/d\/([^\/]+)");
return match.Success ? match.Groups[1].Value : null;
}
public class BlogPostForm
{
public string Title { get; set; }
public string Lead { get; set; }
public string DriveLink { get; set; }
public string Tags { get; set; }
public IFormFile CoverImage { get; set; }
}
}
}