Module:Get images
Jump to navigation
Jump to search
Used in {{Get images}}.
Usage
{{#invoke:Get images|main|Page title|1<!-- number of images -->|<!-- set to "random" for random output -->}}
-- Module:GetImages
-- Returns a specified number of images from a page, optionally randomized.
-- First parameter: full page title
-- Second parameter: number of images or "all"
-- Third parameter: "random" to shuffle
-- Mode parameter: mode ("list", "gallery", or other for raw output)
local p = {}
local getArgs = require('Module:Arguments').getArgs
-- Hard maximum number of images to process
local MAX_IMAGES = 150
-- Fisher-Yates shuffle
local function shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
end
-- Remove HTML comments and templates
local function stripCommentsAndTemplates(text)
text = text:gsub("<!%-%-(.-)%-%->", "")
local pattern = "{{.-}}"
local maxIter = 50
local iter = 0
while text:find(pattern) and iter < maxIter do
text = text:gsub(pattern, "")
iter = iter + 1
end
return text
end
function p.main(frame)
local args = getArgs(frame)
local pageTitle = args[1]
local numParam = args[2] or "0"
local randomize = (args[3] or ""):lower()
local mode = (args.mode or ""):lower()
if not pageTitle then
return '<span class="error">Error: please specify a page title.</span>'
end
-- Load page content
local titleObj = mw.title.new(pageTitle)
if not titleObj or not titleObj.exists then
return '<span class="error">Error: page not found.</span>'
end
local text = titleObj:getContent() or ""
text = stripCommentsAndTemplates(text)
-- Collect all [[File:...]] and [[Image:...]] links
local images = {}
for fileLink in text:gmatch("%[%[[Ff]ile:.-%]%]") do
table.insert(images, fileLink)
end
for fileLink in text:gmatch("%[%[[Ii]mage:.-%]%]") do
table.insert(images, fileLink)
end
if #images == 0 then
return '<span class="error">No images with format <code>[[File:Example.jpg]]</code> found on page: ' .. pageTitle .. ', are you sure the page isn\'t a redirect?</span>'
end
-- Enforce maximum hard limit
if #images > MAX_IMAGES then
return '<span class="error">Error: page has more than ' .. MAX_IMAGES .. ' images. Maximum allowed is ' .. MAX_IMAGES .. '.</span>'
end
-- Shuffle if requested
if randomize == "random" then
math.randomseed(os.time())
shuffle(images)
end
-- Determine how many images to select
local maxImages
if type(numParam) == "string" and numParam:lower() == "all" then
maxImages = #images -- already capped by hard limit above
else
local numImages = tonumber(numParam) or 0
if numImages <= 0 then
return '<span class="error">Error: please specify a positive number of images.</span>'
end
maxImages = math.min(numImages, #images)
end
-- Select images
local selectedImages = {}
for i = 1, maxImages do
table.insert(selectedImages, images[i])
end
-- Output based on mode
if mode == "gallery" then
local galleryWidth = args.width or args.widths
local galleryHeight = args.height or args.heights
local galleryMode = args.gallerymode or args["gallery-mode"] or 'traditional'
local galleryPerRow = args.perrow or args["per-row"]
local galleryLines = {}
for _, link in ipairs(selectedImages) do
local cleanLink = link:match("%[%[([Ff]ile:[^|%]]+)") -- "File:Example.jpg"
if cleanLink then
table.insert(galleryLines, cleanLink)
end
end
local galleryAttrs = {
widths = galleryWidth or nil,
heights = galleryHeight or nil,
mode = galleryMode or nil,
perrow = galleryPerRow or nil
}
return frame:extensionTag("gallery", table.concat(galleryLines, "\n"), galleryAttrs)
elseif mode == "list" then
local listLines = {}
for _, link in ipairs(selectedImages) do
-- Extract just the file name
local filename = link:match("%[%[([Ff]ile:[^|%]]+)")
if filename then
-- Use the filename as the link text
table.insert(listLines, "* [[:"
.. filename .. "|" .. filename:match("File:(.+)") .. "]]")
end
end
return table.concat(listLines, "\n")
else
return table.concat(selectedImages, " ")
end
end
return p