43 lines
2.0 KiB
C#
43 lines
2.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using MediaBrowser.Controller.LiveTv;
|
|
|
|
namespace Jellyfin.Plugin.Enigma2;
|
|
|
|
/// <summary>Keep saved native channels playable after a receiver bouquet migration.</summary>
|
|
public static class ChannelReferenceResolver
|
|
{
|
|
public static string Resolve(string reference, IEnumerable<ChannelInfo> channels, Func<string> previousName)
|
|
{
|
|
var current = channels.Where(c => !string.IsNullOrWhiteSpace(c.Id)).ToArray();
|
|
var exact = current.FirstOrDefault(c => string.Equals(c.Id, reference, StringComparison.OrdinalIgnoreCase));
|
|
if (exact != null) return exact.Id;
|
|
|
|
// A changed Enigma service type does not change the DVB service identity.
|
|
var identity = Identity(reference);
|
|
var matches = current.Where(c => identity != null && Identity(c.Id) == identity)
|
|
.Select(c => c.Id).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
|
|
if (matches.Length == 1) return matches[0];
|
|
if (matches.Length > 1) return reference;
|
|
|
|
// A moved service has a new SID/TSID. Use only a unique exact historical
|
|
// name; never guess between HD/SD, regional or alternative services.
|
|
var name = previousName()?.Trim();
|
|
if (string.IsNullOrEmpty(name)) return reference;
|
|
matches = current.Where(c => string.Equals(c.Name?.Trim(), name, StringComparison.OrdinalIgnoreCase))
|
|
.Select(c => c.Id).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
|
|
return matches.Length == 1 ? matches[0] : reference;
|
|
}
|
|
|
|
private static string Identity(string reference)
|
|
{
|
|
var fields = reference?.TrimEnd(':').Split(':');
|
|
if (fields == null || fields.Length != 10 || fields[0] != "1" || fields[1] != "0") return null;
|
|
// No URLs, labels or non-DVB references participate in this fallback.
|
|
if (fields.Any(f => f.Length == 0 || !f.All(Uri.IsHexDigit))) return null;
|
|
fields[2] = "";
|
|
return string.Join(':', fields).ToUpperInvariant();
|
|
}
|
|
}
|