Purpose
editThis module supports SuggestBot when posting or updating suggestions to WikiProjects, using the design layout of WikiProject X.
Usage
edit{{#invoke:User:SuggestBot|function_name}}
local wp = {}
-- BTW: Lua allows literal strings declarations [[ ]], but the syntax
-- highlighter doesn't support them properly, fails if the string contains
-- another set of square brackets...
-- Number of articles in each list if the page invoking this module is transcluded
local inc_limit = 2
-- Mapping of article assessment ratings to low/medium/high as numbers
local rating_numbers = {FA=3, A=3, GA=3, B=2, C=2, Start=1, Stub=1, NA=0}
local rating_names = {FA='High', A='High', GA='High', B='Medium', C='Medium',
Start='Low', Stub='Low', NA='Unassessed'}
-- Mapping of SuggestBot's task categories (see [[User:SuggestBot/Documentation/Task categories]])
-- to section titles and descriptions, and the order in which they will be presented
local taskcat_order = {'source', 'cleanup', 'expand', 'unenc',
'merge', 'wikify', 'orphan', 'stub'}
local taskcat_map = {
source={
title='Add sources',
descr='See [[Wikipedia:Citing sources]] for more information.'
},
cleanup={
title='Cleanup',
descr='Improve the presentation of content.'
},
expand={
title='Expand',
descr='Add more information to these articles.'
},
unenc={
title='Unencyclopaedic',
descr='Remove content that is not relevant for an encyclopaedia.'
},
merge={
title='Merge',
descr='Should this article be merged with another article?'
},
wikify={
title='Wikify',
descr='Improve the wiki-formatting on this article.'
},
orphan={
title='Orphan',
descr='Few or no articles link to this article.'
},
stub={
title='Stub',
descr='Expand on this brief article.'
}
}
-- Mapping of needs (specific tasks to improve an article) to descriptions
local needs_list = {'content', 'headings', 'links', 'images', 'sources'}
local needs_map = {content='more content',
headings='proper section headings',
links='more wikilinks',
images='more images',
sources='more sources'}
-- Local support functions follow below
local function has_key(tbl, key)
-- Check if the given table has the given key
return tbl[key] ~= nil
end
local function sort_articles(arglist, task_cats)
-- Sort the given argument list into a table mapping task categories
-- to a list of articles in that task category.
local sorted_arts = {}
for i, task_cat in pairs(task_cats) do
sorted_arts[task_cat] = {}
end
-- 0-based index of the current article being processed
local cur_art = 0
while arglist[(cur_art * 6) + 1] do
local cur_idx = cur_art * 6
local task_cat = arglist[cur_idx + 1]
-- Do we have this task category in our table?
if sorted_arts[task_cat] then
table.insert(sorted_arts[task_cat], {
tag=task_cat, title=arglist[cur_idx + 2],
views=arglist[cur_idx + 3],
cur_qual=arglist[cur_idx + 4],
pred_qual=arglist[cur_idx + 5],
tasks=arglist[cur_idx + 6]
})
end
cur_art = cur_art + 1
end
return sorted_arts
end
local function randomizeArray(t, limit)
-- Randomizes an array. It works by iterating through the list backwards, each time swapping the entry
-- "i" with a random entry. Courtesy of Xinhuan at http://forums.wowace.com/showthread.php?p=279756
-- If the limit parameter is set, the array is shortened to that many elements after being randomized.
-- The lowest possible value is 0, and the highest possible is the length of the array.
local len = #t
for i = len, 2, -1 do
local r = math.random(i)
t[i], t[r] = t[r], t[i]
end
if limit and limit < len then
local ret = {}
for i, v in ipairs(t) do
if i > limit then
break
end
ret[i] = v
end
return ret
else
return t
end
end
local function make_ratingdesc(assessment, prediction)
-- Make a string that describes the article's quality
-- Quality: Low, Assessed class: Stub, Predicted class: Stub
return "Quality: " .. rating_names[prediction] ..
", Assessed class: " .. assessment ..
", Predicted class: " .. prediction
end
local function make_needs(needs)
-- From the given comma-separated list of needs, make a string that
-- describes those needs based on needs_map
local result = ''
for i, task in ipairs(needs_list) do
if string.find(needs, task) then
result = result .. ", " .. needs_map[task]
end
end
-- Remove the first two characters (", ")
result = mw.ustring.sub(result, 3)
-- Return with the first character in upper-case, from http://lua-users.org/wiki/StringRecipes
return result:gsub("^%l", string.upper)
end
-- Globally exposed functions follow below
function wp.suggestions(frame)
-- Process the suggested articles given in the frame's arguments
-- and build lists of articles for each task category defined in the global
-- list of categories above.
-- Keyword arguments:
-- * is_included=yes: passed in to limit lists to two items each when
-- the page of the call is transcluded
-- * list_col=[colour value]: defines the CSS colour value of list headers
-- * item_col=[colour value]: defines the CSS colour value of list items
--
-- The rest of the arguments are sets of six parameters describing each
-- suggested article, as follows:
-- 1: task category
-- 2: article title
-- 3: number of average views/day (14 days prior to the update)
-- 4: assessed quality
-- 5: predicted quality
-- 6: comma-separated list of specific tasks for improving this article
local list_col = '#086'
local item_col = '#37f'
if has_key(frame, 'list_col') then
list_col = frame['list_col']
end
if has_key(frame, 'item_col') then
item_col = frame['item_col']
end
local is_included = false
if has_key(frame.args, 'is_included') then
is_included = true
end
-- When was the page this is invoked from last updated?
local last_update = frame:expandTemplate{title='WPX last updated',
args={frame:getParent():getTitle()}}
local result = ''
-- sort the supplied suggested articles and process into lists…
local sorted_articles = sort_articles(frame.args, taskcat_order)
for i, task_cat in pairs(taskcat_order) do
-- write list start
local list_params = {color=list_col,
title=taskcat_map[task_cat]['title'],
intro=taskcat_map[task_cat]['descr'] .. "<br />" .. last_update
}
if is_included then
list_params['constrained'] = 'yes'
end
result = result .. frame:expandTemplate{title='WPX list start',
args=list_params}
-- write some articles
local articles = sorted_articles[task_cat]
if is_included then
articles = randomizeArray(articles, inc_limit)
end
for j, article in pairs(articles) do
result = result .. frame:expandTemplate{title='WPX article recommendation',
args={
color=item_col,
title=article['title'],
pageviews=article['views'],
rating=rating_numbers[article['pred_qual']],
rating_description=make_ratingdesc(article['cur_qual'],
article['pred_qual']),
needs=make_needs(article['tasks'])
}
}
end
-- write list end
result = result .. frame:expandTemplate{title='WPX list end',
args={more=frame:getParent():getTitle(), section=string.gsub(taskcat_map[task_cat]['title'], ' ', '_')}}
end
return result
end
function wp.hello(frame)
return "Hello World!"
end
function wp.test_args(frame)
result = "The method got the following arguments:"
if has_key(frame, 'is_included') then
result = result .. "\n* is_included" .. frame.args['is_included']
end
for k, v in pairs(frame.args) do
result = result .. "\n* " .. k .. "=" .. v
end
return result
end
return wp