File title and file information. If the code here grows beyond a border line, this should be converted to an interface and the processing code should be outsourced.

استعمال

ترمیم

Note that an error is thrown, if the title can't be constructed (e.g. a title containing invalid characters is supplied) or meta data isn't available (e.g. due to missing file or extraction error). It is your responsibility to catch them; in Lua through pcall(); from Wikitext as {{#iferror: {{#invoke:File|function|file=File:P%bar]baz.qqq}} | meaningful message}}.

From Wikitext

ترمیم

Search (Ctrl+F) for @exports.

Examples:
{{#invoke:File|extension|file=File:Test.jpg}}jpg
{{#invoke:File|width|file=File:Test.jpg}}3120
{{#invoke:File|size|file=File:Test.jpg}}21003815
{{#invoke:File|mime|file=File:Test.jpg}}image/jpeg deprecated
{{#invoke:File|mimeType|file=File:Test.jpg}}image/jpeg
{{#invoke:File|dateWorkCreated|file=File:Ballot-sprite.png}}
{{#invoke:File|fileExists|file=File:Ballot-sprite.png}}true
{{#invoke:File|fileExists|file=File:DOESNOTEXIST-0a8de8c83.png}}
{{#invoke:File|fileExistsRelaxed|file=File:Ba[!#llot-sprite.png}}

From Lua

ترمیم
local file = require( 'Module:File' )
local fileObj = file.File( 'File:Test.svg' )
local withoutExtension = fileObj.woExtension()
-- withoutExtension is now 'Test'

local exists = fileObj.metadata().exists
if exists then
   mw.log( fileObj.metadata().width )
end

-- Module for handling Media files (Origin: Wikimedia Commons)

-- Helpers
local h, File = {}
h.getFile = function(f)
	return File( f.args[1] or f.args["file"] or f.args["title"] or mw.title.getCurrentTitle().text )
end
h.getWikiText = function(title, frame)
	return '<html>' .. (frame or mw.getCurrentFrame()):expandTemplate{ title = title, args = {}}:gsub('<nowiki>.*?</nowiki>', '') .. '</html>'
end

File = function(title)
	local funcs = {}
	local titleInstance, metadataInstance

	function getTitle()
		if titleInstance == nil then
			titleInstance = mw.title.new( title, 6 )
		end
		return titleInstance
	end

	function getMetadata()
		if metadataInstance == nil then
			metadataInstance = getTitle().file
		end
		return metadataInstance
	end

	-- =p.File("Foo.bar.svg").extension()
	-- @return "svg"
	funcs.extension = function()
		local parts = mw.text.split( title, '.', true )
		return parts[#parts]
	end
	-- =p.File("Foo.bar.svg").woExtension()
	-- Original author: Bawolff at [[Module:FileName]]
	-- @return "Foo.bar"
	funcs.woExtension = function()
		local parts = mw.text.split( title , '.', true )
		local upTo = #parts - 1
		if upTo == 0 then upTo = 1 end
		return table.concat( parts, '.', 1, upTo )
	end
	-- Mapping file extensions to MIME-types (only MIME types accepted for files in Commons)
	funcs.extensionMap = {

		-- File types with full support in Commons (See [[Commons:File types]])
		DJVU = "image/vnd.djvu",
		FLAC = "audio/x-flac",
		GIF  = "image/gif",
		JPEG = "image/jpeg",
		JPG  = "image/jpeg",
		MID  = "audio/midi",
		OGA  = "audio/ogg",
		OGG  = "audio/ogg",
		OGV  = "video/ogg",
		PDF  = "application/pdf",
		PNG  = "image/png",
		SVG  = "image/svg+xml",
		TIF  = "image/tiff",
		TIFF = "image/tiff",
		WEBM = "video/webm",
		WAV  = "audio/x-wav",
		XCF  = "image/xcf",

		-- Other file types with restrictions (not accepted in standard uploads on Commons but in "User:" namespace)
		-- They could be supported in Wiki pages by embedding their content in an <pre> or <source> elements
		CSS  = "text/css",
		CSV  = "text/csv",
		JS   = "application/javascript",
		JSON = "application/json",
		TXT  = "text/plain",
		XML  = "application/xml",

		-- Only generated by MediaWiki on output of some queries, restricted in all uploads
		GZ   = "application/gzip", -- delivered only only for some wiki results
		ZIP  = "application/zip", -- delivered only for some wiki data exports

		-- Other file types not supported and to convert (a few of them may be in special administration namespaces)
		DOC  = "application/msword", -- please convert to PDF, DJVU, or Wiki
		F4V  = "video/mpeg", -- (deprecated, replaced by MP4) please convert to OGV or WEBM
		FLV  = "video/x-flv", -- (deprecated, replaced by MP4) please convert to OGV or WEBM
		ICO  = "image/vnd.microsoft.icon", -- used in MediaWiki resources for "website icons"
		MP3  = "audio/mpeg", -- please convert to OGA
		MP4  = "video/mpeg", -- please convert to OGV or WEBM
		QT   = "video/quicktime", -- (deprecated, replaced by MP4) convert to OGV or WEBM
		RA   = "audio/vnd.rn-realaudio", -- (deprecated, replaced by MP3) convert to OGA
		SWF  = "video/x-flv", -- (deprecated, replaced by MP4) convert to OGV or WEBM
		WMA  = "audio/x-ms-wma", -- please convert to OGA
		WMV  = "video/x-ms-wmv", -- please convert to OGV or WEBM
		XLS  = "application/vnd.ms-excel", -- please convert to PDF, DJVU, or Wiki

	}
	-- =p.File("Foo.bar.svg").extension()
	-- @return "image/svg+xml"
	funcs.mime = function()
		local extension = funcs.extension():upper()
		mw.log( 'mime() is deprecated. Use mimeType.' )
		return funcs.extensionMap[extension] or "unknown"
	end
	-- =p.File("Foo.bar.tiff").maxthumb()
	funcs.maxthumb = function()
		local mime = funcs.mime()
		if mime == "image/png" then
			return mw.getCurrentFrame():preprocess( '{{LargePNG/limit}}' )
		elseif mime == "image/tiff" or mime == "image/gif" then
			return mw.getCurrentFrame():preprocess( '{{LargeTIFF/limit}}' )
		else
			return 'unknown @Module:File'
		end
	end
	funcs.dateWorkCreated = function(frame)
		local page, htmlparser = mw.title.new( title, 6 ).prefixedText, require("Module:HTMLParser")
		local ok, html = pcall( h.getWikiText, page, frame )
		if not ok then return nil end
		-- add a root node
		local root = htmlparser.parse(html)
		local tdElem = root('#fileinfotpl_date')
		-- We queried an ID so there should be only one result
		for td in pairs(tdElem) do
			-- We need the next sibling, which doesn't seem to be directly supported by HTMLParser
			-- ... so ask him for the parent <tr> and find the <time> element in it
			local timeElem = td.parent('time')
			for t in pairs(timeElem) do
				return t.attributes['datetime']
			end
		end
	end
	funcs.metadata = function()
		return getMetadata()
	end
	return funcs
end

-- @exports
local p = {}
p.File = File
p.extension = function(frame)
	return h.getFile(frame).extension():lower()
end
p.extensionUpper = function(frame)
	return h.getFile(frame).extension():upper()
end
p.woExtension = function(frame)
	return h.getFile(frame).woExtension()
end
p.mime = function(frame)
	return h.getFile(frame).mime()
end
p.mimeType = function(frame)
	return h.getFile(frame).metadata().mimeType
end
p.maxthumb = function(frame)
	return h.getFile(frame).maxthumb()
end
p.dateWorkCreated = function(frame)
	return h.getFile(frame).dateWorkCreated() or ''
end
p.fileExists = function(frame)
	return h.getFile(frame).metadata().exists or ''
end
-- This one won't throw errors at you
p.fileExistsRelaxed = function(frame)
	local success, metadata = pcall(h.getFile(frame).metadata)
	if success then
		return metadata.exists or ''
	else
		return ''
	end
end
p.width = function(frame)
	return h.getFile(frame).metadata().width
end
p.height = function(frame)
	return h.getFile(frame).metadata().height
end
p.size = function(frame)
	return h.getFile(frame).metadata().size
end
p.pageCount = function(frame)
	local pages = h.getFile(frame).metadata().pages or {'page'}
	return #pages
end

p.runTests = function()
	local toTest = require('Module:File/tests/all')
	local result = true
	
	for i, t in ipairs(toTest) do
		local f = File(t.fileName)
		local stringResult = ''
		local ret = true
		local results = {
			extension = (t.extension == f.extension():lower()),
			extensionUpper = (t.extensionUpper == f.extension():upper()),
			woExtension = (t.woExtension == f.woExtension()),
			mime = (t.mime == f.mime()),
			maxthumb = (not (tonumber(f.maxthumb()) == nil) == t.maxthumbIsNumber),
			dateWorkCreated = t.dateWorkCreated == f.dateWorkCreated()
		}
		for k, v in pairs(results) do
			stringResult = stringResult .. k .. ': ' .. (v and 'ok    ' or 'failed') .. ' '
			ret = ret and v
		end
		mw.log(i, ret and 'passed' or 'FAILED', t.typeOfFileName, (not ret) and ('\n >>' .. stringResult .. '\n     >> ' .. t.fileName) or '')
		result = result and ret
	end
	return result
end

return p