SoftTraderBackend/Controller/NewsSentimentController.cs
2026-03-21 09:16:59 -04:00

106 lines
2.7 KiB
C#

using Backend.DatabaseHandler;
using Backend.Interface;
using Backend.ServiceHandler;
using Microsoft.AspNetCore.Mvc;
namespace Backend.Controllers
{
[ApiController]
[Route("api/news-sentiment")]
public sealed class NewsSentimentController : ControllerBase
{
private static DateTime _lastRefresh = DateTime.MinValue;
private static readonly Lock _refreshLock = new();
private readonly NewsSentimentService _service;
private readonly IUserInterestStore _interests;
private readonly INewsSentimentStore _store;
public NewsSentimentController(
NewsSentimentService service,
IUserInterestStore interests,
INewsSentimentStore store)
{
_service = service;
_interests = interests;
_store = store;
}
[HttpGet]
public async Task<IActionResult> Analyze(
[FromQuery] string keyword,
CancellationToken cancellationToken)
{
var results = await _service.AnalyzeAsync(keyword, cancellationToken);
return Ok(results);
}
[HttpGet("feed")]
public async Task<IActionResult> Feed(
[FromQuery] string user,
[FromQuery] string? keyword = null,
[FromQuery(Name = "request-amount")] int requestAmount = 20,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(user))
return BadRequest("User cannot be empty.");
if (requestAmount < 1)
requestAmount = 1;
List<string> keywords;
if (!string.IsNullOrWhiteSpace(keyword))
{
keywords = [keyword.Trim()];
}
else
{
var symbols = await _interests.FetchAllAsync(user, "symbol");
var topics = await _interests.FetchAllAsync(user, "topic");
keywords = symbols.Concat(topics).Distinct().ToList();
}
if (keywords.Count == 0)
return Ok(Array.Empty<object>());
var results = await _store.GetFeedAsync(keywords, requestAmount, cancellationToken);
return Ok(results.Select(NewsFeedItem.From));
}
[HttpGet("refresh")]
public async Task<ActionResult<BoolResponse>> Refresh(
[FromQuery] string user,
CancellationToken cancellationToken = default)
{
try
{
if (string.IsNullOrWhiteSpace(user))
return BadRequest("User cannot be empty.");
lock (_refreshLock)
{
if ((DateTime.UtcNow - _lastRefresh).TotalSeconds < 5)
return Ok(new BoolResponse { Success = false });
_lastRefresh = DateTime.UtcNow;
}
var symbols = await _interests.FetchAllAsync(user, "symbol");
var topics = await _interests.FetchAllAsync(user, "topic");
var kws = symbols.Concat(topics).Distinct().ToList();
foreach (var kw in kws)
{
await _service.AnalyzeAsync(kw, cancellationToken);
}
return Ok(new BoolResponse { Success = true });
}
catch (Exception)
{
return Ok(new BoolResponse { Success = false });
}
}
}
}