>BANIP |
>BANIP |
1번째 줄: |
1번째 줄: |
| local p = {} | | local p = {} |
| local table = require('table') -- 배열 입출력을 위한 테이블 내부 라이브러리
| |
|
| |
|
| -- 속성 케이스 검사할 값, 발견시 반환할 값 정의
| | function p.a(category) |
| p.propertyCases = {
| | frame = mw.getCurrentFrame() |
| {
| | return frame:callParserFunction{ name = 'expr', args = { "1 + 1" } } |
| key = "platform",
| |
| formatter = "[[분류:$title 게임]]",
| |
| validate = function(gameMeta, scheme)
| |
| local platform = t.walk(gameMeta, {"platform"})
| |
| if platform == nil then return false end
| |
| local platFormDef = t.walk(scheme, {"$defs", "platform", "oneOf"})
| |
| local platFormData = t.find(platFormDef, function(p)
| |
| return p.const == platform
| |
| end)
| |
| if platFormData == nil then return false end
| |
| return {{key = "title", value = platFormData.title}}
| |
| end
| |
| },
| |
| {
| |
| key = "abandon",
| |
| formatter = "[[분류:버려진 게임]]",
| |
| validate = function(gameMeta, scheme)
| |
| return t.walk(gameMeta, {"abandon"}) or false
| |
| end
| |
| },
| |
| {
| |
| key = "construction",
| |
| formatter = "[[분류:공사중인 게임]]",
| |
| validate = function(gameMeta, scheme)
| |
| local construction = t.walk(gameMeta, {"construction"})
| |
| if not construction then return false end
| |
| if construction == true then return {{key = "value", value = ""}} end
| |
| return {{key = "value", value = construction}}
| |
| end
| |
| }, | |
| {
| |
| key = "progress",
| |
| formatter = "[[분류:$title]]",
| |
| validate = function(gameMeta, scheme)
| |
| local progress = t.walk(gameMeta, {"progress"})
| |
| if progress == nil then return false end
| |
| local progressDef = t.walk(scheme, {"properties", "progress", "oneOf"})
| |
| local progressData = t.find(progressDef, function(p)
| |
| return p.const == progress
| |
| end)
| |
| if progressData == nil then return false end
| |
| return {{key = "title", value = progressData.title}}
| |
| end
| |
| },
| |
| {
| |
| key = "rating",
| |
| formatter = "[[분류:$title 게임]]",
| |
| validate = function(gameMeta, scheme)
| |
| local age = t.walk(gameMeta, {"rating", "libertygame", "age"})
| |
| if age == nil then return false end
| |
| local ageDef = t.walk(scheme, {"properties", "rating", "oneOf", 2, "properties", "libertygame", "properties", "age", "oneOf"})
| |
| local ageData = t.find(ageDef, function(a)
| |
| return a.const == age
| |
| end)
| |
| if ageData == nil then return false end
| |
| return {{key = "title", value = ageData.title}}
| |
| end
| |
| },
| |
| {
| |
| key = "repair",
| |
| formatter = "[[분류:수리중인 게임]]",
| |
| validate = function(gameMeta, scheme)
| |
| local repair = t.walk(gameMeta, {"repair"})
| |
| if not repair then return false end
| |
| if repair == true then return {{key = "value", value = ""}} end
| |
| return {{key = "value", value = repair}}
| |
| end
| |
| },
| |
| {
| |
| key = "genre",
| |
| formatter = "[[분류:$title]]",
| |
| validate = function(gameMeta, scheme)
| |
| local genres = t.walk(gameMeta, {"genre"})
| |
| if genres == nil then return false end
| |
| if type(genres) == "string" then genres = {genres} end
| |
| local genreDef = t.walk(scheme, {"$defs", "genre", "oneOf"})
| |
| local genreData = t.filter(t.map(genres, function(genre)
| |
| return t.find(genreDef, function(genreData)
| |
| return genreData.const == genre
| |
| end)
| |
| end), function(genreData)
| |
| return genreData ~= nil
| |
| end)
| |
|
| |
|
| return t.map(genreData, function(genreData)
| |
| return {key = "title", value = genreData.title}
| |
| end)
| |
| end
| |
| }
| |
| }
| |
|
| |
| -- 테이블 관련 유틸리티 함수들
| |
| t = {
| |
| -- 자바스크립트의 find 함수와 동일
| |
| -- 주어진 함수를 만족하는 첫 번째 요소를 반환
| |
| find = function(tb, func)
| |
| for _, value in ipairs(tb) do
| |
| if func(value) then
| |
| return value
| |
| end
| |
| end
| |
| return nil
| |
| end,
| |
| -- 자바스크립트의 map 함수와 동일
| |
| -- 주어진 함수를 이용하여 테이블의 모든 요소를 변환
| |
| map = function(tb, func)
| |
| local newTable = {}
| |
| for i, value in ipairs(tb) do
| |
| newTable[i] = func(value)
| |
| end
| |
| return newTable
| |
| end,
| |
| -- 자바스크립트의 filter 함수와 동일
| |
| -- 주어진 함수를 만족하는 요소만으로 새 테이블 생성
| |
| filter = function(tb, func)
| |
| local newTable = {}
| |
| for _, value in ipairs(tb) do
| |
| if func(value) then
| |
| table.insert(newTable, value)
| |
| end
| |
| end
| |
| return newTable
| |
| end,
| |
| -- gameMeta.rating.libertygame.age와 같이 다단계 키로 이루어진 테이블 값을 가져오는 함수
| |
| -- 키의 경로 중간에 nil이 있는 경우 nil 반환
| |
| walk = function(tbl, keys)
| |
| local value = tbl
| |
| for i, key in ipairs(keys) do
| |
| value = value[key]
| |
| if value == nil or type(value) == 'number' or type(value) == 'string' then
| |
| return value
| |
| end
| |
| end
| |
| return value
| |
| end,
| |
| }
| |
|
| |
|
| |
| -- 게임 메타데이터를 분석하고 각 속성에 대해 적절한 포맷을 적용하는 함수
| |
| function p._manualParser(scheme, gameMeta)
| |
| local results = {}
| |
|
| |
| -- 각 속성 케이스를 순회합니다.
| |
| for _, propertyCase in ipairs(p.propertyCases) do
| |
| -- 현재 속성의 유효성을 확인합니다.
| |
| local validatedGroup = propertyCase.validate(gameMeta,scheme)
| |
|
| |
| if validatedGroup ~= false and validatedGroup ~= nil then
| |
| -- 배열이 아닌 경우 기본 배열로 변환
| |
| if type(validatedGroup) ~= 'table' then
| |
| validatedGroup = {}
| |
| end
| |
|
| |
| -- 2단계 배열이 아닌 경우 한번 더 감싸기(하위 테이블에 "key"라는 키가 있을 때)
| |
| if #validatedGroup ~= 0 and validatedGroup[1].key ~= nil then
| |
| validatedGroup = {validatedGroup}
| |
| end
| |
|
| |
| for _, validated in ipairs(validatedGroup) do
| |
| local resultString = propertyCase.formatter
| |
| for _, v in ipairs(validated) do
| |
| local key = v.key
| |
| local value = v.value
| |
| resultString = resultString:gsub("$" .. key, value)
| |
| end
| |
| table.insert(results, resultString)
| |
| end
| |
| end
| |
| end
| |
|
| |
| return results
| |
| end | | end |
|
| |
| function p.manualParse(frame)
| |
| -- 틀 호출하기 위해서 필요한 현재 페이지 프레임 변수 획득
| |
| local currentFrame = mw.getCurrentFrame()
| |
|
| |
| local schemePagename = '리버티게임:게임 메타데이터/스키마.json'
| |
| -- schemePagename 페이지가 존재하는지 확인 없으면 오류반환
| |
| if not mw.title.new(schemePagename).exists then
| |
| return "자동 분류에 필요한 [[" .. schemePagename .. "]] 페이지가 존재하지 않습니다. 관리자에게 알려주세요. "
| |
| end
| |
|
| |
| -- 메타데이터 스키마 획득 후 테이블로 변환
| |
| local schemeRaw = currentFrame:expandTemplate{title = schemePagename}
| |
| local scheme = mw.text.jsonDecode(schemeRaw)
| |
|
| |
| -- 첫번째 변수혹은 현재 페이지명으로 게임 메타데이터 페이지 이름 획득
| |
| local gameMetaPagename = frame.args[1] or (mw.title.getCurrentTitle().prefixedText .. "/game.json")
| |
|
| |
| -- 위키낚시/game.json => :위키낚시/game.json
| |
| -- 사:BANIP/위키낚시/game.json => 사:BANIP/위키낚시/game.json
| |
| if not gameMetaPagename:find(":") then
| |
| gameMetaPagename = ":" .. gameMetaPagename
| |
| end
| |
|
| |
| -- game.json 페이지 있는지 확인 및 없으면 오류 반환
| |
| if not mw.title.new(gameMetaPagename).exists then
| |
| return "[[분류:게임 메타데이터가 없는 게임]]"
| |
| end
| |
|
| |
| -- 게임 메타데이터 획득 후 테이블로 변환
| |
| local gameMetaRaw = currentFrame:expandTemplate{title = gameMetaPagename}
| |
| local gameMeta = mw.text.jsonDecode(gameMetaRaw)
| |
|
| |
| -- 게임 메타데이터 파싱
| |
| local parsed = p._manualParser(scheme, gameMeta)
| |
|
| |
| -- 파싱 결과 반환
| |
| return table.concat(parsed)
| |
| end
| |
|
| |
| return p | | return p |