Files
pz8-relay/idnorm.go
T

73 lines
1.9 KiB
Go
Raw Normal View History

2026-05-06 11:05:20 +02:00
package main
import (
"strings"
"unicode"
)
// Trailing dotted suffixes that EPG providers commonly append to channel ids
// (e.g. "Italia 1.it"). Conservative allow-list to avoid eating real id chars.
var idSuffixes = []string{".it", ".uk", ".de", ".com", ".us", ".fr", ".es", ".tv"}
// Trailing video-quality markers commonly appended by either the playlist or
// the EPG (e.g. open-epg uses "Italia 1 HD.it" while the playlist may say
// "Italia 1"). Stripped symmetrically from both sides. Order matters: longer
// markers first so " full hd" wins over a partial " hd" match.
var qualitySuffixes = []string{" full hd", " uhd", " fhd", " hd", " 4k", " sd"}
// normalizeChannelID returns a stable lookup key for a channel identifier,
// collapsing cosmetic divergences across sources:
//
// "Italia 1" / "Italia 1.it" / "Italia 1 HD.it" / "italia1" → "italia1"
func normalizeChannelID(id string) string {
s := strings.ToLower(strings.TrimSpace(id))
for _, suf := range idSuffixes {
if strings.HasSuffix(s, suf) {
s = s[:len(s)-len(suf)]
break
}
}
// Strip trailing quality markers, possibly stacked ("Italia 1 Full HD HD").
for {
matched := false
for _, suf := range qualitySuffixes {
if strings.HasSuffix(s, suf) {
s = s[:len(s)-len(suf)]
matched = true
break
}
}
if !matched {
break
}
}
var b strings.Builder
b.Grow(len(s))
for _, r := range s {
if unicode.IsLetter(r) || unicode.IsDigit(r) {
b.WriteRune(r)
}
}
return b.String()
}
// buildIDMap turns a list of playlist tvg-ids into a normalized→canonical
// lookup. The canonical form is the playlist's exact tvg-id string; the EPG
// merger uses it to rewrite incoming channel/programme references.
func buildIDMap(tvgIDs []string) map[string]string {
m := make(map[string]string, len(tvgIDs))
for _, id := range tvgIDs {
key := normalizeChannelID(id)
if key == "" {
continue
}
if _, exists := m[key]; !exists {
m[key] = id
}
}
return m
}