« Module:Episode/MultiSeries » : différence entre les versions
Apparence
Contenu supprimé Contenu ajouté
Aucun résumé des modifications |
Aucun résumé des modifications |
||
| Ligne 1 : | Ligne 1 : | ||
------------------------------------------------------------ |
|||
-- Module:Episode/MultiSeries |
-- Module:Episode/MultiSeries |
||
-- Fusion SG1 + SGA + SGU |
|||
-- Fusionne toutes les séries et saisons (SG-1, SGA, SGU, Films…) |
|||
-- Normalisation, alias, indexation, cache, doublons |
|||
-- Fournit : get(id), get_by_alias(alias), resolve_alias(alias) |
|||
------------------------------------------------------------ |
|||
-- + Détection automatique des doublons |
|||
-- + Cache interne pour éviter le signal 24 |
|||
local Multi = {} |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 1. Cache anti-signal-24 |
|||
-- CACHE : si déjà chargé, on renvoie la version en mémoire |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
if package.loaded["Module:Episode/MultiSeries"] then |
|||
return package.loaded["Module:Episode/MultiSeries"] |
|||
if type(cached) == "table" then |
|||
return cached |
|||
end |
end |
||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 2. Chargement des séries |
|||
-- Dépendances |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
local |
local SG1 = require("Module:Episode/SG1") |
||
local SGA = require("Module:Episode/SGA") |
|||
local SGU = require("Module:Episode/SGU") |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 3. Tables globales |
|||
-- Structure principale |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
Multi.episodes = {} |
|||
Multi.by_id = {} |
|||
episodes = {}, -- id → table épisode |
|||
Multi.by_alias = {} |
|||
aliases = {}, -- alias normalisé → id |
|||
Multi.by_page = {} |
|||
loaded = {}, -- modules chargés |
|||
Multi.by_series = {} |
|||
duplicates = nil -- rapport de doublons |
|||
Multi.by_season = {} |
|||
} |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 4. Fonction normalize() finale |
|||
-- Liste des modules index de séries |
|||
-- (tu ajoutes ici SG1, SGA, SGU, Films, etc.) |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
local |
local function normalize(str) |
||
if not str then return "" end |
|||
"Module:Episode/SG1/Index", |
|||
"Module:Episode/SGA/Index", |
|||
"Module:Episode/SGU/Index", |
|||
"Module:Episode/Films/Index", |
|||
} |
|||
str = mw.ustring.lower(str) |
|||
------------------------------------------------------------ |
|||
str = mw.ustring.toNFD(str) |
|||
-- Charge un module de saison et fusionne son contenu |
|||
str = mw.ustring.gsub(str, "%pM", "") |
|||
------------------------------------------------------------ |
|||
str = str:gsub("'%s*", "") |
|||
local function load_season_module(path) |
|||
str = str:gsub("[{}]", " ") |
|||
str = str:gsub("[%p]", " ") |
|||
str = str:gsub("[^%w%s]", " ") |
|||
return false |
|||
str = str:gsub("%s+", " ") |
|||
end |
|||
str = mw.text.trim(str) |
|||
for key, value in pairs(mod) do |
|||
------------------------------------------------------------ |
|||
-- Cas 1 : entrée d’épisode (table avec .id) |
|||
------------------------------------------------------------ |
|||
if type(value) == "table" and value.id then |
|||
Multi.episodes[value.id] = value |
|||
-- Ajout des alias déclarés dans l’épisode |
|||
if type(value.aliases) == "table" then |
|||
for _, alias in ipairs(value.aliases) do |
|||
local norm = utils.normalize_alias(alias) |
|||
if norm then |
|||
Multi.aliases[norm] = value.id |
|||
end |
|||
end |
|||
end |
|||
------------------------------------------------------------ |
|||
-- Cas 2 : alias → id (clé = alias, valeur = id) |
|||
------------------------------------------------------------ |
|||
elseif type(value) == "string" then |
|||
local norm = utils.normalize_alias(key) |
|||
if norm then |
|||
Multi.aliases[norm] = value |
|||
end |
|||
end |
|||
end |
|||
return str |
|||
table.insert(Multi.loaded, path) |
|||
return true |
|||
end |
end |
||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 5. Alias techniques SGX |
|||
-- Charge un module index de série (liste des saisons) |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
local function |
local function make_tech_aliases(series, season, episode) |
||
local |
local s = string.format("%02d", tonumber(season)) |
||
local e = string.format("%02d", tonumber(episode)) |
|||
if not ok or type(idx) ~= "table" or not idx.list_seasons then |
|||
series = normalize(series) |
|||
return |
|||
end |
|||
return { |
|||
for _, entry in ipairs(idx.list_seasons()) do |
|||
string.format("%s s%se%s", series, s, e), |
|||
load_season_module(entry.module) |
|||
string.format("%s %sx%s", series, s, e), |
|||
end |
|||
string.format("%s %s%s", series, s, e), |
|||
} |
|||
end |
end |
||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 6. Génération complète des alias |
|||
-- Détection des doublons (IDs, alias, alias contradictoires) |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
local function |
local function make_aliases(ep) |
||
local |
local a = {} |
||
duplicate_ids = {}, |
|||
duplicate_aliases = {}, |
|||
conflicting_aliases = {}, |
|||
} |
|||
-- |
-- titres normalisés |
||
table.insert(a, normalize(ep.title_fr)) |
|||
local seen_ids = {} |
|||
table.insert(a, normalize(ep.title_en)) |
|||
for id,_ in pairs(Multi.episodes) do |
|||
if seen_ids[id] then |
|||
-- id normalisé |
|||
table.insert(report.duplicate_ids, id) |
|||
table.insert(a, normalize(ep.id)) |
|||
else |
|||
seen_ids[id] = true |
|||
-- alias techniques |
|||
for _, alias in ipairs(make_tech_aliases(ep.series, ep.season, ep.episode)) do |
|||
table.insert(a, alias) |
|||
end |
end |
||
-- |
-- extra_aliases |
||
if ep.extra_aliases then |
|||
local alias_targets = {} |
|||
for |
for _, alias in ipairs(ep.extra_aliases) do |
||
table.insert(a, normalize(alias)) |
|||
if alias_targets[alias] and alias_targets[alias] ~= id then |
|||
table.insert(report.conflicting_aliases, { |
|||
alias = alias, |
|||
id1 = alias_targets[alias], |
|||
id2 = id, |
|||
}) |
|||
elseif alias_targets[alias] then |
|||
table.insert(report.duplicate_aliases, alias) |
|||
else |
|||
alias_targets[alias] = id |
|||
end |
end |
||
end |
end |
||
return a |
|||
Multi.duplicates = report |
|||
end |
end |
||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 7. Ajout d'une série complète |
|||
-- Chargement global (toutes séries + saisons) |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
local function |
local function append_series(series_module) |
||
for _, |
for _, ep in ipairs(series_module.episodes or {}) do |
||
load_series_index(series_path) |
|||
end |
|||
detect_duplicates() |
|||
end |
|||
---------------------------------------------------- |
|||
load_all() |
|||
-- Génération des alias |
|||
---------------------------------------------------- |
|||
ep.aliases = make_aliases(ep) |
|||
---------------------------------------------------- |
|||
-- Index par ID |
|||
-- API publique |
|||
---------------------------------------------------- |
|||
Multi.by_id[ep.id] = ep |
|||
---------------------------------------------------- |
|||
-- Récupère un épisode par ID |
|||
-- Index par page (FR + EN) |
|||
function Multi.get(id) |
|||
---------------------------------------------------- |
|||
return Multi.episodes[id] |
|||
if ep.page_title_fr then |
|||
end |
|||
Multi.by_page[normalize(ep.page_title_fr)] = ep |
|||
end |
|||
if ep.page_title_en then |
|||
Multi.by_page[normalize(ep.page_title_en)] = ep |
|||
end |
|||
---------------------------------------------------- |
|||
-- Résout un alias → ID |
|||
-- Index par alias |
|||
function Multi.resolve_alias(alias) |
|||
---------------------------------------------------- |
|||
if not alias then return nil end |
|||
for _, alias in ipairs(ep.aliases) do |
|||
local norm = utils.normalize_alias(alias) |
|||
alias = normalize(alias) |
|||
return Multi.aliases[norm] |
|||
Multi.by_alias[alias] = Multi.by_alias[alias] or {} |
|||
end |
|||
table.insert(Multi.by_alias[alias], ep) |
|||
end |
|||
---------------------------------------------------- |
|||
-- Récupère un épisode via alias |
|||
-- Index par série |
|||
function Multi.get_by_alias(alias) |
|||
---------------------------------------------------- |
|||
local id = Multi.resolve_alias(alias) |
|||
Multi.by_series[ep.series] = Multi.by_series[ep.series] or {} |
|||
if id then |
|||
table.insert(Multi.by_series[ep.series], ep) |
|||
return Multi.get(id) |
|||
---------------------------------------------------- |
|||
-- Index par saison |
|||
---------------------------------------------------- |
|||
local key = ep.series .. "-" .. ep.season |
|||
Multi.by_season[key] = Multi.by_season[key] or {} |
|||
table.insert(Multi.by_season[key], ep) |
|||
---------------------------------------------------- |
|||
-- Ajout à la liste globale |
|||
---------------------------------------------------- |
|||
table.insert(Multi.episodes, ep) |
|||
end |
end |
||
return nil |
|||
end |
end |
||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
-- 8. Fusion des séries |
|||
-- CACHE : on stocke la table Multi pour les appels suivants |
|||
------------------------------------------------------------ |
|||
append_series(SG1) |
|||
append_series(SGA) |
|||
append_series(SGU) |
|||
------------------------------------------------------------ |
|||
-- 9. Cache final |
|||
------------------------------------------------------------ |
------------------------------------------------------------ |
||
package.loaded["Module:Episode/MultiSeries"] = Multi |
package.loaded["Module:Episode/MultiSeries"] = Multi |
||
Version du 2 juin 2026 à 14:47
| Il sera peut-être nécessaire de créer une page documentation pour ce module Scribunto programmé dans la page créer Les éditeurs peuvent faire des tests sur les pages bac à sable (créer | miroir) et études de cas (créer) du module. Veuillez ajouter les catégories dans la sous-page /documentation. Sous-pages de ce module. |
------------------------------------------------------------
-- Module:Episode/MultiSeries
-- Fusion SG1 + SGA + SGU
-- Normalisation, alias, indexation, cache, doublons
------------------------------------------------------------
local Multi = {}
------------------------------------------------------------
-- 1. Cache anti-signal-24
------------------------------------------------------------
if package.loaded["Module:Episode/MultiSeries"] then
return package.loaded["Module:Episode/MultiSeries"]
end
------------------------------------------------------------
-- 2. Chargement des séries
------------------------------------------------------------
local SG1 = require("Module:Episode/SG1")
local SGA = require("Module:Episode/SGA")
local SGU = require("Module:Episode/SGU")
------------------------------------------------------------
-- 3. Tables globales
------------------------------------------------------------
Multi.episodes = {}
Multi.by_id = {}
Multi.by_alias = {}
Multi.by_page = {}
Multi.by_series = {}
Multi.by_season = {}
------------------------------------------------------------
-- 4. Fonction normalize() finale
------------------------------------------------------------
local function normalize(str)
if not str then return "" end
str = mw.ustring.lower(str)
str = mw.ustring.toNFD(str)
str = mw.ustring.gsub(str, "%pM", "")
str = str:gsub("'%s*", "")
str = str:gsub("[{}]", " ")
str = str:gsub("[%p]", " ")
str = str:gsub("[^%w%s]", " ")
str = str:gsub("%s+", " ")
str = mw.text.trim(str)
return str
end
------------------------------------------------------------
-- 5. Alias techniques SGX
------------------------------------------------------------
local function make_tech_aliases(series, season, episode)
local s = string.format("%02d", tonumber(season))
local e = string.format("%02d", tonumber(episode))
series = normalize(series)
return {
string.format("%s s%se%s", series, s, e),
string.format("%s %sx%s", series, s, e),
string.format("%s %s%s", series, s, e),
}
end
------------------------------------------------------------
-- 6. Génération complète des alias
------------------------------------------------------------
local function make_aliases(ep)
local a = {}
-- titres normalisés
table.insert(a, normalize(ep.title_fr))
table.insert(a, normalize(ep.title_en))
-- id normalisé
table.insert(a, normalize(ep.id))
-- alias techniques
for _, alias in ipairs(make_tech_aliases(ep.series, ep.season, ep.episode)) do
table.insert(a, alias)
end
-- extra_aliases
if ep.extra_aliases then
for _, alias in ipairs(ep.extra_aliases) do
table.insert(a, normalize(alias))
end
end
return a
end
------------------------------------------------------------
-- 7. Ajout d'une série complète
------------------------------------------------------------
local function append_series(series_module)
for _, ep in ipairs(series_module.episodes or {}) do
----------------------------------------------------
-- Génération des alias
----------------------------------------------------
ep.aliases = make_aliases(ep)
----------------------------------------------------
-- Index par ID
----------------------------------------------------
Multi.by_id[ep.id] = ep
----------------------------------------------------
-- Index par page (FR + EN)
----------------------------------------------------
if ep.page_title_fr then
Multi.by_page[normalize(ep.page_title_fr)] = ep
end
if ep.page_title_en then
Multi.by_page[normalize(ep.page_title_en)] = ep
end
----------------------------------------------------
-- Index par alias
----------------------------------------------------
for _, alias in ipairs(ep.aliases) do
alias = normalize(alias)
Multi.by_alias[alias] = Multi.by_alias[alias] or {}
table.insert(Multi.by_alias[alias], ep)
end
----------------------------------------------------
-- Index par série
----------------------------------------------------
Multi.by_series[ep.series] = Multi.by_series[ep.series] or {}
table.insert(Multi.by_series[ep.series], ep)
----------------------------------------------------
-- Index par saison
----------------------------------------------------
local key = ep.series .. "-" .. ep.season
Multi.by_season[key] = Multi.by_season[key] or {}
table.insert(Multi.by_season[key], ep)
----------------------------------------------------
-- Ajout à la liste globale
----------------------------------------------------
table.insert(Multi.episodes, ep)
end
end
------------------------------------------------------------
-- 8. Fusion des séries
------------------------------------------------------------
append_series(SG1)
append_series(SGA)
append_series(SGU)
------------------------------------------------------------
-- 9. Cache final
------------------------------------------------------------
package.loaded["Module:Episode/MultiSeries"] = Multi
return Multi