Synchronize native Enigma2 channels every six hours and migrate preferences

This commit is contained in:
2026-10-23 19:26:28 +02:00
parent 50b39fa40b
commit 2e7662f018
11 changed files with 391 additions and 6 deletions
@@ -57,6 +57,23 @@ public sealed class PreferencesStore
await File.WriteAllTextAsync(temp,JsonSerializer.Serialize(value),token); File.Move(temp,file,true); }
finally { gate.Release(); }
}
public async Task Remap(Guid user, System.Collections.Generic.IReadOnlyDictionary<string,string> mapping, CancellationToken token)
{
var gate=locks.GetOrAdd(user,_=>new(1)); await gate.WaitAsync(token);
try
{
var file=Path.Combine(folder,user.ToString("N")+".json");
if(!File.Exists(file))return;
var value=JsonSerializer.Deserialize<ChannelPreferences>(await File.ReadAllTextAsync(file,token))??new();value.Validate();
var before=JsonSerializer.Serialize(value);
string[] Map(string[] ids)=>ids.Select(id=>mapping.TryGetValue(id,out var target)?target:id).Distinct().ToArray();
value.FavoriteIds=Map(value.FavoriteIds);value.HiddenIds=Map(value.HiddenIds);value.OrderedIds=Map(value.OrderedIds);
var after=JsonSerializer.Serialize(value);
if(before==after)return;
await File.WriteAllTextAsync(file+".tmp",after,token);File.Move(file+".tmp",file,true);
}
finally { gate.Release(); }
}
}
[ApiController]
[Route("DecoderIntegration")]
@@ -69,7 +86,8 @@ public sealed class PreferencesController : ControllerBase
private readonly LiveStreamProbe probe;
private readonly ILibraryManager library;
private readonly IUserManager users;
public PreferencesController(PreferencesStore store,InternetEpg epg,LiveStreamRelay relay,LiveStreamProbe probe,ILibraryManager library,IUserManager users) { this.store=store; this.epg=epg; this.relay=relay; this.probe=probe; this.library=library; this.users=users; }
private readonly ChannelSyncTask channelSync;
public PreferencesController(PreferencesStore store,InternetEpg epg,LiveStreamRelay relay,LiveStreamProbe probe,ILibraryManager library,IUserManager users,ChannelSyncTask channelSync=null) { this.store=store; this.epg=epg; this.relay=relay; this.probe=probe; this.library=library; this.users=users; this.channelSync=channelSync; }
private Guid UserId => Guid.TryParse(User.FindFirst("Jellyfin-UserId")?.Value,out var id) ? id : Guid.Empty;
[HttpGet("Channels")]
[AllowAnonymous]
@@ -98,5 +116,5 @@ public sealed class PreferencesController : ControllerBase
}
[HttpGet("Status")]
[Authorize(Policy="RequiresElevation")]
public IActionResult Status() => Ok(new { epg.LastSuccess,epg.MatchedImages,epg.LastError, Source="https://epg.polishteam.one/guide.xml", Streams=relay.Status(), ProbeError=probe.LastError });
public IActionResult Status() => Ok(new { epg.LastSuccess,epg.MatchedImages,epg.LastError, Source="https://epg.polishteam.one/guide.xml", Streams=relay.Status(), ProbeError=probe.LastError, ChannelSync=channelSync==null?null:new {channelSync.LastCheckedUtc,channelSync.LastSynchronizedUtc,channelSync.LastError} });
}