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
 
(2 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
-- Module:Episode
local p = {}
-- API publique pour accéder aux épisodes (toutes séries confondues)
-- Utilise Module:Episode/MultiSeries comme backend


-- Centralized Episode Index (multi-series, episodes + movies)
local Index = require("Module:Episode/MultiSeries")
local Index = require("Module:Episode/MultiSeries")

local p = {}


------------------------------------------------------------
------------------------------------------------------------
-- Récupère une entrée d’épisode depuis un argument
-- Internal helper: retrieve episode entry from key
------------------------------------------------------------
------------------------------------------------------------
local function getEntry(frame)
local function getEntry(frame)
Ligne 12 : Ligne 15 :
return nil
return nil
end
end

return Index.get(key)
-- Recherche par ID direct ou alias
return Index.get(key) or Index.get_by_alias(key)
end
end


------------------------------------------------------------
------------------------------------------------------------
-- Prétraitement du titre (parser)
-- Internal helper: preprocess a title using the parser
-- Falls back gracefully if title is missing.
------------------------------------------------------------
------------------------------------------------------------
local function preprocessTitle(frame, ep)
local function preprocessTitle(frame, ep)
Ligne 25 : Ligne 29 :


------------------------------------------------------------
------------------------------------------------------------
-- Construction d’un lien d’épisode
-- Internal helper: build a link using the episode namespace
-- If namespace is empty (movies), omit it.
-- Title is always preprocessed here.
------------------------------------------------------------
------------------------------------------------------------
local function buildEpisodeLink(frame, ep, labelOverride)
local function buildEpisodeLink(frame, ep, labelOverride)
Ligne 33 : Ligne 35 :


if ep.namespace == "" or ep.namespace == nil then
if ep.namespace == "" or ep.namespace == nil then
-- Movies and telefilms: no namespace
-- Films / téléfilms
return string.format("[[%s|%s]]", ep.page_title, title)
return string.format("[[%s|%s]]", ep.page_title, title)
else
else
-- Regular episodes: use namespace
-- Épisodes normaux
return string.format("[[%s:%s|%s]]", ep.namespace, ep.page_title, title)
return string.format("[[%s:%s|%s]]", ep.namespace, ep.page_title, title)
end
end
Ligne 42 : Ligne 44 :


------------------------------------------------------------
------------------------------------------------------------
-- 1. Lien normal vers l’épisode
-- Function 1: Get full episode link (default namespace)
-- Uses preprocessed French title as label.
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisode(frame)
function p.getEpisode(frame)
Ligne 54 : Ligne 55 :


------------------------------------------------------------
------------------------------------------------------------
-- Function 2: Force namespace to "Crédits:"
-- 2. Lien vers Crédits:
-- Uses preprocessed French title as label.
------------------------------------------------------------
------------------------------------------------------------
function p.getCreditsLink(frame)
function p.getCreditsLink(frame)
Ligne 62 : Ligne 62 :
return "Épisode ou film non référencé"
return "Épisode ou film non référencé"
end
end

local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
return string.format("[[Crédits:%s|%s]]", ep.page_title, title)
return string.format("[[Crédits:%s|%s]]", ep.page_title, title)
Ligne 68 : Ligne 67 :


------------------------------------------------------------
------------------------------------------------------------
-- Function 3: Force namespace to "Retranscription:"
-- 3. Lien vers Retranscription:
-- Uses preprocessed French title as label.
------------------------------------------------------------
------------------------------------------------------------
function p.getTranscriptLink(frame)
function p.getTranscriptLink(frame)
Ligne 76 : Ligne 74 :
return "Épisode ou film non référencé"
return "Épisode ou film non référencé"
end
end

local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
return string.format("[[Retranscription:%s|%s]]", ep.page_title, title)
return string.format("[[Retranscription:%s|%s]]", ep.page_title, title)
Ligne 82 : Ligne 79 :


------------------------------------------------------------
------------------------------------------------------------
-- Function 4: Force namespace to "Citations:"
-- 4. Lien vers Citations:
-- Uses preprocessed French title as label.
------------------------------------------------------------
------------------------------------------------------------
function p.getQuotesLink(frame)
function p.getQuotesLink(frame)
Ligne 90 : Ligne 86 :
return "Épisode ou film non référencé"
return "Épisode ou film non référencé"
end
end

local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
return string.format("[[Citations:%s|%s]]", ep.page_title, title)
return string.format("[[Citations:%s|%s]]", ep.page_title, title)
Ligne 96 : Ligne 91 :


------------------------------------------------------------
------------------------------------------------------------
-- Function 5: Force namespace to "Catégorie:Images de ..."
-- 5. Lien vers Catégorie:Images de ...
-- Leading colon prevents categorization when used in articles.
-- Uses preprocessed French title as label.
------------------------------------------------------------
------------------------------------------------------------
function p.getImagesLink(frame)
function p.getImagesLink(frame)
Ligne 105 : Ligne 98 :
return "Épisode ou film non référencé"
return "Épisode ou film non référencé"
end
end

local title = preprocessTitle(frame, ep)
local title = preprocessTitle(frame, ep)
return string.format("[[:Catégorie:Images de %s|%s]]", ep.page_title, title)
return string.format("[[:Catégorie:Images de %s|%s]]", ep.page_title, title)
Ligne 111 : Ligne 103 :


------------------------------------------------------------
------------------------------------------------------------
-- Function 6: Retrieve only the page title (no namespace)
-- 6. Récupère uniquement le titre de page (sans namespace)
-- No preprocess needed here.
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeLink(frame)
function p.getEpisodeLink(frame)
Ligne 123 : Ligne 114 :


------------------------------------------------------------
------------------------------------------------------------
-- Function 7: Retrieve full link target (namespace + title)
-- 7. Récupère le lien complet (namespace + titre)
-- Example: "Épisode:Enfants des dieux"
-- Movies return only "Enfants des dieux".
-- No preprocess needed here.
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeFullLink(frame)
function p.getEpisodeFullLink(frame)
Ligne 142 : Ligne 130 :


------------------------------------------------------------
------------------------------------------------------------
-- 8. Récupère uniquement le titre français (prétraité)
-- Function 8: Retrieve only the French title (preprocessed)
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeTitle(frame)
function p.getEpisodeTitle(frame)
Ligne 153 : Ligne 141 :


------------------------------------------------------------
------------------------------------------------------------
-- 9. Numéro d’épisode (2 chiffres)
-- Function 9: Get the episode number as a two‑digit string
-- Returns "" for movies (no episode number)
------------------------------------------------------------
------------------------------------------------------------
function p.getEpisodeNumber(frame)
function p.getEpisodeNumber(frame)
Ligne 162 : Ligne 149 :
end
end


-- Movies and telefilms have no episode number
if not ep.episode or ep.episode == "" then
if not ep.episode or ep.episode == "" then
return ""
return ""
end
end


-- Format as two digits (01, 02, ..., 22)
return string.format("%02d", tonumber(ep.episode))
return string.format("%02d", tonumber(ep.episode))
end
end


------------------------------------------------------------
------------------------------------------------------------
-- 10. Numéro de saison
-- Function 10: Get the season number as a numeric string
-- Returns "" for movies (no season number)
------------------------------------------------------------
------------------------------------------------------------
function p.getSeasonNumber(frame)
function p.getSeasonNumber(frame)
Ligne 181 : Ligne 165 :
end
end


-- Movies and telefilms have no season number
if not ep.season or ep.season == "" then
if not ep.season or ep.season == "" then
return ""
return ""
end
end


-- Return numeric season (no formatting)
return tostring(ep.season)
return tostring(ep.season)
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

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
-- Paramètres :
-- serie = SG1 / SGA / SGU / Films
-- 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



Dernière version du 1 juin 2026 à 20:48

Documentation icon Documentation module[créer]
-- Module:Episode
-- API publique pour accéder aux épisodes (toutes séries confondues)
-- Utilise Module:Episode/MultiSeries comme backend

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

local p = {}

------------------------------------------------------------
-- 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

    -- Recherche par ID direct ou alias
    return Index.get(key) or Index.get_by_alias(key)
end

------------------------------------------------------------
-- 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

------------------------------------------------------------
-- Construction d’un lien d’épisode
------------------------------------------------------------
local function buildEpisodeLink(frame, ep, labelOverride)
    local title = labelOverride or preprocessTitle(frame, ep)

    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

------------------------------------------------------------
-- 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)
    return string.format("[[Crédits:%s|%s]]", ep.page_title, 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)
    return string.format("[[Retranscription:%s|%s]]", ep.page_title, 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)
    return string.format("[[Citations:%s|%s]]", ep.page_title, 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)
    return string.format("[[:Catégorie:Images de %s|%s]]", ep.page_title, 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
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

    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

------------------------------------------------------------
-- 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

    if not ep.episode or ep.episode == "" then
        return ""
    end

    return string.format("%02d", tonumber(ep.episode))
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

    if not ep.season or ep.season == "" then
        return ""
    end

    return tostring(ep.season)
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

    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
-- Paramètres :
--   serie  = SG1 / SGA / SGU / Films
--   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

return p