Module:Energy meter

-- This module implements Template:Energy meter.

local lang = mw.language.getContentLanguage()

local yesno = require('Module:Yesno')

local p = {}

local function round(n)

return math.floor(n + 0.5)

end

local function sanitizePercentage(n)

if n < 0 then

n = 0

elseif n > 100 then

n = 100

end

return n

end

local function getUnixTime(date)

return tonumber(lang:formatDate('U', date))

end

local function calculateHumanPercentage(energyleft)

if not energyleft then

error("the 'energyleft' parameter must be specified for all non-bot users", 3)

end

energyleft = tonumber(energyleft)

if not energyleft then

error("the 'energyleft' parameter was not a valid number", 3)

end

return sanitizePercentage(energyleft)

end

local function calculateBotPercentage(expiry)

if not expiry then

error("the 'expiry' parameter must be specified for all bot users", 3)

end

local now = getUnixTime()

local lifespan = getUnixTime('now + 6 months') - now

local timeLeft = getUnixTime(expiry) - now

local percentage = timeLeft / lifespan * 100

return sanitizePercentage(percentage)

end

local function calculateDaysLeft(expiry)

local seconds = getUnixTime(expiry) - getUnixTime()

local days = seconds / 60 / 60 / 24

if days < 0 then

days = 0

end

return math.floor(days)

end

function p._main(args, frame)

frame = frame or mw.getCurrentFrame()

local isBot = yesno(args.isbot) or false

local isHorizontal = yesno(args.ishorizontal) or false

local isTopIcon = yesno(args.istopicon) or false

local isThumb = not yesno(args.nothumb)

-- Percentage

local percentage

if isBot then

percentage = calculateBotPercentage(args.expiry)

else

percentage = calculateHumanPercentage(args.energyleft)

end

-- Power level

local powerLevel = math.ceil(percentage / 100 * 6)

-- Image name

local image

do

local images = {

'Empty',

'Almost Empty',

'Partially Empty',

'Half',

'Partially Full',

'Almost Full',

'Full'

}

image = images[powerLevel + 1]

image = 'Battery ' .. image

if isHorizontal then

image = 'Horizontal ' .. image

end

image = image .. '.png'

end

-- Caption

local caption

if isBot then

caption = 'This bot has ' .. round(percentage) .. '% power left.'

if powerLevel == 2 then

caption = caption .. '
This bot is running low on energy.'

elseif powerLevel == 1 then

caption = caption ..

'
This bot has almost no energy left.' ..

'
It will die in ' ..

calculateDaysLeft(args.expiry) ..

' day(s).' ..

'
Contact operator.'

elseif powerLevel == 0 then

caption = caption .. '
This bot has died. Contact the operator.'

end

else

-- Is a human

caption = 'This user has ' .. round(percentage) .. '% energy left.'

if powerLevel == 2 then

caption = caption ..

'
This user is running low on energy.' ..

'
They may not be very active on Wikipedia.'

elseif powerLevel == 1 then

caption = caption ..

'
This user has almost no energy left.' ..

'
They may retire soon.'

elseif powerLevel == 0 then

caption = caption .. '
This user retired.'

end

end

-- Width

local width

if isTopIcon then

width = '25'

else

width = '200'

end

width = width .. 'px'

-- Position

local position

if not isTopIcon then

position = args.position or 'right'

end

-- File link

local fileLink = string.format(

'File:%s',

image,

caption,

width,

position and '|' .. position or '',

not isTopIcon and isThumb and '|thumb' or ''

)

-- Output

if isTopIcon then

local name = 'energy-meter'

if args.sortkey then

name = args.sortkey .. '-' .. name

end

return frame:extensionTag{

name = 'indicator',

content = fileLink,

args = {name = name}

}

else

return fileLink

end

end

function p.main(frame)

local args = require('Module:Arguments').getArgs(frame, {

wrappers = 'Template:Energy meter'

})

return p._main(args, frame)

end

return p