Aller au contenu

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

De Stargate Wiki Sémantique
Contenu supprimé Contenu ajouté
Aucun résumé des modifications
Aucun résumé des modifications
Ligne 1 : Ligne 1 :
------------------------------------------------------------
-- Module:Episode
-- Module:Episode
-- API publique pour accéder aux épisodes (toutes séries confondues)
-- API publique pour accéder aux épisodes Stargate
-- Utilise Module:Episode/MultiSeries comme backend
-- Utilise Module:Episode/MultiSeries (indexation complète)
------------------------------------------------------------

local Index = require("Module:Episode/MultiSeries")


local p = {}
local p = {}
local Multi = require("Module:Episode/MultiSeries")


------------------------------------------------------------
------------------------------------------------------------
-- Normalisation locale (même logique que MultiSeries)
-- Récupère une entrée d’épisode depuis un argument
------------------------------------------------------------
------------------------------------------------------------
local function getEntry(frame)
local function normalize(str)
if not str then return "" end
local key = frame.args[1]
if not key or key == "" then
return nil
end


str = mw.ustring.lower(str)
-- Recherche par ID direct ou alias
str = mw.ustring.toNFD(str)
return Index.get(key) or Index.get_by_alias(key)
str = mw.ustring.gsub(str, "%pM", "")
end
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
------------------------------------------------------------
-- Prétraitement du titre (parser)
------------------------------------------------------------
local function preprocessTitle(frame, ep)
local raw = ep.title_fr or ep.page_title or ep.property or ep.id or ""
return frame:preprocess(raw)
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Construction d’un lien d’épisode
-- Récupération d’un épisode par ID
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeById(id)
local function buildEpisodeLink(frame, ep, labelOverride)
if not id then return nil end
local title = labelOverride or preprocessTitle(frame, ep)
return Multi.by_id[id]

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


------------------------------------------------------------
------------------------------------------------------------
-- Récupération d’un épisode par alias
-- 1. Lien normal vers l’épisode
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisode(frame)
function p.getEpisodeByAlias(alias)
if not alias then return nil end
local ep = getEntry(frame)
alias = normalize(alias)
if not ep then
local list = Multi.by_alias[alias]
return "Épisode ou film non référencé"
if not list then return nil end
end
return buildEpisodeLink(frame, ep)
end


-- Si un seul épisode correspond → renvoyer directement
------------------------------------------------------------
if #list == 1 then
-- 2. Lien vers Crédits:
return list[1]
------------------------------------------------------------
function p.getCreditsLink(frame)
local ep = getEntry(frame)
if not ep then
return "Épisode ou film non référencé"
end
end
local title = preprocessTitle(frame, ep)
return string.format("[[Crédits:%s|%s]]", ep.page_title, title)
end


-- Sinon renvoyer la liste complète (ambiguïté)
------------------------------------------------------------
return list
-- 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)
return string.format("[[Retranscription:%s|%s]]", ep.page_title, title)
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Récupération d’un épisode par titre de page
-- 4. Lien vers Citations:
------------------------------------------------------------
------------------------------------------------------------
function p.getQuotesLink(frame)
function p.getEpisodeByPage(page)
if not page then return nil end
local ep = getEntry(frame)
return Multi.by_page[normalize(page)]
if not ep then
return "Épisode ou film non référencé"
end
local title = preprocessTitle(frame, ep)
return string.format("[[Citations:%s|%s]]", ep.page_title, title)
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Récupération d’un épisode par série + saison + numéro
-- 5. Lien vers Catégorie:Images de ...
------------------------------------------------------------
------------------------------------------------------------
function p.getImagesLink(frame)
function p.getEpisode(series, season, episode)
if not (series and season and episode) then return nil end
local ep = getEntry(frame)
if not ep then
return "Épisode ou film non référencé"
end
local title = preprocessTitle(frame, ep)
return string.format("[[:Catégorie:Images de %s|%s]]", ep.page_title, title)
end


local key = series .. "-" .. season
------------------------------------------------------------
local list = Multi.by_season[key]
-- 6. Récupère uniquement le titre de page (sans namespace)
if not list then return nil end
------------------------------------------------------------
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
end


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


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


------------------------------------------------------------
------------------------------------------------------------
-- Génération d’un lien vers l’épisode
-- 8. Récupère uniquement le titre français (prétraité)
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeTitle(frame)
function p.getEpisodeLink(ep)
local ep = getEntry(frame)
if not ep then return "" end
return string.format("[[%s:%s]]", ep.namespace_fr or "Épisode", ep.page_title_fr)
if not ep then
return "Épisode ou film non référencé"
end
return preprocessTitle(frame, ep)
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Génération d’un lien complet (FR + EN)
-- 9. Numéro d’épisode (2 chiffres)
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeNumber(frame)
function p.getEpisodeFullLink(ep)
local ep = getEntry(frame)
if not ep then return "" end
if not ep then
return "Épisode ou film non référencé"
end


local fr = string.format("[[%s:%s|%s]]",
if not ep.episode or ep.episode == "" then
return ""
ep.namespace_fr or "Épisode",
ep.page_title_fr,
end
ep.title_fr or ep.page_title_fr
)


return string.format("%02d", tonumber(ep.episode))
local en = string.format("[[%s:%s|%s]]",
ep.namespace_en or "Episode",
ep.page_title_en,
ep.title_en or ep.page_title_en
)

return fr .. " / " .. en
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Raccourcis API pour #invoke
-- 10. Numéro de saison
------------------------------------------------------------
------------------------------------------------------------
function p.getSeasonNumber(frame)
function p.id(frame)
local ep = getEntry(frame)
local id = frame.args[1] or frame.args.id
if not ep then
local ep = p.getEpisodeById(id)
return "Épisode ou film non référencé"
if not ep then return "" end
return p.getEpisodeLink(ep)
end
end


function p.alias(frame)
if not ep.season or ep.season == "" then
local alias = frame.args[1] or frame.args.alias
return ""
local ep = p.getEpisodeByAlias(alias)
end
if not ep then return "" end


if type(ep) == "table" and ep.id then
return tostring(ep.season)
return p.getEpisodeLink(ep)
end

------------------------------------------------------------
-- 11. Rapport lisible des doublons
------------------------------------------------------------
function p.debugDuplicates(frame)
local d = Index.duplicates
if not d then
return "Aucun rapport de doublons disponible"
end
end


-- Ambiguïté : renvoyer la liste
local out = {}
local out = {}
for _, e in ipairs(ep) do

table.insert(out, "== Doublons d’ID ==")
table.insert(out, p.getEpisodeLink(e))
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
end
return table.concat(out, " • ")

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
end


function p.page(frame)
------------------------------------------------------------
local page = frame.args[1] or frame.args.page
-- 12. Génération d’une liste d’épisodes
local ep = p.getEpisodeByPage(page)
-- Paramètres :
-- serie = SG1 / SGA / SGU / Films
if not ep then return "" end
return p.getEpisodeLink(ep)
-- saison = numéro de saison (optionnel)
-- liste = liste d’IDs séparés par des virgules (optionnel)
------------------------------------------------------------
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 (liste = "SG1-S01E01, SG1-S01E02")
------------------------------------------------------------
if liste and liste ~= "" then
for id in mw.text.gsplit(liste, ",") do
id = mw.text.trim(id)
local ep = Index.get(id) or Index.get_by_alias(id)
if ep then
table.insert(out, "* " .. ep.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 id, ep in pairs(Index.episodes) do
if ep.series == serie and ep.season == saison then
table.insert(out, { sort = ep.episode, text = "* " .. ep.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 id, ep in pairs(Index.episodes) do
if ep.series == serie then
table.insert(out, { sort = ep.season * 100 + ep.episode, text = "* " .. ep.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
end



Version du 2 juin 2026 à 14:50

Documentation icon Documentation module[créer]
------------------------------------------------------------
-- Module:Episode
-- API publique pour accéder aux épisodes Stargate
-- Utilise Module:Episode/MultiSeries (indexation complète)
------------------------------------------------------------

local p = {}
local Multi = require("Module:Episode/MultiSeries")

------------------------------------------------------------
-- Normalisation locale (même logique que MultiSeries)
------------------------------------------------------------
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

------------------------------------------------------------
-- Récupération d’un épisode par ID
------------------------------------------------------------
function p.getEpisodeById(id)
    if not id then return nil end
    return Multi.by_id[id]
end

------------------------------------------------------------
-- Récupération d’un épisode par alias
------------------------------------------------------------
function p.getEpisodeByAlias(alias)
    if not alias then return nil end
    alias = normalize(alias)
    local list = Multi.by_alias[alias]
    if not list then return nil end

    -- Si un seul épisode correspond → renvoyer directement
    if #list == 1 then
        return list[1]
    end

    -- Sinon renvoyer la liste complète (ambiguïté)
    return list
end

------------------------------------------------------------
-- Récupération d’un épisode par titre de page
------------------------------------------------------------
function p.getEpisodeByPage(page)
    if not page then return nil end
    return Multi.by_page[normalize(page)]
end

------------------------------------------------------------
-- Récupération d’un épisode par série + saison + numéro
------------------------------------------------------------
function p.getEpisode(series, season, episode)
    if not (series and season and episode) then return nil end

    local key = series .. "-" .. season
    local list = Multi.by_season[key]
    if not list then return nil end

    for _, ep in ipairs(list) do
        if ep.episode == tonumber(episode) then
            return ep
        end
    end

    return nil
end

------------------------------------------------------------
-- Génération d’un lien vers l’épisode
------------------------------------------------------------
function p.getEpisodeLink(ep)
    if not ep then return "" end
    return string.format("[[%s:%s]]", ep.namespace_fr or "Épisode", ep.page_title_fr)
end

------------------------------------------------------------
-- Génération d’un lien complet (FR + EN)
------------------------------------------------------------
function p.getEpisodeFullLink(ep)
    if not ep then return "" end

    local fr = string.format("[[%s:%s|%s]]",
        ep.namespace_fr or "Épisode",
        ep.page_title_fr,
        ep.title_fr or ep.page_title_fr
    )

    local en = string.format("[[%s:%s|%s]]",
        ep.namespace_en or "Episode",
        ep.page_title_en,
        ep.title_en or ep.page_title_en
    )

    return fr .. " / " .. en
end

------------------------------------------------------------
-- Raccourcis API pour #invoke
------------------------------------------------------------
function p.id(frame)
    local id = frame.args[1] or frame.args.id
    local ep = p.getEpisodeById(id)
    if not ep then return "" end
    return p.getEpisodeLink(ep)
end

function p.alias(frame)
    local alias = frame.args[1] or frame.args.alias
    local ep = p.getEpisodeByAlias(alias)
    if not ep then return "" end

    if type(ep) == "table" and ep.id then
        return p.getEpisodeLink(ep)
    end

    -- Ambiguïté : renvoyer la liste
    local out = {}
    for _, e in ipairs(ep) do
        table.insert(out, p.getEpisodeLink(e))
    end
    return table.concat(out, " • ")
end

function p.page(frame)
    local page = frame.args[1] or frame.args.page
    local ep = p.getEpisodeByPage(page)
    if not ep then return "" end
    return p.getEpisodeLink(ep)
end

return p