Module:Television infoboxes disambiguation check

local libraryUtil = require('libraryUtil')

--=============================================================--

-- DisambiguationPattern class.

local function DisambiguationPattern(o)

local DisambiguationPattern = o or {pattern = "", type = ""}

local checkSelf = libraryUtil.makeCheckSelfFunction( 'Television infoboxes disambiguation check', 'DisambiguationPattern', DisambiguationPattern, 'Television infoboxes disambiguation check object' )

return DisambiguationPattern

end

--=============================================================--

-- Constants.

local DAB_VALID = {

[true] = "valid",

[false] = "invalid"

}

local CATEGORY_INCORRECT = "Category:Television articles with incorrect naming style"

local validationTypeList = {

["VALIDATION_TYPE_YEAR_COUNTRY"] = 1,

["VALIDATION_TYPE_YEAR"] = 2,

["VALIDATION_TYPE_COUNTRY"] = 3,

["VALIDATION_TYPE_YEAR_SEASON_NUMBER"] = 4,

["VALIDATION_TYPE_COUNTRY_SEASON_NUMBER"] = 5,

["VALIDATION_TYPE_SEASON_NUMBER"] = 6,

["VALIDATION_TYPE_COUNTRY_SEASON"] = 7,

["VALIDATION_TYPE_YEAR_COUNTRY_SEASON_NUMBER"] = 8

}

local debugMessageList = {

["DEBUG_EMPTY_TITLE"] = "Debug: Error: Empty title.",

["DEBUG_NO_DAB"] = "Debug: No disambiguation.",

["DEBUG_TITLE_ON_EXCEPTION"] = "Debug: Title on exception list.",

["DEBUG_VALID_FORMAT"] = "Debug: Using a valid format.",

["DEBUG_NOT_VALID_FORMAT"] = "Debug: Not a valid format.",

["DEBUG_YEAR_COUNTRY"] = "Debug: Using a valid format with an extended Year and Country - {}.",

["DEBUG_YEAR"] = "Debug: Using a valid format with an extended Year - {}.",

["DEBUG_COUNTRY"] = "Debug: Using a valid format with an extended Country - {}.",

["DEBUG_INCORRECT_STYLE"] = "Debug: Using a valid format but using an incorrect extended style.",

["DEBUG_INCORRECT_INFOBOX"] = "Debug: Using incorrect infobox - {}.",

["DEBUG_YEAR_SEASON_NUMBER"] = "Debug: Using a valid format with an extended Year and Season number - {}.",

["DEBUG_COUNTRY_SEASON_NUMBER"] = "Debug: Using a valid format with an extended Country and Season number - {}.",

["DEBUG_SEASON_NUMBER"] = "Debug: Using a valid format with a Season number - {}.",

["DEBUG_COUNTRY_SEASON"] = "Debug: Using a valid format with a Country and the word Season - {}.",

["DEBUG_YEAR_COUNTRY_SEASON_NUMBER"] = "Debug: Using a valid format with an extended Year, Country and Season number - {}."

}

-- Local function which checks if both booleans are true or not.

local function validateTwoParameters(isValid1, isValid2)

if (isValid1 and isValid2) then

return true

else

return false

end

end

-- Validate that the season number entered is a valid number -

-- that it does not start with a leading zero (0).

local function validateSeasonNumber(seasonNumber)

if (tonumber(string.sub(seasonNumber, 1, 1)) == 0) then

return false

else

return true

end

end

-- Validate that the year entered is a valid year.

local function validateYear(year)

if (string.len(year) == 4) then

return true

else

return false

end

end

-- Validate that the text entered is a supported country adjective.

local function validateCountryAdjective(adjective)

local data = mw.loadData('Module:Country adjective')

-- Search for a country corresponding to the given text.

if (data.getCountryFromAdj[adjective]) then

return true

else

return false

end

end

-- Checks pages using by validating the disambiguation patterns.

local function validatePatterns(disambiguation, disambiguationPatternList)

local year = ""

local adjective = ""

local seasonNumber = ""

local isYearValid

local isAdjectiveValid

local isSeasonNumberValid

for i, v in ipairs(disambiguationPatternList) do

local currentDisambiguationPattern = disambiguationPatternList[i]

if (disambiguation:match(currentDisambiguationPattern.pattern)) then

-- Year and Country styles: "1999 American TV series"

if (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_YEAR_COUNTRY"]) then

year, adjective = disambiguation:match(currentDisambiguationPattern.pattern)

isYearValid = validateYear(year)

isAdjectiveValid = validateCountryAdjective(adjective)

local isValid = validateTwoParameters(isYearValid, isAdjectiveValid)

return isValid, debugMessageList["DEBUG_YEAR_COUNTRY"]:gsub("{}", DAB_VALID[isValid])

-- Year styles: "1999 TV series"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_YEAR"]) then

year = disambiguation

isYearValid = validateYear(year)

return isYearValid, debugMessageList["DEBUG_YEAR"]:gsub("{}", DAB_VALID[isYearValid])

-- Country styles: "American TV series"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_COUNTRY"]) then

adjective = disambiguation

isAdjectiveValid = validateCountryAdjective(adjective)

return isAdjectiveValid, debugMessageList["DEBUG_COUNTRY"]:gsub("{}", DAB_VALID[isAdjectiveValid])

-- Year and Season number styles: "1999 TV series, season 1"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_YEAR_SEASON_NUMBER"]) then

year, seasonNumber = disambiguation:match(currentDisambiguationPattern.pattern)

isYearValid = validateYear(year)

isSeasonNumberValid = validateSeasonNumber(seasonNumber)

local isValid = validateTwoParameters(isYearValid, isSeasonNumberValid)

return isValid, debugMessageList["DEBUG_YEAR_SEASON_NUMBER"]:gsub("{}", DAB_VALID[isValid])

-- Country and Season number styles: "American season 1" and "American TV series, season 1"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_COUNTRY_SEASON_NUMBER"]) then

adjective, seasonNumber = disambiguation:match(currentDisambiguationPattern.pattern)

isAdjectiveValid = validateCountryAdjective(mw.text.trim(adjective))

isSeasonNumberValid = validateSeasonNumber(seasonNumber)

local isValid = validateTwoParameters(isAdjectiveValid, isSeasonNumberValid)

return isValid, debugMessageList["DEBUG_COUNTRY_SEASON_NUMBER"]:gsub("{}", DAB_VALID[isValid])

-- Country and the word season: "American season"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_COUNTRY_SEASON"]) then

adjective = disambiguation:match(currentDisambiguationPattern.pattern)

isAdjectiveValid = validateCountryAdjective(mw.text.trim(adjective))

return isAdjectiveValid, debugMessageList["DEBUG_COUNTRY_SEASON"]:gsub("{}", DAB_VALID[isAdjectiveValid])

--Season number styles: "season 1"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_SEASON_NUMBER"]) then

seasonNumber = disambiguation:match(currentDisambiguationPattern.pattern)

isSeasonNumberValid = validateSeasonNumber(seasonNumber)

return isSeasonNumberValid, debugMessageList["DEBUG_SEASON_NUMBER"]:gsub("{}", DAB_VALID[isSeasonNumberValid])

-- Year, Country and Season number styles: "Gladiators (2008 British TV series, series 2)"

elseif (currentDisambiguationPattern.type == validationTypeList["VALIDATION_TYPE_YEAR_COUNTRY_SEASON_NUMBER"]) then

year, adjective, seasonNumber = disambiguation:match(currentDisambiguationPattern.pattern)

isYearValid = validateYear(year)

isAdjectiveValid = validateCountryAdjective(mw.text.trim(adjective))

isSeasonNumberValid = validateSeasonNumber(seasonNumber)

local isValid = validateTwoParameters(isYearValid, isAdjectiveValid)

isValid = validateTwoParameters(isValid, isSeasonNumberValid)

return isValid, debugMessageList["DEBUG_YEAR_COUNTRY_SEASON_NUMBER"]:gsub("{}", DAB_VALID[isValid])

-- Not a valid supported style.

else

-- Do nothing.

end

else

-- Do nothing.

end

end

return false, debugMessageList["DEBUG_INCORRECT_STYLE"]

end

-- Validate that the disambiguation type is one of the supported types.

local function validateDisambiguationType(disambiguation, validDisambiguationTypeList)

local extendedDisambiguation

local count = 0

for i, v in ipairs(validDisambiguationTypeList) do

extendedDisambiguation, count = disambiguation:gsub(v, '')

extendedDisambiguation = mw.text.trim(extendedDisambiguation)

if (count ~= 0) then

-- Disambiguation was a valid type; Exit loop.

break

end

end

count = count ~= 0

return count, extendedDisambiguation

end

-- Validate that the complete disambiguation is using a supported style.

local function validateDisambiguation(invoker, disambiguation, validDisambiguationTypeList, validDisambiguationPatternList)

-- Check if the list is empty.

if (table.getn(validDisambiguationTypeList) ~= 0) then

local isDisambiguationValid, extendedDisambiguation = validateDisambiguationType(disambiguation, validDisambiguationTypeList)

-- Exit module if the disambiguation type is not a supported style.

if (not isDisambiguationValid) then

return false, debugMessageList["DEBUG_NOT_VALID_FORMAT"]

end

-- Check if there is no extended disambiguation.

if (extendedDisambiguation == '') then

return true, debugMessageList["DEBUG_VALID_FORMAT"]

end

-- A bit of hack so I won't need to refactor a ton of code.

if (invoker ~= "infobox television season") then

disambiguation = extendedDisambiguation

end

end

return validatePatterns(disambiguation, validDisambiguationPatternList)

end

-- Check if the page is using disambiguation style that belongs to a different infobox.

local function isPageUsingIncorrectInfobox(disambiguation, otherInfoboxList)

for k, v in pairs(otherInfoboxList) do

if (string.match(disambiguation, k)) then

return true, v, debugMessageList["DEBUG_INCORRECT_INFOBOX"]:gsub("{}", k)

end

end

return false

end

-- Validate that the title has brackets that are part of the title and not part of disambiguation.

local function isOnExceptionList(title, exceptionList)

for _, v in ipairs(exceptionList) do

if (v == title) then

return true

elseif (string.match(title, v)) then

return true

end

end

return false

end

-- Get the disambiguation text and make sure that if the title has more than 1 pair of brackets, it returns the last one.

local function getDisambiguation(title)

local match = require("Module:String")._match

return match(title, "%s%((.-)%)", 1, -1, false, "")

-- return (string.match (title, '%s*%b()$') or ):gsub('[%(%)]', )

end

-- Validate that arg is not nill and not empty.

local function isEmpty(arg)

if (not arg or arg == "") then

return true

else

return false

end

end

-- Returns two objects:

--- The first is either an empty string or a tracking category which will appear when using the live version.

--- The second is a debug string which will appear when using /testcases.

local function main(title, invoker, validDisambiguationTypeList, validDisambiguationPatternList, exceptionList, otherInfoboxList, invalidTitleStyleList)

-- Exit module if the parameter has no value.

if (isEmpty(title)) then

return "", debugMessageList["DEBUG_EMPTY_TITLE"]

end

-- Exit module if the title has brackets that are part of the title (not disambiguation).

if (isOnExceptionList(title, exceptionList)) then

return "", debugMessageList["DEBUG_TITLE_ON_EXCEPTION"]

end

if (invoker == "infobox television season") then

if (#invalidTitleStyleList ~= 0) then

for i = 1, #invalidTitleStyleList do

if (string.find(title, invalidTitleStyleList[i])) then

return CATEGORY_INCORRECT, debugMessageList["DEBUG_NOT_VALID_FORMAT"]

end

end

end

end

-- Get the disambiguation.

local disambiguation = getDisambiguation(title)

-- Exit module if the title has no disambiguation.

if (isEmpty(disambiguation)) then

return "", debugMessageList["DEBUG_NO_DAB"]

end

-- Exit module if the disambiguation belongs to a different infobox.

local isValid, category, debugString = isPageUsingIncorrectInfobox(disambiguation, otherInfoboxList)

if (isValid) then

return category, debugString

end

-- Check if the disambiguation is valid.

isValid, debugString = validateDisambiguation(invoker, disambiguation, validDisambiguationTypeList, validDisambiguationPatternList)

-- Check if the disambiguation is not valid and add category.

if (not isValid) then

category = CATEGORY_INCORRECT

end

return category, debugString

end

return {

main = main,

DisambiguationPattern = DisambiguationPattern

}