Module:FileMedia

local FileMedia = { suite = "FileMedia", serial = "2018-07-21", item  = 24765326 } --[=[ FileMedia ]=]

FileMedia.failsafe = function ( assert ) local since = assert local r   if since == "wikidata" then local item = FileMedia.item; since = false; if type( item ) == "number" and  item > 0 then local ent = mw.wikibase.getEntity( string.format( "Q%d", item ) ); if type( ent ) == "table" then local vsn = ent:formatPropertyValues( "P348" ); if type( vsn ) == "table" and type( vsn.value) == "string" and vsn.value ~= "" then r = vsn.value; end end end end if not r then if not since or  since <= FileMedia.serial then r = FileMedia.serial else r = false end end return r end -- FileMedia.failsafe

FileMedia.getExtension = function ( ask ) -- Retrieve "file name extension" from file name -- Precondition: --    ask  -- file name; string, or nil -- Postcondition: --    Returns string, or false local r = false local s = FileMedia.getTitle( ask ) if s then s = ask:match( ".%.(%w+)%s*$" ) if s then r = s:lower end end return r end -- FileMedia.getExtension

FileMedia.getHeight = function ( ask ) -- Retrieve image height -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns number, or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.height end end return r end -- FileMedia.getHeight

FileMedia.getHeightWidth = function ( ask ) -- Retrieve image height x width -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns string like "123x456px", or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.height if r then r = string.format("%dx%dpx", r, d.file.width) end end end return r end -- FileMedia.getHeightWidth

FileMedia.getMimeType = function ( ask ) -- Retrieve file MimeType -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns string, or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.mimeType end end return r end -- FileMedia.getMimeType

FileMedia.getPageCount = function ( ask ) -- Retrieve number of file pages (paged media fragments) -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns number (0 if not paged media), or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.pages if r then r = #r elseif d.file.size then r = 0 end end end return r end -- FileMedia.getPageCount

FileMedia.getPages = function ( ask ) -- Retrieve table of file page sizes (paged media fragments) -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns table, or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.pages end end return r end -- FileMedia.getPages

FileMedia.getSize = function ( ask ) -- Retrieve file size -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns number, or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.size end end return r end -- FileMedia.getSize

FileMedia.getTitle = function ( ask ) -- Retrieve file page title from page name -- Precondition: --    ask  -- file name; string, or nil -- Postcondition: --    Returns string, or false if not a valid file local r = false if FileMedia.isType( ask, "file" ) then local space, s = ask:match( "^([^:]+):(.+)$" ) if space then if FileMedia.isSpacing( space ) then r = mw.text.trim( s ) end else r = mw.text.trim( ask ) end end return r end -- FileMedia.getTitle

FileMedia.getType = function ( ask ) -- Retrieve supposed file type from "file name extension" -- Precondition: --    ask  -- file name; string, or nil -- Postcondition: --    Returns string, or false --            "audio" --            "data" --            "paged" --            "pixel" --            "program" --            "style" --            "vector" --            "video" local r = false if ask then local s = ask:match( ".%.(%w+)%s*$" ) if s then local ext = mw.loadData( "Module:FileMedia/extensions" ) if ext then s = ext[ s:lower ] if s then r = s               end end end end return r end -- FileMedia.getType

FileMedia.getWidth = function ( ask ) -- Retrieve image width -- Precondition: --    ask  -- file name or title; string, or nil -- Postcondition: --    Returns number, or false or nil local r = false local s = FileMedia.getTitle( ask ) if s then local d = mw.title.makeTitle( "File", s ) if d and d.file then r = d.file.width end end return r end -- FileMedia.getWidth

FileMedia.isFile = function ( ask ) -- Is this a valid (existing) file title or file name? -- Precondition: --    ask  -- file title or file name; string, or nil -- Postcondition: --    Returns boolean -- Expensive function. local r   local s = FileMedia.getTitle( ask ) if s then r = mw.title.makeTitle( "File", s ).fileExists else r = false end return r end -- FileMedia.isFile

FileMedia.isSpacing = function ( ask ) -- Is presumed space name not conflicting with files? -- Precondition: --    ask  -- possible space name; string, or nil -- Postcondition: --    Returns boolean; false: conflict local r = true if ask then local space = mw.site.namespaces[ mw.text.trim( ask ) ] if space then space = space.canonicalName r    = ( space == "Media"  or  space == "File" ) end end return r end -- FileMedia.isSpacing

FileMedia.isType = function ( ask, against ) -- Does file name match type expectation? -- Precondition: --    ask      -- file name; string, or nil --    against  -- expectation; generic or "file" or "image" or any -- Postcondition: --    Returns boolean local r = false local s = FileMedia.getType( ask ) if s then local scope if against == "file" then scope = "audio paged pixel vector video" elseif against == "image" then scope = "paged pixel vector" end if scope then local suffix = ask:match( ".%.(%w+)%s*$" ) if suffix and  suffix:lower ~= "doc" then r = scope:match( s ) end else r = ( s == against ) end if r then s = ask:match( "^%s*([^:]+)%s*:" ) r = FileMedia.isSpacing( s ) end end return r end -- FileMedia.isType

FileMedia.setParSize = function ( assign, atleast, ahead ) -- Check or adapt transclusion parameter for size -- Precondition: --    assign   -- size parameter; string, or nil --    atleast  -- fallback value; string, or nil --    ahead    -- start with pipe, if not empty; boolean, or nil -- Postcondition: --    Returns px string, if valid or corrected, else false local r = false if type( assign ) == "string" then local s = mw.text.trim( assign ) if s ~= "" then if s:match( "^[1-9]%d?%d?%d?$" ) then r = s .. "px" else s = s:lower if s:match( "%d$" ) then s = s .. "px" elseif not s:match( "%dpx$" ) then s = false end if s then if s:match( "^[1-9]%d?%d?%d?px$" ) or                       s:match( "^[1-9]%d?%d?%d?x[1-9]%d?%d?%d?px$" )  or                       s:match( "^x[1-9]%d?%d?%d?px$" ) then r = s                   end end end end end if not r and atleast then r = atleast end if r and ahead then r = "|" .. r   end return r end -- FileMedia.setParSize

-- Export local p = { }

p.getExtension = function ( frame ) -- Retrieve "file name extension" from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getExtension,                           frame.args[ 1 ] ) return r or "" end -- p.getExtension

p.getHeight = function ( frame ) -- Retrieve image height from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getHeight,                           frame.args[ 1 ] ) return r or "" end -- p.getHeight

p.getHeightWidth = function ( frame ) -- Retrieve image height x width from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getHeightWidth,                           frame.args[ 1 ] ) return r or "" end -- p.getHeightWidth

p.getMimeType = function ( frame ) -- Retrieve MIME type from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getMimeType,                           frame.args[ 1 ] ) return r or "" end -- p.getMimeType

p.getPageCount = function ( frame ) -- Retrieve number of file pages (paged media fragments) from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getPageCount,                           frame.args[ 1 ] ) return r or "" end -- p.getPageCount

p.getSize = function ( frame ) -- Retrieve file size from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getSize,                           frame.args[ 1 ] ) return r or "" end -- p.getSize

p.getTitle = function ( frame ) -- Retrieve file title from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getTitle,                           frame.args[ 1 ] ) return r or "" end -- p.getTitle

p.getType = function ( frame ) -- Retrieve supposed file type from "file name extension" --    1  -- file title or name local lucky, r = pcall( FileMedia.getType,                           frame.args[ 1 ] ) return r or "" end -- p.getType

p.getWidth = function ( frame ) -- Retrieve file width from page title or name --    1  -- file title or name local lucky, r = pcall( FileMedia.getWidth,                           frame.args[ 1 ] ) return r or "" end -- p.getWidth

p.isFile = function ( frame ) -- Is this a valid (existing) file title or file name? --    1  -- file name; with or without namespace -- Expensive function. local lucky, r = pcall( FileMedia.isFile,                           frame.args[ 1 ] ) return r and "1" or "" end -- p.isFile

p.isType = function ( frame ) -- Does file name match type expectation? --    1  -- file name --    2  -- expected local r       = false local supposed = frame.args[ 2 ] if supposed then supposed = supposed:match( "^%s*(%w+)%s*$" ) if supposed then local lucky lucky, r = pcall( FileMedia.isType,                             frame.args[ 1 ],                              supposed:lower ) end end return r and "1" or "" end -- p.isType

p.setParSize = function ( frame ) -- Check or adapt transclusion parameter [ 1 ] for size -- Returns px string, if valid or corrected, else empty --        Fallback to parameter [ 2 ] local lead = frame.args.pipe local r   if lead  and ( lead == "" or  lead == "0" ) then lead = false end r = FileMedia.setParSize( frame.args[ 1 ],                             frame.args[ 2 ],                              lead ) return r or "" end -- p.setParSize

p.failsafe = function ( frame ) -- Versioning interface local s = type( frame ) local since if s == "table" then since = frame.args[ 1 ] elseif s == "string" then since = frame end if since then since = mw.text.trim( since ) if since == "" then since = false end end return FileMedia.failsafe( since ) or  "" end -- p.failsafe

p.FileMedia = function return FileMedia end -- p.FileMedia

return p