|
|
(他の1人の利用者による、間の1版が非表示) |
1行目: |
1行目: |
| -- Module for handling Media files (Origin: Wikimedia Commons) | | -- Module for handling Media files (Origin: Wikimedia Commons) |
|
| |
|
| -- Helpers
| | require('strict') |
| local h = {}
| | |
| h.expandPage = function(fullPageName, args)
| | -- ================================================== |
| -- This expansion may fail, use it with pcall and inspect error status
| | -- === helper Lookup table ========================== |
| return mw.getCurrentFrame():expandTemplate{title = ':' .. fullPageName, args}
| | -- ================================================== |
| end
| | |
| h.expandPageNoFail = function(fullPageName, args)
| | local extensionMap = { |
| local ok, wikiText = pcall(h.expandPage, fullPageName, args)
| |
| if ok then
| |
| return wikiText
| |
| end
| |
| return ''
| |
| end
| |
| -- Limits in megapixels are currently stored in Commons templates, they could be in this module. | |
| -- There may be more limits for other supported mime types (djvu, flac, ogv, pdf, svg, webm, xcf). | |
| h.maxthumbMap = {
| |
| -- ['image/gif'] = h.expandPageNoFail('Template:LargeTIFF/limit', {}), -- current value is '50' but higher now
| |
| ['image/png' ] = h.expandPageNoFail('Template:LargePNG/limit', {}), -- current value is '2500'
| |
| ['image/tiff'] = h.expandPageNoFail('Template:LargeTIFF/limit', {}), -- current value is '50' but higher now
| |
| }
| |
| h.maxthumbMap['image/gif' ] = h.maxthumbMap['image/tiff'] -- current value is '50' but higher now
| |
| h.extensionMap = {
| |
| -- File types with full support in Commons (See [[c:Commons:File types]]). | | -- File types with full support in Commons (See [[c:Commons:File types]]). |
| DJVU = 'image/vnd.djvu', | | DJVU = 'image/vnd.djvu', |
61行目: |
46行目: |
| FLV = 'video/x-flv', -- (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' | | ICO = 'image/vnd.microsoft.icon', -- used in MediaWiki resources for 'website icons' |
| MP4 = 'video/mp4', -- please convert to OGV or WEBM | | MP4 = 'video/mp4', |
| QT = 'video/quicktime', -- (deprecated, replaced by MP4) please convert to OGV or WEBM | | QT = 'video/quicktime', -- (deprecated, replaced by MP4) please convert to OGV or WEBM |
| RA = 'audio/vnd.rn-realaudio', -- (deprecated, replaced by MP3) please convert to OGA | | RA = 'audio/vnd.rn-realaudio', -- (deprecated, replaced by MP3) please convert to OGA |
69行目: |
54行目: |
| XLS = 'application/vnd.ms-excel', -- please convert to PDF, DJVU, or Wiki | | XLS = 'application/vnd.ms-excel', -- please convert to PDF, DJVU, or Wiki |
| } | | } |
| h.parse = require("Module:HTMLParser").parse
| |
|
| |
|
| local File = function(title) | | -- ================================================== |
| local funcs = {} | | -- === Local functions ============================== |
| local titleInstance, metadataInstance
| | -- ================================================== |
| | |
| | local function filename(frame) |
| | return frame.args[1] or frame.args["file"] or frame.args["title"] |
| | end |
|
| |
|
| function getTitle() | | local function getMetadata(frame) |
| if titleInstance == nil then
| | local fname = filename(frame) |
| titleInstance = mw.title.new(title, 6)
| | local title |
| end | | if fname then |
| return titleInstance | | title = mw.title.new(fname, 6) |
| | else |
| | title = mw.title.getCurrentTitle() |
| | end |
| | if title then |
| | return title.file |
| | else |
| | return {exists=false} |
| end | | end |
| | end |
|
| |
|
| function getFullName()
| | -- ================================================== |
| return getTitle().prefixedText
| | -- === External functions =========================== |
| end
| | -- ================================================== |
| | local p = {} |
|
| |
|
| -- =p.File("Foo.bar.svg").extension()
| | -- p.csExtension("Foo.bar.svg") |
| -- @return "svg"
| | -- @return "svg" |
| funcs.extension = function() | | function p.csExtension(frame) |
| local parts = mw.text.split(title, '.', true)
| | local fname = filename(frame) or mw.title.getCurrentTitle().text |
| | local parts = mw.text.split(fname, '.', true) |
| | if #parts>1 then |
| return parts[#parts] | | return parts[#parts] |
| | else |
| | return '' |
| end | | end |
| | end |
|
| |
|
| -- =p.File("Foo.bar.svg").woExtension()
| | function p.extension(frame) |
| -- @return "Foo.bar" | | return p.csExtension(frame):lower() |
| -- Original author: Bawolff at [[Module:FileName]]
| | end |
| 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
| |
|
| |
| function getMetadata()
| |
| if metadataInstance == nil then
| |
| metadataInstance = getTitle().file
| |
| end
| |
| return metadataInstance
| |
| end
| |
| funcs.metadata = function()
| |
| return getMetadata()
| |
| end
| |
|
| |
|
| -- Mapping file extensions to MIME-types (only MIME types accepted for files in Commons).
| | function p.extensionUpper(frame) |
| -- Works even if file still does not exist.
| | return p.csExtension(frame):upper() |
| -- =p.File('Foo.bar.svg').extension()
| | end |
| -- @return 'image/svg+xml' | |
| funcs.mime = function()
| |
| local ok, metadata = pcall(funcs.metadata())
| |
| if ok and metadata.exists then
| |
| -- Note: does not work if file does not exist, where metadata == {'exists': false} only
| |
| return metadata.mimeType
| |
| end
| |
| -- mw.log('mime() is deprecated. Use metadata().mimeType.')
| |
| return h.extensionMap[funcs.extension():upper()] or 'unknown'
| |
| end
| |
|
| |
|
| -- =p.File('Foo.bar.tiff').maxthumb()
| | -- p.woExtension("Foo.bar.svg") |
| funcs.maxthumb = function() | | -- @return "Foo.bar" |
| return h.maxthumbMap[funcs.mime()] or 'unknown @Module:File'
| | -- Original author: Bawolff at [[Module:FileName]] |
| end
| | function p.woExtension(frame) |
| | local fname = filename(frame) or mw.title.getCurrentTitle().text |
| | local parts = mw.text.split(fname , '.', true) |
| | local upTo = #parts - 1 |
| | if upTo == 0 then upTo = 1 end |
| | return table.concat(parts, '.', 1, upTo) |
| | end |
|
| |
|
| funcs.dateWorkCreated = function()
| | function p.mime(frame) |
| -- Parse the expanded wiki text into an html root node and select a child node by specific ID.
| | local meta = getMetadata(frame) |
| local root = h.parse('<html>' ..
| | if meta.exists then |
| h.expandPageNoFail(getFullName(), {})
| | return meta.mimeType |
| :gsub('<nowiki>.*?</nowiki>', '')
| | else |
| .. '</html>')
| | return extensionMap[p.extensionUpper(frame)] or 'unknown' |
| local tdElem = root('#fileinfotpl_date')
| |
| for td in pairs(tdElem) do -- We queried an ID so there should be only one result in this loop. | |
| -- We need the next sibling, which doesn't seem to be directly supported by HTMLParser.
| |
| -- ... so ask him for the parent <tr> node and find the first <time> element in it.
| |
| local timeElem = td.parent('time')
| |
| for t in pairs(timeElem) do
| |
| return t.attributes['datetime']
| |
| end
| |
| end
| |
| end | | end |
| | end |
|
| |
|
| return funcs | | function p.mimeType(frame) |
| | return getMetadata(frame).mimeType |
| end | | end |
| h.getFile = function(frame)
| | |
| return File(frame.args[1] or frame.args["file"] or frame.args["title"] or mw.title.getCurrentTitle().text) | | function p.fileExists(frame) |
| | return getMetadata(frame).exists or '' |
| end | | 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.csExtension = function(frame)
| |
| return h.getFile(frame).extension()
| |
| end
| |
| p.woExtension = function(frame)
| |
| return h.getFile(frame).woExtension()
| |
| end
| |
| p.mime = function(frame)
| |
| return h.getFile(frame).mime()
| |
| end
| |
| p.fileExists = function(frame)
| |
| return h.getFile(frame).metadata().exists or ''
| |
| end
| |
| -- This one won't throw errors at you | | -- This one won't throw errors at you |
| p.fileExistsRelaxed = function(frame) | | function p.fileExistsRelaxed(frame) |
| local ok, metadata = pcall(h.getFile(frame).metadata) | | local ok, metadata = pcall(getMetadata(frame)) |
| if ok then | | if ok then |
| return metadata.exists or '' | | return metadata.exists or '' |
185行目: |
140行目: |
| end | | end |
| end | | end |
| p.mimeType = function(frame) | | |
| return h.getFile(frame).metadata().mimeType
| | function p.maxthumb(frame) |
| | -- Limits in megapixels are currently stored in Commons templates, they could be in this module. |
| | -- There may be more limits for other supported mime types (djvu, flac, ogv, pdf, svg, webm, xcf). |
| | local maxthumbMap = { |
| | ['image/gif'] = 1000, |
| | ['image/png' ] = 2500, -- see Template:LargePNG/limit |
| | ['image/tiff'] = 1000, -- see Template:LargeTIFF/limit |
| | } |
| | local mime = p.mime(frame) |
| | return maxthumbMap[mime] or 'unknown @Module:File' |
| end | | end |
| p.maxthumb = function(frame) | | |
| return h.getFile(frame).maxthumb() | | function p.dateWorkCreated(frame) |
| | return '' -- no longer supported |
| end | | end |
| p.dateWorkCreated = function(frame) | | |
| return h.getFile(frame).dateWorkCreated(frame) or '' | | function p.width(frame) |
| | return getMetadata(frame).width |
| end | | end |
| p.width = function(frame) | | |
| return h.getFile(frame).metadata().width | | function p.height(frame) |
| | return getMetadata(frame).height |
| end | | end |
| p.height = function(frame) | | |
| return h.getFile(frame).metadata().height | | function p.dimensions(frame) |
| | local d = getMetadata(frame) |
| | if d.exists then |
| | return d.width .. ' × ' .. d.height |
| | else |
| | return '' |
| | end |
| end | | end |
| p.dimensions = function(frame) | | |
| local d = h.getFile(frame).metadata() | | function p.size(frame) |
| return d.width .. ' × ' .. d.height
| | return getMetadata(frame).size |
| end | | end |
| p.size = function(frame)
| | |
| return h.getFile(frame).metadata().size
| | function p.pageCount(frame) |
| end
| | local pages = getMetadata(frame).pages or {1} |
| p.pageCount = function(frame) | |
| local pages = h.getFile(frame).metadata().pages or {1} | |
| return #pages | | return #pages |
| end | | end |
| -- Module autotest
| |
| 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()),
| |
| extensionLower = (t.extensionLower == 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\t>>\t' .. t.fileName .. '\n\t>>\t' .. stringResult) or '')
| |
| result = result and ret
| |
| end
| |
| return result
| |
| end
| |
| -- p.h = h -- if needed for running some tests
| |
|
| |
|
| return p | | return p |