모듈:GameJSONParser: 두 판 사이의 차이
둘러보기로 이동
검색으로 이동
>BANIP 잔글편집 요약 없음 |
>BANIP (주석, 깊은 테이블 사용을 위한 t.walk 함수 추가, propertyCases에 반영) |
||
1번째 줄: | 1번째 줄: | ||
local p = {} | local p = {} | ||
-- 테이블 유틸리티 함수 | |||
t = { | t = { | ||
-- js의 find | |||
find = function(table, func) | find = function(table, func) | ||
for _, value in ipairs(table) do | for _, value in ipairs(table) do | ||
10번째 줄: | 12번째 줄: | ||
return nil | return nil | ||
end, | end, | ||
-- js의 map | |||
map = function(table, func) | map = function(table, func) | ||
local newTable = {} | local newTable = {} | ||
18번째 줄: | 20번째 줄: | ||
return newTable | return newTable | ||
end, | end, | ||
-- js의 필터 | |||
filter = function(table, func) | filter = function(table, func) | ||
local newTable = {} | local newTable = {} | ||
27번째 줄: | 29번째 줄: | ||
end | end | ||
return newTable | return newTable | ||
end | end, | ||
--t.walk(gameMeta, {"rating","libertygame","age"})를 호출 시 | |||
--gameMeta.rating.libertygame.age로 들어가다가 도중에 들어갈 수 없는 구조를 만나면 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, | |||
} | } | ||
40번째 줄: | 54번째 줄: | ||
-- 현재 속성의 유효성을 확인합니다. | -- 현재 속성의 유효성을 확인합니다. | ||
local validatedGroup = propertyCase:validate(scheme,gameMeta) | local validatedGroup = propertyCase:validate(scheme,gameMeta) | ||
if validatedGroup ~= false then | if validatedGroup ~= false and validatedGroup ~= nil then | ||
-- 배열이 아닌 경우 기본 배열로 변환 | |||
if type(validatedGroup) ~= 'table' then | |||
validatedGroup = {} | |||
end | |||
-- 2단계 배열이 아닌 경우 한번 더 감싸기 | |||
if #validatedGroup ~= 0 and type(validatedGroup[1]) ~= 'table' then | if #validatedGroup ~= 0 and type(validatedGroup[1]) ~= 'table' then | ||
validatedGroup = {validatedGroup} | validatedGroup = {validatedGroup} | ||
67번째 줄: | 88번째 줄: | ||
local gameMeta = mw.text.jsonDecode(frame.args[2]) | local gameMeta = mw.text.jsonDecode(frame.args[2]) | ||
-- | -- 속성 케이스 검사할 값, 발견시 반환할 값 정의 | ||
local propertyCases = { | local propertyCases = { | ||
{ | { | ||
73번째 줄: | 94번째 줄: | ||
formatter = "[[분류:$title 게임]]", | formatter = "[[분류:$title 게임]]", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
local | local platform = t.walk(gameMeta, {"platform"}) | ||
return | 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) | end) | ||
if platFormData == nil then return false end | if platFormData == nil then return false end | ||
84번째 줄: | 108번째 줄: | ||
formatter = "{{뱃지|버려진 게임}}", | formatter = "{{뱃지|버려진 게임}}", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
return gameMeta | return t.walk(gameMeta, {"abandon"}) or false | ||
end | end | ||
}, | }, | ||
91번째 줄: | 115번째 줄: | ||
formatter = "{{뱃지|공사중|$value}}", | formatter = "{{뱃지|공사중|$value}}", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
if not | local construction = t.walk(gameMeta, {"construction"}) | ||
if | if not construction then return false end | ||
return {{key = "value", value = | if construction == true then return {{key = "value", value = ""}} end | ||
return {{key = "value", value = construction}} | |||
end | end | ||
}, | }, | ||
100번째 줄: | 125번째 줄: | ||
formatter = "[[분류:$title]]", | formatter = "[[분류:$title]]", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
local | local progress = t.walk(gameMeta, {"progress"}) | ||
return | 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) | end) | ||
if progressData == nil then return false end | if progressData == nil then return false end | ||
111번째 줄: | 139번째 줄: | ||
formatter = "[[분류:$title 게임]]", | formatter = "[[분류:$title 게임]]", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
local age = gameMeta | local age = t.walk(gameMeta, {"rating", "libertygame", "age"}) | ||
local | if age == nil then return false end | ||
return | 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) | end) | ||
if ageData == nil then return false end | if ageData == nil then return false end | ||
123번째 줄: | 153번째 줄: | ||
formatter = "{{뱃지|수리중}}", | formatter = "{{뱃지|수리중}}", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
if not | local repair = t.walk(gameMeta, {"repair"}) | ||
if | if not repair then return false end | ||
return {{key = "value", value = | if repair == true then return {{key = "value", value = ""}} end | ||
return {{key = "value", value = repair}} | |||
end | end | ||
}, | }, | ||
132번째 줄: | 163번째 줄: | ||
formatter = "[[분류:$title 게임]]", | formatter = "[[분류:$title 게임]]", | ||
validate = function(gameMeta, scheme) | validate = function(gameMeta, scheme) | ||
local genres = gameMeta | local genres = t.walk(gameMeta, {"genre"}) | ||
if genres == nil then return false end | |||
if type(genres) == "string" then genres = {genres} 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) | local genreData = t.filter(t.map(genres, function(genre) | ||
return t.find( | return t.find(genreDef, function(genreData) | ||
return genreData.const == genre | return genreData.const == genre | ||
end) | end) | ||
141번째 줄: | 174번째 줄: | ||
return genreData ~= nil | return genreData ~= nil | ||
end) | end) | ||
return t.map(genreData, function(genreData) | return t.map(genreData, function(genreData) | ||
return {key = "title", value = genreData.title} | return {key = "title", value = genreData.title} |
2023년 7월 28일 (금) 00:44 판
getGameInfo
- 이 부분의 본문은 틀:게임 정보입니다.
getGamecard
- 이 부분의 본문은 틀:게임카드입니다.
getFeaturedCard
- 이 부분의 본문은 틀:추천평카드입니다.
도보시오
- 리버티게임:게임 메타데이터/스키마.json : 메타데이터 스키마
- 모듈:GameJSONParser/연구소
위 설명은 모듈:GameJSONParser/설명문서의 내용을 가져와 보여주고 있습니다. (편집 | 역사) 이 모듈에 대한 수정 연습과 시험은 연습장 (만들기 | 미러)과 시험장 (만들기)에서 할 수 있습니다. 분류는 /설명문서에 넣어주세요. 이 모듈에 딸린 문서. |
local p = {}
-- 테이블 유틸리티 함수
t = {
-- js의 find
find = function(table, func)
for _, value in ipairs(table) do
if func(value) then
return value
end
end
return nil
end,
-- js의 map
map = function(table, func)
local newTable = {}
for i, value in ipairs(table) do
newTable[i] = func(value)
end
return newTable
end,
-- js의 필터
filter = function(table, func)
local newTable = {}
for _, value in ipairs(table) do
if func(value) then
table.insert(newTable, value)
end
end
return newTable
end,
--t.walk(gameMeta, {"rating","libertygame","age"})를 호출 시
--gameMeta.rating.libertygame.age로 들어가다가 도중에 들어갈 수 없는 구조를 만나면 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, propertyCases, gameMeta)
local results = {}
-- 각 속성 케이스를 순회합니다.
for _, propertyCase in ipairs(propertyCases) do
-- 현재 속성의 유효성을 확인합니다.
local validatedGroup = propertyCase:validate(scheme,gameMeta)
if validatedGroup ~= false and validatedGroup ~= nil then
-- 배열이 아닌 경우 기본 배열로 변환
if type(validatedGroup) ~= 'table' then
validatedGroup = {}
end
-- 2단계 배열이 아닌 경우 한번 더 감싸기
if #validatedGroup ~= 0 and type(validatedGroup[1]) ~= 'table' then
validatedGroup = {validatedGroup}
end
for _, validated in ipairs(validatedGroup) do
local resultString = propertyCase.formatter
for _, v in ipairs(validated) do
local key = v[1]
local value = v[2]
resultString = resultString:gsub("$" .. key, value)
end
table.insert(results, resultString)
end
end
end
return results
end
-- 첫번째 파라미터에 리버티게임:게임 메타데이터/스키마.json,
-- 두번째 파라미터에 game.json 넣어서 게임 자동분류 사용 가능
-- 아직 테스트되지 않음
function p.manualParse(frame)
local scheme = mw.text.jsonDecode(frame.args[1])
local gameMeta = mw.text.jsonDecode(frame.args[2])
-- 속성 케이스 검사할 값, 발견시 반환할 값 정의
local propertyCases = {
{
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 = "{{뱃지|공사중|$value}}",
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
}
}
local parsed = p._manualParser(scheme, propertyCases, gameMeta)
return mw.text.jsonEncode(parsed)
--return table.concat(parsed)
end
function p.testParser(frame)
local jsonschema = require('모듈:Jsonschema')
local validator = jsonschema.generate_validator {
type = 'object',
properties = {
foo = { type = 'string' },
bar = { type = 'number' },
},
}
return mw.text.jsonEncode( validator{ foo='hello', bar=42 } )
end
function p.testImportJson(frame)
local jsonschema = require('모듈:GameJSONParser/scheme.json')
return mw.text.jsonEncode( jsonschema )
end
function p.test(frame)
local jsonschema = require('모듈:Jsonschema')
local validator = jsonschema.generate_validator {
type = 'object',
properties = {
foo = { type = 'string' },
bar = { type = 'number' },
},
}
return mw.text.jsonEncode( validator{ foo='hello', bar=42 } )
end
function p.testjson(frame)
local encoded = mw.text.jsonDecode(frame.args[1])
return mw.text.jsonEncode(encoded["$defs"].platform.oneOf)
end
return p