:Module:User:SuggestBot/WikiProjects

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'] .. "
" .. 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