![]() |
VOOZH | about |
This module implements {{Issue list}}.
localp={} p.i18n={ process_args_module="Module:ProcessArgs", description_arg_prefix=nil,-- specify a string if you want to have separate parameters for descriptions of searched terms. -- Useful as terms are necessarily English, and users may want to have localized descriptions term_wrap='"%s"',-- a string wrapped into quotes, for text output; quotes may be language-specific pair_separator=", ", final_or_separator=", or ", two_item_or_separator=" or ",-- the separators are used to concatenate tables to make strings like "A or B", "A, B, or C" message='Issues relating to %s are maintained on the [[bug tracker]]. Issues should be reported and viewed [https://bugs.mojang.com/issues/?jql=%s there].', message_dungeons='Issues for \'\'Minecraft Dungeons\'\' relating to %s are no longer maintained on the [[bug tracker]] since September 28, 2023.', message_legends='Issues for \'\'Minecraft Legends\'\' relating to %s are no longer maintained on the [[bug tracker]] since January 10, 2024.', namespace_dungeons=10000, namespace_legends=10006, release_mc='1.21.10' } --[[ Concatenates a table using a set of separators. Behavior depends on which of the separators are provided. Parameters: • some_table (sequence table): the table to concatenate; required • pair_sep (string; required), final_sep (string), two_sep (string): separators used in concatenation If only `pair_sep` is provided, behaves like `table.concat(some_table, pair_sep)`. If `final_sep` is also provided, it is used to separate the last pair of table entries. If `two_sep` is also provided, it is used to separate the entries instead of `final_sep` if there are two of them. Returns a string with the concatenated table. Example: ``` local table1 = {"a", "b", "c"} local table2 = {"a", "b"} print( concat_table_3sep(table1, ", ") ) -- prints "a, b, c" print( concat_table_3sep(table1, ", ", " and ") ) -- prints "a, b and c" print( concat_table_3sep(table1, ", ", ", and ", " and ") ) -- prints "a, b, and c" print( concat_table_3sep(table2, ", ") ) -- prints "a, b" print( concat_table_3sep(table2, ", ", " and ") ) -- prints "a and b" print( concat_table_3sep(table2, ", ", ", and ", " and ") ) -- prints "a and b" ``` ]] functionp.concat_table_3sep(some_table,pair_sep,final_sep,two_sep) locallength=#some_table iflength<3then localsep=two_seporfinal_seporpair_sep returntable.concat(some_table,sep) end localresult_table={} forindex=1,length-2do table.insert(result_table,some_table[index]) table.insert(result_table,pair_sep) end table.insert(result_table,some_table[length-1]) table.insert(result_table,final_seporpair_sep) table.insert(result_table,some_table[length]) returntable.concat(result_table) end --[[ Similar to ipairs, but iterates over string keys with a constant prefix and a variable integer suffix. Parameters: • some_table (table): the table to iterate over • prefix (string): the key prefix to use when iterating • allow_numberless (boolean, optional): if truthy, allows reading the key without an integer suffix as if it had the suffix 1. WARNING: behavior is unspecified if: 1) allow_numberless is truthy; 2) a key without an integer suffix is mapped to a value; 3) a key with integer suffix 1 is also mapped to a value. In such cases, there is no guarantee on which of the two values is used. Example: ``` local t = { a1 = 1, a2 = 4, a3 = 9 } for index, value in prefixed_ipairs(t, "a") do print(index, value) end ``` This prints ``` 1 1 2 4 3 9 ``` With `allow_numberless = true`, the above example would also work identically for the following table: ``` local t = { a = 1, a2 = 4, a3 = 9 } ``` However, with the following table, the example may print either 1 or 2 in the first line, depending on how prefixed_ipairs is currently implemented: ``` local t = { a = 1, a1 = 2, -- Don't do this! a2 = 4, a3 = 9 } ``` ]] functionp.prefixed_ipairs(some_table,prefix,allow_numberless) locali=0 returnfunction() i=i+1 localvalue=some_table[prefix..tostring(i)] ifi==1andallow_numberlessandsome_table[prefix]~=nilthen value=some_table[prefix] end ifvalue~=nilthen returni,value end end end -- Helper functions ------------------------------------------------------------ -- Returns the human-readable description of search terms. localfunctionget_subject_string(inclusions) locallang=mw.language.getContentLanguage() localwrapped_inclusions={} forindex,inclusioninipairs(inclusions)do table.insert(wrapped_inclusions,p.i18n.term_wrap:format(lang:ucfirst(inclusion))) end returnp.concat_table_3sep( wrapped_inclusions, p.i18n.pair_separator, p.i18n.final_or_separator, p.i18n.two_item_or_separator ) end -- Returns the part of the query string that lists what items to query. localfunctionget_query_string_inclusions(inclusions) localquery_inclusions={} forindex,inclusioninipairs(inclusions)do table.insert(query_inclusions,'summary ~ "'..inclusion..'"') end return"("..table.concat(query_inclusions,' OR ')..")" end -- Returns the part of the query string that removes certain items from the output. localfunctionget_query_string_exclusions(exclusions) if#exclusions==0then return"" end localnegated_exclusions={} forindex,exclusioninipairs(exclusions)do table.insert(negated_exclusions,"-"..exclusion) end localexclusions_string=table.concat(negated_exclusions," ") return(' AND summary ~ "%s"'):format(exclusions_string) end --[[ Returns the link query string for Mojira. Note about numbers for resolution: the JIRA manual recommends searching resolution IDs instead of names. Here's Mojira's IDs: 1 = fixed 2 = won't fix 3 = duplicate 4 = incomplete 5 = cannot reproduce 6 = works as intended 7 = invalid "Unresolved" is seen as "empty" in JIRA. ]] localfunctionget_link_query_string(projects,inclusions_string,exclusions_string) localquery_string='project in (' ..projects ..') AND (resolution is EMPTY OR resolution in (1, 2, 6))' ..exclusions_string .." AND " ..inclusions_string .." ORDER BY resolution DESC" returnmw.uri.encode(query_string,"PATH") end --[[ Returns the api query strings for Mojira. ]] localfunctionget_api_query_strings(api_list,projects,inclusions_string,exclusions_string) forprojectinmw.text.gsplit(projects,'%s*,%s*')do ifproject=='MC'then api_list:attr('data-mc', -- No project needed due to post-migration API quirks -- 'project = MC' '"Confirmation Status" != Unconfirmed' ..' AND (' ..'resolution is EMPTY' ..' OR (' ..'resolution = "Fixed"' ..' AND affectedVersion = "'..p.i18n.release_mc..'"' ..'))' ..exclusions_string ..' AND ' ..inclusions_string ..' ORDER BY ' ..'resolution ASC, ' ..'"Mojang Priority" ASC, ' ..'"Votes Count" DESC, ' ..'key ASC' ) elseifproject=='MCD'orproject=='MCLG'then api_list:attr('data-'..project:lower(), -- 'project = ' .. project '"Confirmation Status" != Unconfirmed' ..' AND (resolution is EMPTY OR resolution = "Won\'t Fix")' ..exclusions_string ..' AND ' ..inclusions_string ..' ORDER BY ' ..'"Votes Count" DESC, ' ..'key ASC' ) else api_list:attr('data-'..project:lower(), -- 'project = ' .. project '"Confirmation Status" != Unconfirmed' ..' AND resolution is EMPTY' ..exclusions_string ..' AND ' ..inclusions_string ..' ORDER BY ' ..'"Votes Count" DESC, ' ..'key ASC' ) end end end -- Main functions and entry points --------------------------------------------- p.issue_list=function(descriptions,projects,inclusions,exclusions) localsubject_string=get_subject_string(descriptionsorinclusions) localinclusions_string=get_query_string_inclusions(inclusions) localexclusions_string=get_query_string_exclusions(exclusions) locallink_query_string=get_link_query_string(projects,inclusions_string,exclusions_string) localmessage=p.i18n.message ifmw.title.getCurrentTitle().namespace==p.i18n.namespace_dungeonsthen message=p.i18n.message_dungeons elseifmw.title.getCurrentTitle().namespace==p.i18n.namespace_legendsthen message=p.i18n.message_legends end message=message:format(subject_string,link_query_string) localapi_list=mw.html.create('div') api_list:addClass('issue-list') get_api_query_strings(api_list,projects,inclusions_string,exclusions_string) returnmessage..'\n'..tostring(api_list) end -- Entry point for [[Template:Issue list]]. p.issue_list_entry=function(frame) localargs=require(p.i18n.process_args_module).norm() localinclusions={} localexclusions={} for_,arginipairs(args)do ifarg:find("^-")then table.insert(exclusions,(arg:gsub("-",""))) else table.insert(inclusions,arg) end end if#inclusions==0then inclusions[1]=mw.title.getCurrentTitle().text end localprojects=args.projectsornil ifprojects==nilthen ifmw.title.getCurrentTitle().namespace==p.i18n.namespace_dungeonsthen projects='MCD' elseifmw.title.getCurrentTitle().namespace==p.i18n.namespace_legendsthen projects='MCLG' else projects='MC, MCPE' end end localdescriptions ifp.i18n.description_arg_prefixthen descriptions={} for_,arginp.prefixed_ipairs(args,p.i18n.description_arg_prefix,true)do table.insert(descriptions,arg) end if#descriptions==0then table.insert(descriptions,mw.title.getCurrentTitle().text) end end returnp.issue_list(descriptions,projects,inclusions,exclusions) end returnp