Модуль:CargoConverter: различия между версиями
Перейти к навигации
Перейти к поиску
Lord (обсуждение | вклад) Нет описания правки |
Lord (обсуждение | вклад) Нет описания правки |
||
| Строка 8: | Строка 8: | ||
end | end | ||
-- Вспомогательная функция для оборачивания вывода в | -- Вспомогательная функция для оборачивания вывода в аккуратный scroll-бокс | ||
local function wrap_output(text) | local function wrap_output(text) | ||
-- | -- Используем только разрешенные в MediaWiki теги <div> и <pre> | ||
-- | -- Задаем ограничение по высоте (max-height), рамку и авто-прокрутку | ||
return '<div style="' .. | |||
'max-height: 400px; ' .. | |||
return '< | 'overflow: auto; ' .. | ||
' | |||
' | |||
'border: 1px solid #a2a9b1; ' .. | 'border: 1px solid #a2a9b1; ' .. | ||
'background-color: #f8f9fa; ' .. | 'background-color: #f8f9fa; ' .. | ||
'padding: 10px; ' .. | |||
'border-radius: 3px; ' .. | 'border-radius: 3px; ' .. | ||
' | '-webkit-user-select: all; ' .. | ||
' | '-moz-user-select: all; ' .. | ||
'">' .. | '-ms-user-select: all; ' .. | ||
'user-select: all;' .. | |||
'">' .. | |||
'<pre style="margin: 0; font-family: monospace, Courier, monospace;"><nowiki>\n' .. | |||
text .. | |||
'\n</nowiki></pre></div>' | |||
end | end | ||
Версия от 21:55, 27 мая 2026
Инструкция
Этот скрипт не перезаписывает базу сам, он выступает в роли "переводчика". Он читает старый Lua и выдаёт вам готовый текст, который Cargo поймёт.
Действие 1: Конвертация финальных матчей ЧТМ (Подробных)
- Создайте любую черновую страницу (например,
Песочница_Cargo). - Напишите там следующий код и нажмите «Предварительный просмотр»:
{{#invoke:CargoConverter|runDetailed|2046}}(Вместо 2046 ставьте нужный год). - Прямо в окне предпросмотра вы увидите огромный блок текста, начинающийся с
<pre>. Внутри будут тысячи готовых строчек вида{{TWC_Match|...}},{{TWC_Lineups|...}}. - Выделите этот текст, скопируйте его.
- Создайте страницу, где эти данные будут жить вечно (например,
Данные:2046_Финал) и вставьте туда скопированный текст. Сохраните. База Cargo проглотила матчи!
Действие 2: Конвертация сеток турниров
- Возвращаетесь в Песочницу.
- Теперь вызываете вторую функцию:
{{#invoke:CargoConverter|runTournaments|2046}} - Снова "Предварительный просмотр". Теперь скрипт прочитает
Модуль:Data/Tournaments/2046, разобьёт 2-матчевые противостояния на два отдельных матча (с пометками_L1и_L2), расставит поля и цвета. - Копируете выданный текст.
- Создаёте страницу (например,
Данные:2046_Турниры) и вставляете текст туда. Сохраняете. Cargo проглотил сетки!
Действие 3: Заполняем Справочник Команд (TWC_Teams)
- Зайдите в вашу Песочницу.
- Вставьте вызов:
{{#invoke:CargoConverter|runTeams}} - Сделайте «Предварительный просмотр». Скрипт выдаст стройную таблицу вызовов
{{TWC_Teams|...}}для всех стран из словаря. - Скопируйте этот текст.
- Создайте страницу
Данные:Команды_БД(или любое удобное вам название), вставьте текст туда и сохраните. - Сделайте на ней «нулевую правку» (сохраните пустой), чтобы запустить запись в Cargo [1.1.6, 1.2.6]. Справочник команд заполнен!
Действие 4: Заполняем Справочник Турниров (TWC_Tournaments)
- В Песочнице напишите:
{{#invoke:CargoConverter|runTournamentsList}} - Нажмите «Предварительный просмотр». Модуль сам прошерстит файлы за 2006, 2009, 2010... 2048 годы, соберёт все когда-либо существовавшие турниры и сгенерирует красивый список вызовов
{{TWC_Tournaments|...}}. - Скопируйте результат.
- Создайте страницу
Данные:Турниры_БД, вставьте текст туда и сохраните. - Сделайте «нулевую правку» [1.1.6, 1.2.6]. Метаданные турниров записаны!
(Конечно, вы можете вставлять оба результата на одну большую страницу Данные:2046, если захотите — Cargo не против).
local p = {}
-- Вспомогательная функция для безопасного вывода
local function safe(val)
if val == nil then return "" end
if type(val) == "boolean" then return val and "1" or "0" end
return tostring(val)
end
-- Вспомогательная функция для оборачивания вывода в аккуратный scroll-бокс
local function wrap_output(text)
-- Используем только разрешенные в MediaWiki теги <div> и <pre>
-- Задаем ограничение по высоте (max-height), рамку и авто-прокрутку
return '<div style="' ..
'max-height: 400px; ' ..
'overflow: auto; ' ..
'border: 1px solid #a2a9b1; ' ..
'background-color: #f8f9fa; ' ..
'padding: 10px; ' ..
'border-radius: 3px; ' ..
'-webkit-user-select: all; ' ..
'-moz-user-select: all; ' ..
'-ms-user-select: all; ' ..
'user-select: all;' ..
'">' ..
'<pre style="margin: 0; font-family: monospace, Courier, monospace;"><nowiki>\n' ..
text ..
'\n</nowiki></pre></div>'
end
-- Функция умной сортировки Match ID (с учётом чисел)
local function get_sorted_match_ids(data)
local keys = {}
for k in pairs(data) do
table.insert(keys, k)
end
table.sort(keys, function(a, b)
-- Извлекаем год и номер матча (например, "2046" и "3" из "2046-03")
local ya, na = string.match(a, "^(%d+)-(%d+)")
local yb, nb = string.match(b, "^(%d+)-(%d+)")
if ya and yb and na and nb then
local tya, tna = tonumber(ya), tonumber(na)
local tyb, tnb = tonumber(yb), tonumber(nb)
if tya ~= tyb then
return tya < tyb
else
return tna < tnb
end
end
return a < b -- если формат другой, сортируем просто по алфавиту
end)
return keys
end
-- =========================================================
-- 1. КОНВЕРТЕР ПОДРОБНЫХ МАТЧЕЙ (из Модуль:Data/Год)
-- =========================================================
function p.runDetailed(frame)
local year = frame.args[1] or "2046"
local data = mw.loadData('Модуль:Data/' .. year)
local out = {}
local tourn_id = "ЧТМ_" .. year .. "_Final"
-- Получаем отсортированный список ключей
local sorted_keys = get_sorted_match_ids(data)
for _, match_id in ipairs(sorted_keys) do
local m = data[match_id]
-- 1. Базовый матч
table.insert(out, string.format(
"{{TWC_Matches|MatchID=%s|TournamentID=%s|Stage=%s|GroupLetter=%s|Tour=%s|RealDate=%s|Matchday=%s|NumHist=%s|Team1=%s|Team2=%s|Score1=%s|Score2=%s|AET=%s|ShootoutScore1=%s|ShootoutScore2=%s|Stadium=%s|Players1=%s|Players2=%s|Gates=%s|ThrowIns=%s|Halfs=%s|HalfTime=%s|ExtraTime=%s|ET_Halfs=%s|ET_HalfTime=%s|SubsRules=%s|Chg1_Score=%s|Chg1_Min=%s|Chg1_Pl1=%s|Chg1_Pl2=%s|Chg2_Score=%s|Chg2_Min=%s|Chg2_Pl1=%s|Chg2_Pl2=%s|Chg3_Score=%s|Chg3_Min=%s|Chg3_Pl1=%s|Chg3_Pl2=%s|Video=%s|VkVideo=%s|ReviewUrl=%s|VkReviewUrl=%s|ReviewTime=%s|WikiLink=%s|Comment=%s}}",
safe(match_id), safe(tourn_id), safe(m.stage), safe(m.letter), safe(m.tour), safe(m.date), safe(m.matchday), safe(m.num_hist),
safe(m.team1), safe(m.team2), safe(m.score1), safe(m.score2), safe(m.aet), safe(m.shootout_score1), safe(m.shootout_score2), safe(m.stadium),
safe(m.players1), safe(m.players2), safe(m.gates), safe(m.throw_ins), safe(m.halfs), safe(m.half_time),
safe(m.extra_time), safe(m.et_halfs), safe(m.et_half_time), safe(m.subs_rules),
safe(m.changed_format_score), safe(m.changed_format_min), safe(m.changed_players_team1), safe(m.changed_players_team2),
safe(m.changed_format2_score), safe(m.changed_format2_min), safe(m.changed_players2_team1), safe(m.changed_players2_team2),
safe(m.changed_format3_score), safe(m.changed_format3_min), safe(m.changed_players3_team1), safe(m.changed_players3_team2),
safe(m.video), safe(m.vk_video), safe(m.review_url), safe(m.vk_review_url), safe(m.review_time), safe(m.wikilink), safe(m.comment)
))
-- 2. Составы (TWC_Lineups)
local function parse_squad(sq, t_idx)
if not sq then return end
if sq.starters then
for _, pl in ipairs(sq.starters) do
local is_cap = (pl == sq.captain)
local is_gk = (pl == sq.full_match_goalie)
table.insert(out, string.format("{{TWC_Lineups|MatchID=%s|Player=%s|TeamIndex=%s|Role=starter|IsCaptain=%s|IsFullMatchGoalie=%s}}", match_id, pl, t_idx, safe(is_cap), safe(is_gk)))
end
end
if sq.substitutes then
for _, pl in ipairs(sq.substitutes) do
table.insert(out, string.format("{{TWC_Lineups|MatchID=%s|Player=%s|TeamIndex=%s|Role=sub|IsCaptain=0|IsFullMatchGoalie=0}}", match_id, pl, t_idx))
end
end
end
parse_squad(m.squad1, 1)
parse_squad(m.squad2, 2)
parse_squad(m.neutral_gk, 0)
-- 3. Голы (TWC_Goals)
if m.goals then
for _, g in ipairs(m.goals) do
table.insert(out, string.format("{{TWC_Goals|MatchID=%s|TeamIndex=%s|Scorer=%s|OwnScorer=%s|Assist=%s|ScoreAfter=%s|Minute=%s|GoalType1=%s|GoalType2=%s|IsET=%s|Fouler=%s}}",
match_id, safe(g.team), safe(g.scorer), safe(g.own_scorer), safe(g.assist), safe(g.score), safe(g.min), safe(g.goal_type), safe(g.goal_type2), safe(g.et_goal), safe(g.fouler)))
end
end
-- 4. Замены (TWC_Subs)
if m.subs then
for _, s in ipairs(m.subs) do
table.insert(out, string.format("{{TWC_Subs|MatchID=%s|TeamIndex=%s|PlayerOut=%s|PlayerIn=%s|ScoreAfter=%s|Minute=%s}}",
match_id, safe(s.team), safe(s.player_out), safe(s.player_in), safe(s.score), safe(s.min)))
end
end
-- 5. Карточки (TWC_Cards)
if m.cards then
for _, c in ipairs(m.cards) do
table.insert(out, string.format("{{TWC_Cards|MatchID=%s|TeamIndex=%s|Player=%s|Color=%s|ScoreAfter=%s|Minute=%s|IsReturned=%s|ReturnScore=%s|ReturnMin=%s|Reason=%s}}",
match_id, safe(c.team), safe(c.player), safe(c.color), safe(c.score), safe(c.min), safe(c.returned), safe(c.return_score), safe(c.return_min), safe(c.reason)))
end
end
-- 6. Промахи пенальти и Выносы
if m.missed_pens then
for _, p in ipairs(m.missed_pens) do
table.insert(out, string.format("{{TWC_MissedPens|MatchID=%s|TeamIndex=%s|Taker=%s|Result=%s|Goalie=%s|Fouler=%s|ScoreAfter=%s|Minute=%s}}", match_id, safe(p.team), safe(p.taker), safe(p.result), safe(p.goalie), safe(p.fouler), safe(p.score), safe(p.min)))
end
end
if m.clearances then
for _, cl in ipairs(m.clearances) do
table.insert(out, string.format("{{TWC_Clearances|MatchID=%s|TeamIndex=%s|Player=%s|ScoreAfter=%s|Minute=%s}}", match_id, safe(cl.team), safe(cl.player), safe(cl.score), safe(cl.min)))
end
end
-- 6.5 Серия пенальти (TWC_Shootouts)
if m.shootout then
for _, sh in ipairs(m.shootout) do
table.insert(out, string.format("{{TWC_Shootouts|MatchID=%s|Num=%s|TeamIndex=%s|Taker=%s|Goalie=%s|Result=%s|ScoreAfter=%s}}",
match_id, safe(sh.num), safe(sh.team), safe(sh.taker), safe(sh.goalie), safe(sh.result), safe(sh.score_after)))
end
end
-- 7. Награды и MVP
if m.mvp and m.mvp.player then
table.insert(out, string.format("{{TWC_Awards|ContextID=%s|AwardType=MVP|Player=%s|TeamIndex=%s|Role=%s}}", match_id, safe(m.mvp.player), safe(m.mvp.team), safe(m.mvp.role)))
end
-- Призы турнира
local awards_map = {golden_sphere="GoldenSphere", silver_sphere="SilverSphere", bronze_sphere="BronzeSphere", wooden_sphere="WoodenSphere", elnur_award="ElnurAward", best_goal="BestGoal", golden_shoe="GoldenShoe", silver_shoe="SilverShoe", bronze_shoe="BronzeShoe", wooden_shoe="WoodenShoe", golden_assistant="GoldenAssistant", silver_assistant="SilverAssistant", bronze_assistant="BronzeAssistant", wooden_assistant="WoodenAssistant", superchampions="Superchampion"}
for k, v in pairs(awards_map) do
if m[k] then
if type(m[k]) == "table" then
for _, p in ipairs(m[k]) do
table.insert(out, string.format("{{TWC_Awards|ContextID=%s|AwardType=%s|Player=%s}}", tourn_id, v, p))
end
else
table.insert(out, string.format("{{TWC_Awards|ContextID=%s|AwardType=%s|Player=%s}}", tourn_id, v, m[k]))
end
end
end
table.insert(out, "") -- пустая строка для разделения матчей
end
return wrap_output(table.concat(out, "\n"))
end
-- =========================================================
-- 2. КОНВЕРТЕР ТУРНИРОВ (из Модуль:Data/Tournaments/Год)
-- =========================================================
function p.runTournaments(frame)
local year = frame.args[1] or "2046"
local data = mw.loadData('Модуль:Data/Tournaments/' .. year)
local out = {}
-- Сортируем названия турниров по алфавиту
local sorted_tournaments = {}
for t_name in pairs(data) do
table.insert(sorted_tournaments, t_name)
end
table.sort(sorted_tournaments)
for _, tourn_name in ipairs(sorted_tournaments) do
local stages = data[tourn_name]
table.insert(out, string.format("=== %s ===", tourn_name))
-- Сортируем стадии турнира по алфавиту
local sorted_stages = {}
for s_name in pairs(stages) do
table.insert(sorted_stages, s_name)
end
table.sort(sorted_stages)
for _, stage_name in ipairs(sorted_stages) do
local stage_data = stages[stage_name]
-- 1. Итоговые таблицы групп
if stage_data.standings then
for pos, st in ipairs(stage_data.standings) do
table.insert(out, string.format("{{TWC_StageTeams|TournamentID=%s|Stage=%s|Team=%s|Position=%s|ColorCode=%s}}",
safe(tourn_name), safe(stage_name), safe(st[1]), pos, safe(st[2])))
end
end
-- 2. Матчи турнира
if stage_data.matches then
for i, m in ipairs(stage_data.matches) do
local base_match_id = tourn_name .. "_" .. stage_name .. "_M" .. i
if stage_data.type == "group" then
table.insert(out, string.format("{{TWC_Matches|MatchID=%s|TournamentID=%s|Stage=%s|Team1=%s|Team2=%s|Score1=%s|Score2=%s|FieldAdvantage=%s}}",
base_match_id, safe(tourn_name), safe(stage_name), safe(m[1]), safe(m[2]), safe(m[3]), safe(m[4]), safe(m[5])))
elseif stage_data.type == "knockout" then
if stage_data.number_of_rounds == 1 then
local aet = (m[5] == "aet")
table.insert(out, string.format("{{TWC_Matches|MatchID=%s|TournamentID=%s|Stage=%s|Team1=%s|Team2=%s|Score1=%s|Score2=%s|AET=%s|ShootoutScore1=%s|ShootoutScore2=%s|Color1=%s|Color2=%s|FieldAdvantage=%s}}",
base_match_id, safe(tourn_name), safe(stage_name), safe(m[1]), safe(m[2]), safe(m[3]), safe(m[4]), safe(aet), safe(m[6]), safe(m[7]), safe(m[8]), safe(m[9]), safe(m[10])))
else
-- Первый матч
table.insert(out, string.format("{{TWC_Matches|MatchID=%s_L1|TournamentID=%s|Stage=%s|Team1=%s|Team2=%s|Score1=%s|Score2=%s|FieldAdvantage=1}}",
base_match_id, safe(tourn_name), safe(stage_name), safe(m[1]), safe(m[2]), safe(m[3]), safe(m[4])))
-- Второй матч
local aet = (m[7] == "aet")
table.insert(out, string.format("{{TWC_Matches|MatchID=%s_L2|TournamentID=%s|Stage=%s|Team1=%s|Team2=%s|Score1=%s|Score2=%s|AET=%s|ShootoutScore1=%s|ShootoutScore2=%s|Color1=%s|Color2=%s|FieldAdvantage=2}}",
base_match_id, safe(tourn_name), safe(stage_name), safe(m[2]), safe(m[1]), safe(m[6]), safe(m[5]), safe(aet), safe(m[9]), safe(m[8]), safe(m[11]), safe(m[10])))
end
end
end
end
table.insert(out, "")
end
end
return wrap_output(table.concat(out, "\n"))
end
-- =========================================================
-- 3. КОНВЕРТЕР СПРАВОЧНИКА КОМАНД (в TWC_Teams)
-- =========================================================
function p.runTeams(frame)
local teams_mod = require('Модуль:Data/Teams')
local raw = teams_mod.raw_data
if not raw then
return "<span style='color:red; font-weight:bold;'>Ошибка:</span> Не удалось получить raw_data из Модуль:Data/Teams.\n" ..
"Убедитесь, что добавили строку <pre>M.raw_data = raw_data</pre> в самый конец Модуль:Data/Teams перед return M."
end
local out = {}
-- Сортируем коды по алфавиту
local sorted_codes = {}
for code in pairs(raw) do
table.insert(sorted_codes, code)
end
table.sort(sorted_codes)
local CONFS = {
[1] = "Америка",
[2] = "Африка",
[3] = "Евразия",
[4] = "Океания"
}
for _, code in ipairs(sorted_codes) do
local data = raw[code]
local short_name = data[1]
local full_name = data[2] or short_name
local conf_num = data[3]
local cases = data[4] or {}
local name_gen = cases.gen or full_name
local name_loc = cases.loc or full_name
local twc = data.twc
table.insert(out, string.format("{{TWC_Teams|Code=%s|ShortName=%s|FullName=%s|Confederation=%s|NameGen=%s|NameLoc=%s|IsActive=%s}}",
safe(code), safe(short_name), safe(full_name), safe(conf_num), safe(name_gen), safe(name_loc), safe(twc)))
end
return wrap_output(table.concat(out, "\n"))
end
-- =========================================================
-- 4. КОНВЕРТЕР СПРАВОЧНИКА ТУРНИРОВ (в TWC_Tournaments) — ИСПРАВЛЕНО
-- =========================================================
function p.runTournamentsList(frame)
local config = require('Модуль:Config')
local years = config.all_years
local out = {}
local PREFIXES = {
["ЧТМ"] = "Чемпионат третьего мира",
["КАм"] = "Кубок Америки",
["КАф"] = "Кубок Африки",
["КЕв"] = "Кубок Евразии",
["КОк"] = "Кубок Океании",
["ККо"] = "Кубок Конфедераций",
["КФе"] = "Кубок Федерации",
["ЛНа"] = "Лига Наций",
["КЕвропы"] = "Кубок Европы",
["КЮжАм"] = "Кубок Южной Америки",
["ЧЧМ"] = "Чемпионат четвёртого мира",
["КУб"] = "Кубок Убогих"
}
-- Собираем уникальные ID турниров со всех доступных файлов лет
local tournaments = {}
for _, yr in ipairs(years) do
local success, year_data = pcall(mw.loadData, 'Модуль:Data/Tournaments/' .. yr)
if success and year_data then
for tourn_id, _ in pairs(year_data) do
tournaments[tourn_id] = yr
end
end
end
-- Сортируем турниры по имени
local sorted_tourn = {}
for tourn_id in pairs(tournaments) do
table.insert(sorted_tourn, tourn_id)
end
table.sort(sorted_tourn)
for _, tourn_id in ipairs(sorted_tourn) do
local yr = tournaments[tourn_id]
-- Используем Unicode-совместимый mw.ustring.match вместо string.match!
local prefix, parsed_yr, t_type = mw.ustring.match(tourn_id, "^(%a+)_*(%d+)_*(%a+)")
local display_name = tourn_id -- фоллбэк
if prefix and parsed_yr and t_type then
local rus_prefix = PREFIXES[prefix] or prefix
if t_type == "Final" then
-- Финал: выводим просто название и год без скобок
display_name = string.format("%s %s", rus_prefix, parsed_yr)
else
-- Отбор: выводим название, год и суффикс в строго одинарных скобках
display_name = string.format("%s %s (отборочный турнир)", rus_prefix, parsed_yr)
end
end
table.insert(out, string.format("{{TWC_Tournaments|TournamentID=%s|TournamentName=%s|Year=%s|Type=%s}}",
safe(tourn_id), safe(display_name), safe(yr), safe(t_type)))
end
return wrap_output(table.concat(out, "\n"))
end
return p