135 lines
5.4 KiB
C#
135 lines
5.4 KiB
C#
using Manager.DTOs;
|
|
using ManagerService.Data;
|
|
using ManagerService.Data.SubSection;
|
|
using ManagerService.DTOs;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace ManagerService.Services
|
|
{
|
|
public class AgendaSyncService
|
|
{
|
|
private readonly ILogger<AgendaSyncService> _logger;
|
|
private readonly IServiceScopeFactory _scopeFactory;
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
|
|
public AgendaSyncService(ILogger<AgendaSyncService> logger, IServiceScopeFactory scopeFactory, IHttpClientFactory httpClientFactory)
|
|
{
|
|
_logger = logger;
|
|
_scopeFactory = scopeFactory;
|
|
_httpClientFactory = httpClientFactory;
|
|
}
|
|
|
|
public async Task SyncAllAsync()
|
|
{
|
|
using var scope = _scopeFactory.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<MyInfoMateDbContext>();
|
|
|
|
var sections = db.Sections.OfType<SectionAgenda>()
|
|
.Where(sa => sa.IsOnlineAgenda && sa.AgendaResourceIds != null && sa.AgendaResourceIds.Count > 0)
|
|
.Select(sa => sa.Id)
|
|
.ToList();
|
|
|
|
foreach (var id in sections)
|
|
{
|
|
try { await SyncSectionAsync(id); }
|
|
catch (Exception ex) { _logger.LogError(ex, "Error syncing agenda section {Id}", id); }
|
|
}
|
|
}
|
|
|
|
public async Task SyncSectionAsync(string sectionAgendaId)
|
|
{
|
|
using var scope = _scopeFactory.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<MyInfoMateDbContext>();
|
|
|
|
var section = db.Sections.OfType<SectionAgenda>()
|
|
.Include(sa => sa.EventAgendas)
|
|
.FirstOrDefault(sa => sa.Id == sectionAgendaId);
|
|
|
|
if (section == null || !section.IsOnlineAgenda || section.AgendaResourceIds == null)
|
|
return;
|
|
|
|
var http = _httpClientFactory.CreateClient();
|
|
|
|
foreach (var resourceRef in section.AgendaResourceIds)
|
|
{
|
|
if (string.IsNullOrEmpty(resourceRef.value) || string.IsNullOrEmpty(resourceRef.language))
|
|
continue;
|
|
|
|
var resource = db.Resources.FirstOrDefault(r => r.Id == resourceRef.value);
|
|
if (resource == null || string.IsNullOrEmpty(resource.Url))
|
|
continue;
|
|
|
|
List<RemoteEventAgendaDTO> remoteEvents;
|
|
try
|
|
{
|
|
var json = await http.GetStringAsync(resource.Url);
|
|
remoteEvents = JsonConvert.DeserializeObject<List<RemoteEventAgendaDTO>>(json, RemoteAgendaJsonSettings.Lenient) ?? new();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to fetch agenda JSON for section {Id} language {Lang}", sectionAgendaId, resourceRef.language);
|
|
continue;
|
|
}
|
|
|
|
foreach (var remote in remoteEvents)
|
|
{
|
|
var dateFrom = remote.GetDateFrom();
|
|
|
|
// Match on DateFrom (date part only), restricted to IsSynced events
|
|
var existing = section.EventAgendas.FirstOrDefault(ea =>
|
|
ea.IsSynced &&
|
|
ea.DateFrom.HasValue &&
|
|
dateFrom.HasValue &&
|
|
ea.DateFrom.Value.Date == dateFrom.Value.Date);
|
|
|
|
if (existing == null)
|
|
{
|
|
existing = new EventAgenda
|
|
{
|
|
Label = new List<TranslationDTO>(),
|
|
Description = new List<TranslationDTO>(),
|
|
SectionAgendaId = sectionAgendaId,
|
|
IsSynced = true,
|
|
};
|
|
section.EventAgendas.Add(existing);
|
|
db.EventAgendas.Add(existing);
|
|
}
|
|
|
|
// Update / set translation for this language
|
|
SetTranslation(existing.Label, resourceRef.language, remote.name);
|
|
SetTranslation(existing.Description, resourceRef.language, remote.description);
|
|
|
|
// Non-translated fields (last language wins, acceptable)
|
|
existing.DateFrom = dateFrom;
|
|
existing.DateTo = remote.GetDateTo();
|
|
existing.Phone = remote.phone;
|
|
existing.Email = remote.email;
|
|
existing.Website = remote.website;
|
|
existing.IdVideoYoutube = remote.id_video_youtube;
|
|
existing.IsSynced = true;
|
|
}
|
|
}
|
|
|
|
db.SaveChanges();
|
|
_logger.LogInformation("Synced agenda section {Id}", sectionAgendaId);
|
|
}
|
|
|
|
private static void SetTranslation(List<TranslationDTO> list, string language, string? value)
|
|
{
|
|
var existing = list.FirstOrDefault(t => t.language == language);
|
|
if (existing != null)
|
|
existing.value = value ?? "";
|
|
else
|
|
list.Add(new TranslationDTO { language = language, value = value ?? "" });
|
|
}
|
|
}
|
|
}
|