Aller au contenu

« Module:Episode » : différence entre les versions

De Stargate Wiki Sémantique
Contenu supprimé Contenu ajouté
Aucun résumé des modifications
m LIMAFOX76 a déplacé la page Module:Episode REAL vers Module:Episode sans laisser de redirection
 
(19 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
------------------------------------------------------------
------------------------------------------------------------
-- SCAN COMPLET DE package.loaded
-- Module:Episode
------------------------------------------------------------

local out = {"=== SCAN package.loaded ==="}

for k,v in pairs(package.loaded) do
if tostring(k):match("Episode") then
table.insert(out, tostring(k) .. " = " .. tostring(v))
end
end

mw.log(table.concat(out, "\n"))

------------------------------------------------------------
-- DIAGNOSTIC SAFE — n'affecte pas le module
------------------------------------------------------------

local function dump_table(t)
if type(t) ~= "table" then
return tostring(t)
end
local out = {}
for k,v in pairs(t) do
table.insert(out, tostring(k) .. "=" .. tostring(v))
end
return "{ " .. table.concat(out, ", ") .. " }"
end

local name = "Module:Episode/MultiSeries"

local before = package.loaded[name]
local ok, result = pcall(require, name)
local after = package.loaded[name]

mw.log("=== DIAGNOSTIC SAFE ===")
mw.log("Nom require() = >" .. name .. "<")
mw.log("--- AVANT require() ---")
mw.log(tostring(before))
mw.log("--- RESULTAT require() ---")
mw.log("pcall ok = " .. tostring(ok))
mw.log("result = " .. tostring(result))
mw.log("type(result) = " .. type(result))
mw.log("--- APRES require() ---")
mw.log(tostring(after))
mw.log("--- package.loaded[name] ---")
mw.log(tostring(package.loaded[name]))

------------------------------------------------------------
-- Module:Episode (ULTRA OPTIMISÉ AVEC CACHE GLOBAL)
-- API publique pour accéder aux épisodes (toutes séries)
-- API publique pour accéder aux épisodes (toutes séries)
-- Backend : Module:Episode/MultiSeries
-- Backend : Module:Episode/MultiSeries
Ligne 6 : Ligne 54 :


local Index = require("Module:Episode/MultiSeries")
local Index = require("Module:Episode/MultiSeries")
local normalize = Index.normalize
local p = {}
local p = {}

------------------------------------------------------------
-- CACHE GLOBAL (résultats mémorisés par page)
------------------------------------------------------------
local CACHE = {
entry = {}, -- ID/alias → ep
title = {}, -- id → titre prétraité
link = {}, -- id → lien [[...]]
full = {}, -- id → namespace:page
number = {}, -- id → numéro d’épisode
season = {}, -- id → numéro de saison
}


------------------------------------------------------------
------------------------------------------------------------
Ligne 17 : Ligne 78 :
end
end


-- Recherche par ID direct ou alias
-- Cache direct
return Index.get(key) or Index.get_by_alias(key)
if CACHE.entry[key] ~= nil then
return CACHE.entry[key]
end

-- Normalisation identique à MultiSeries
local norm = normalize(key)

-- 1) Recherche par ID exact
if Index.by_id[key] then
CACHE.entry[key] = Index.by_id[key]
return CACHE.entry[key]
end

-- 2) Recherche par alias normalisé
local list = Index.by_alias[norm]
if list and list[1] then
CACHE.entry[key] = list[1]
return CACHE.entry[key]
end

CACHE.entry[key] = nil
return nil
end
end


Ligne 25 : Ligne 107 :
------------------------------------------------------------
------------------------------------------------------------
local function preprocessTitle(frame, ep)
local function preprocessTitle(frame, ep)
local raw =
local id = ep.id
ep.title_fr
or ep.page_title
or ep.property
or ep.id
or ""


if CACHE.title[id] then
return frame:preprocess(raw)
return CACHE.title[id]
end

local raw = ep.title_fr or ep.page_title_fr or ep.id or ""
local parsed = frame:preprocess(raw)

CACHE.title[id] = parsed
return parsed
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Construction d’un lien d’épisode
-- Construction d’un lien d’épisode (sécurisé)
------------------------------------------------------------
------------------------------------------------------------
local function buildEpisodeLink(frame, ep, labelOverride)
local function buildEpisodeLink(frame, ep, labelOverride)
local id = ep.id

-- Cache si pas de label personnalisé
if not labelOverride and CACHE.link[id] then
return CACHE.link[id]
end

local title = labelOverride or preprocessTitle(frame, ep)
local title = labelOverride or preprocessTitle(frame, ep)
local page = ep.page_title_fr or ep.id


local link
if not ep.namespace or ep.namespace == "" then
if not ep.namespace_fr or ep.namespace_fr == "" then
-- Films / téléfilms
-- Films
return string.format("[[%s|%s]]", ep.page_title, title)
link = string.format("[[%s|%s]]", page, title)
else
else
-- Épisodes normaux
-- Épisodes normaux
return string.format("[[%s:%s|%s]]", ep.namespace, ep.page_title, title)
link = string.format("[[%s:%s|%s]]", ep.namespace_fr, page, title)
end
end

if not labelOverride then
CACHE.link[id] = link
end

return link
end
end


Ligne 55 : Ligne 155 :
function p.getEpisode(frame)
function p.getEpisode(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end
return "Épisode ou film non référencé"
end
return buildEpisodeLink(frame, ep)
return buildEpisodeLink(frame, ep)
end
end
Ligne 66 : Ligne 164 :
function p.getCreditsLink(frame)
function p.getCreditsLink(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end

return "Épisode ou film non référencé"
end
local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
local page = ep.page_title_fr or ep.id
return string.format("[[Crédits:%s|%s]]", ep.page_title, title)

return string.format("[[Crédits:%s|%s]]", page, title)
end
end


Ligne 78 : Ligne 177 :
function p.getTranscriptLink(frame)
function p.getTranscriptLink(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end

return "Épisode ou film non référencé"
end
local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
local page = ep.page_title_fr or ep.id
return string.format("[[Retranscription:%s|%s]]", ep.page_title, title)

return string.format("[[Retranscription:%s|%s]]", page, title)
end
end


Ligne 90 : Ligne 190 :
function p.getQuotesLink(frame)
function p.getQuotesLink(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end

return "Épisode ou film non référencé"
end
local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
local page = ep.page_title_fr or ep.id
return string.format("[[Citations:%s|%s]]", ep.page_title, title)

return string.format("[[Citations:%s|%s]]", page, title)
end
end


Ligne 102 : Ligne 203 :
function p.getImagesLink(frame)
function p.getImagesLink(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end

return "Épisode ou film non référencé"
end
local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
local page = ep.page_title_fr or ep.id
return string.format("[[:Catégorie:Images de %s|%s]]", ep.page_title, title)

return string.format("[[:Catégorie:Images de %s|%s]]", page, title)
end
end


Ligne 114 : Ligne 216 :
function p.getEpisodeLink(frame)
function p.getEpisodeLink(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end
return "Épisode ou film non référencé"
return ep.page_title_fr or ep.id
end
return ep.page_title
end
end


Ligne 125 : Ligne 225 :
function p.getEpisodeFullLink(frame)
function p.getEpisodeFullLink(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end

return "Épisode ou film non référencé"
local id = ep.id
if CACHE.full[id] then
return CACHE.full[id]
end
end


if not ep.namespace or ep.namespace == "" then
local page = ep.page_title_fr or ep.id
local full
return ep.page_title

if not ep.namespace_fr or ep.namespace_fr == "" then
full = page
else
else
return string.format("%s:%s", ep.namespace, ep.page_title)
full = string.format("%s:%s", ep.namespace_fr, page)
end
end

CACHE.full[id] = full
return full
end
end


Ligne 141 : Ligne 250 :
function p.getEpisodeTitle(frame)
function p.getEpisodeTitle(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end
return "Épisode ou film non référencé"
end
return preprocessTitle(frame, ep)
return preprocessTitle(frame, ep)
end
end
Ligne 152 : Ligne 259 :
function p.getEpisodeNumber(frame)
function p.getEpisodeNumber(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end

return "Épisode ou film non référencé"
local id = ep.id
if CACHE.number[id] then
return CACHE.number[id]
end
end


if not ep.episode or ep.episode == "" then
local n = tonumber(ep.episode)
return ""
local out = n and string.format("%02d", n) or ""
end


CACHE.number[id] = out
return string.format("%02d", tonumber(ep.episode))
return out
end
end


Ligne 168 : Ligne 278 :
function p.getSeasonNumber(frame)
function p.getSeasonNumber(frame)
local ep = getEntry(frame)
local ep = getEntry(frame)
if not ep then
if not ep then return "Épisode ou film non référencé" end
return "Épisode ou film non référencé"
end


if not ep.season or ep.season == "" then
local id = ep.id
if CACHE.season[id] then
return ""
return CACHE.season[id]
end
end


return tostring(ep.season)
local out = ep.season and tostring(ep.season) or ""
CACHE.season[id] = out
return out
end
end


------------------------------------------------------------
------------------------------------------------------------
-- 12. Génération d’une liste d’épisodes (films-safe)
-- 11. Rapport lisible des doublons
------------------------------------------------------------
function p.debugDuplicates(frame)
local d = Index.duplicates
if not d then
return "Aucun rapport de doublons disponible"
end

local out = {}

table.insert(out, "== Doublons d’ID ==")
if #d.duplicate_ids == 0 then
table.insert(out, "Aucun")
else
for _, id in ipairs(d.duplicate_ids) do
table.insert(out, "* " .. id)
end
end

table.insert(out, "\n== Alias dupliqués ==")
if #d.duplicate_aliases == 0 then
table.insert(out, "Aucun")
else
for _, alias in ipairs(d.duplicate_aliases) do
table.insert(out, "* " .. alias)
end
end

table.insert(out, "\n== Alias contradictoires ==")
if #d.conflicting_aliases == 0 then
table.insert(out, "Aucun")
else
for _, c in ipairs(d.conflicting_aliases) do
table.insert(out, "* " .. c.alias .. " → " .. c.id1 .. " / " .. c.id2)
end
end

return table.concat(out, "\n")
end

------------------------------------------------------------
-- 12. Génération d’une liste d’épisodes
------------------------------------------------------------
------------------------------------------------------------
function p.renderList(frame)
function p.renderList(frame)
Ligne 236 : Ligne 306 :
for id in mw.text.gsplit(liste, ",") do
for id in mw.text.gsplit(liste, ",") do
id = mw.text.trim(id)
id = mw.text.trim(id)

local ep = Index.get(id) or Index.get_by_alias(id)
local ep =
Index.by_id[id]
or (Index.by_alias[id] and Index.by_alias[id][1])

if ep then
if ep then
table.insert(out, "* " .. frame:preprocess(ep.title_fr))
table.insert(out, "* " .. frame:preprocess(ep.title_fr or ep.page_title_fr))
else
else
table.insert(out, "* (inconnu) " .. id)
table.insert(out, "* (inconnu) " .. id)
Ligne 253 : Ligne 327 :
if ep.series == serie and ep.season == saison then
if ep.series == serie and ep.season == saison then
table.insert(out, {
table.insert(out, {
sort = ep.episode,
sort = tonumber(ep.episode) or 0,
text = "* " .. frame:preprocess(ep.title_fr)
text = "* " .. frame:preprocess(ep.title_fr or ep.page_title_fr)
})
})
end
end
Ligne 275 : Ligne 349 :
for _, ep in pairs(Index.episodes) do
for _, ep in pairs(Index.episodes) do
if ep.series == serie then
if ep.series == serie then
local s = (tonumber(ep.season) or 0) * 100 + (tonumber(ep.episode) or 0)
table.insert(out, {
table.insert(out, {
sort = ep.season * 100 + ep.episode,
sort = s,
text = "* " .. frame:preprocess(ep.title_fr)
text = "* " .. frame:preprocess(ep.title_fr or ep.page_title_fr)
})
})
end
end

Dernière version du 3 juin 2026 à 14:15

Documentation icon Documentation module[créer]
------------------------------------------------------------
-- SCAN COMPLET DE package.loaded
------------------------------------------------------------

local out = {"=== SCAN package.loaded ==="}

for k,v in pairs(package.loaded) do
    if tostring(k):match("Episode") then
        table.insert(out, tostring(k) .. " = " .. tostring(v))
    end
end

mw.log(table.concat(out, "\n"))

------------------------------------------------------------
-- DIAGNOSTIC SAFE — n'affecte pas le module
------------------------------------------------------------

local function dump_table(t)
    if type(t) ~= "table" then
        return tostring(t)
    end
    local out = {}
    for k,v in pairs(t) do
        table.insert(out, tostring(k) .. "=" .. tostring(v))
    end
    return "{ " .. table.concat(out, ", ") .. " }"
end

local name = "Module:Episode/MultiSeries"

local before = package.loaded[name]
local ok, result = pcall(require, name)
local after = package.loaded[name]

mw.log("=== DIAGNOSTIC SAFE ===")
mw.log("Nom require() = >" .. name .. "<")
mw.log("--- AVANT require() ---")
mw.log(tostring(before))
mw.log("--- RESULTAT require() ---")
mw.log("pcall ok = " .. tostring(ok))
mw.log("result = " .. tostring(result))
mw.log("type(result) = " .. type(result))
mw.log("--- APRES require() ---")
mw.log(tostring(after))
mw.log("--- package.loaded[name] ---")
mw.log(tostring(package.loaded[name]))

------------------------------------------------------------
-- Module:Episode (ULTRA OPTIMISÉ AVEC CACHE GLOBAL)
-- API publique pour accéder aux épisodes (toutes séries)
-- Backend : Module:Episode/MultiSeries
------------------------------------------------------------

local Index = require("Module:Episode/MultiSeries")
local normalize = Index.normalize
local p = {}

------------------------------------------------------------
-- CACHE GLOBAL (résultats mémorisés par page)
------------------------------------------------------------
local CACHE = {
    entry  = {},   -- ID/alias → ep
    title  = {},   -- id → titre prétraité
    link   = {},   -- id → lien [[...]]
    full   = {},   -- id → namespace:page
    number = {},   -- id → numéro d’épisode
    season = {},   -- id → numéro de saison
}

------------------------------------------------------------
-- Récupère une entrée d’épisode depuis un argument
------------------------------------------------------------
local function getEntry(frame)
    local key = frame.args[1]
    if not key or key == "" then
        return nil
    end

    -- Cache direct
    if CACHE.entry[key] ~= nil then
        return CACHE.entry[key]
    end

    -- Normalisation identique à MultiSeries
    local norm = normalize(key)

    -- 1) Recherche par ID exact
    if Index.by_id[key] then
        CACHE.entry[key] = Index.by_id[key]
        return CACHE.entry[key]
    end

    -- 2) Recherche par alias normalisé
    local list = Index.by_alias[norm]
    if list and list[1] then
        CACHE.entry[key] = list[1]
        return CACHE.entry[key]
    end

    CACHE.entry[key] = nil
    return nil
end

------------------------------------------------------------
-- Prétraitement du titre (parser)
------------------------------------------------------------
local function preprocessTitle(frame, ep)
    local id = ep.id

    if CACHE.title[id] then
        return CACHE.title[id]
    end

    local raw = ep.title_fr or ep.page_title_fr or ep.id or ""
    local parsed = frame:preprocess(raw)

    CACHE.title[id] = parsed
    return parsed
end

------------------------------------------------------------
-- Construction d’un lien d’épisode (sécurisé)
------------------------------------------------------------
local function buildEpisodeLink(frame, ep, labelOverride)
    local id = ep.id

    -- Cache si pas de label personnalisé
    if not labelOverride and CACHE.link[id] then
        return CACHE.link[id]
    end

    local title = labelOverride or preprocessTitle(frame, ep)
    local page  = ep.page_title_fr or ep.id

    local link
    if not ep.namespace_fr or ep.namespace_fr == "" then
        -- Films
        link = string.format("[[%s|%s]]", page, title)
    else
        -- Épisodes normaux
        link = string.format("[[%s:%s|%s]]", ep.namespace_fr, page, title)
    end

    if not labelOverride then
        CACHE.link[id] = link
    end

    return link
end

------------------------------------------------------------
-- 1. Lien normal vers l’épisode
------------------------------------------------------------
function p.getEpisode(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end
    return buildEpisodeLink(frame, ep)
end

------------------------------------------------------------
-- 2. Lien vers Crédits:
------------------------------------------------------------
function p.getCreditsLink(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local title = preprocessTitle(frame, ep)
    local page  = ep.page_title_fr or ep.id

    return string.format("[[Crédits:%s|%s]]", page, title)
end

------------------------------------------------------------
-- 3. Lien vers Retranscription:
------------------------------------------------------------
function p.getTranscriptLink(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local title = preprocessTitle(frame, ep)
    local page  = ep.page_title_fr or ep.id

    return string.format("[[Retranscription:%s|%s]]", page, title)
end

------------------------------------------------------------
-- 4. Lien vers Citations:
------------------------------------------------------------
function p.getQuotesLink(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local title = preprocessTitle(frame, ep)
    local page  = ep.page_title_fr or ep.id

    return string.format("[[Citations:%s|%s]]", page, title)
end

------------------------------------------------------------
-- 5. Lien vers Catégorie:Images de ...
------------------------------------------------------------
function p.getImagesLink(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local title = preprocessTitle(frame, ep)
    local page  = ep.page_title_fr or ep.id

    return string.format("[[:Catégorie:Images de %s|%s]]", page, title)
end

------------------------------------------------------------
-- 6. Récupère uniquement le titre de page (sans namespace)
------------------------------------------------------------
function p.getEpisodeLink(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end
    return ep.page_title_fr or ep.id
end

------------------------------------------------------------
-- 7. Récupère le lien complet (namespace + titre)
------------------------------------------------------------
function p.getEpisodeFullLink(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local id = ep.id
    if CACHE.full[id] then
        return CACHE.full[id]
    end

    local page = ep.page_title_fr or ep.id
    local full

    if not ep.namespace_fr or ep.namespace_fr == "" then
        full = page
    else
        full = string.format("%s:%s", ep.namespace_fr, page)
    end

    CACHE.full[id] = full
    return full
end

------------------------------------------------------------
-- 8. Récupère uniquement le titre français (prétraité)
------------------------------------------------------------
function p.getEpisodeTitle(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end
    return preprocessTitle(frame, ep)
end

------------------------------------------------------------
-- 9. Numéro d’épisode (2 chiffres)
------------------------------------------------------------
function p.getEpisodeNumber(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local id = ep.id
    if CACHE.number[id] then
        return CACHE.number[id]
    end

    local n = tonumber(ep.episode)
    local out = n and string.format("%02d", n) or ""

    CACHE.number[id] = out
    return out
end

------------------------------------------------------------
-- 10. Numéro de saison
------------------------------------------------------------
function p.getSeasonNumber(frame)
    local ep = getEntry(frame)
    if not ep then return "Épisode ou film non référencé" end

    local id = ep.id
    if CACHE.season[id] then
        return CACHE.season[id]
    end

    local out = ep.season and tostring(ep.season) or ""
    CACHE.season[id] = out
    return out
end

------------------------------------------------------------
-- 12. Génération d’une liste d’épisodes (films-safe)
------------------------------------------------------------
function p.renderList(frame)
    local serie  = frame.args["serie"]
    local saison = tonumber(frame.args["saison"])
    local liste  = frame.args["liste"]

    local out = {}

    ------------------------------------------------------------
    -- Mode 1 : liste personnalisée
    ------------------------------------------------------------
    if liste and liste ~= "" then
        for id in mw.text.gsplit(liste, ",") do
            id = mw.text.trim(id)

            local ep =
                Index.by_id[id]
                or (Index.by_alias[id] and Index.by_alias[id][1])

            if ep then
                table.insert(out, "* " .. frame:preprocess(ep.title_fr or ep.page_title_fr))
            else
                table.insert(out, "* (inconnu) " .. id)
            end
        end
        return table.concat(out, "\n")
    end

    ------------------------------------------------------------
    -- Mode 2 : série + saison
    ------------------------------------------------------------
    if serie and saison then
        for _, ep in pairs(Index.episodes) do
            if ep.series == serie and ep.season == saison then
                table.insert(out, {
                    sort = tonumber(ep.episode) or 0,
                    text = "* " .. frame:preprocess(ep.title_fr or ep.page_title_fr)
                })
            end
        end

        table.sort(out, function(a,b) return a.sort < b.sort end)

        local lines = {}
        for _, item in ipairs(out) do
            table.insert(lines, item.text)
        end

        return table.concat(lines, "\n")
    end

    ------------------------------------------------------------
    -- Mode 3 : série complète
    ------------------------------------------------------------
    if serie then
        for _, ep in pairs(Index.episodes) do
            if ep.series == serie then
                local s = (tonumber(ep.season) or 0) * 100 + (tonumber(ep.episode) or 0)
                table.insert(out, {
                    sort = s,
                    text = "* " .. frame:preprocess(ep.title_fr or ep.page_title_fr)
                })
            end
        end

        table.sort(out, function(a,b) return a.sort < b.sort end)

        local lines = {}
        for _, item in ipairs(out) do
            table.insert(lines, item.text)
        end

        return table.concat(lines, "\n")
    end

    return "Aucun paramètre valide fourni."
end

return p