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

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 }