aboutsummaryrefslogtreecommitdiff
path: root/mediawiki.lrdevplugin/MediaWikiApi.lua
diff options
context:
space:
mode:
Diffstat (limited to 'mediawiki.lrdevplugin/MediaWikiApi.lua')
-rwxr-xr-xmediawiki.lrdevplugin/MediaWikiApi.lua194
1 files changed, 194 insertions, 0 deletions
diff --git a/mediawiki.lrdevplugin/MediaWikiApi.lua b/mediawiki.lrdevplugin/MediaWikiApi.lua
new file mode 100755
index 0000000..420ab9f
--- /dev/null
+++ b/mediawiki.lrdevplugin/MediaWikiApi.lua
@@ -0,0 +1,194 @@
+-- This file is part of the LrMediaWiki project and distributed under the terms
+-- of the MIT license (see LICENSE.txt file in the project root directory or
+-- [0]). See [1] for more information about LrMediaWiki.
+--
+-- Copyright (C) 2014 by the LrMediaWiki team (see CREDITS.txt file in the
+-- project root directory or [2])
+--
+-- [0] <https://raw.githubusercontent.com/LrMediaWiki/LrMediaWiki/master/LICENSE.txt>
+-- [1] <https://commons.wikimedia.org/wiki/Commons:LrMediaWiki>
+-- [2] <https://raw.githubusercontent.com/LrMediaWiki/LrMediaWiki/master/CREDITS.txt>
+
+-- Code status:
+-- doc: partly
+-- i18n: complete
+
+local LrErrors = import 'LrErrors'
+local LrHttp = import 'LrHttp'
+local LrPathUtils = import 'LrPathUtils'
+local LrXml = import 'LrXml'
+
+local Info = require 'Info'
+
+local MediaWikiApi = {
+ userAgent = string.format('LrMediaWiki %d.%d', Info.VERSION.major, Info.VERSION.minor),
+ apiPath = nil,
+}
+
+--- URL-encode a string according to RFC 3986.
+-- Based on http://lua-users.org/wiki/StringRecipes
+-- @param str the string to encode
+-- @return the URL-encoded string
+function MediaWikiApi.urlEncode(str)
+ if str then
+ str = string.gsub(str, '\n', '\r\n')
+ str = string.gsub (str, '([^%w %-%_%.%~])',
+ function(c) return string.format('%%%02X', string.byte(c)) end)
+ str = string.gsub(str, ' ', '+')
+ end
+ return str
+end
+
+--- Convert HTTP arguments to a URL-encoded request body.
+-- @param arguments (table) the arguments to convert
+-- @return (string) a request body created from the URL-encoded arguments
+function MediaWikiApi.createRequestBody(arguments)
+ local body = nil
+ for key, value in pairs(arguments) do
+ if body then
+ body = body .. '&'
+ else
+ body = ''
+ end
+ body = body .. MediaWikiApi.urlEncode(key) .. '=' .. MediaWikiApi.urlEncode(value)
+ end
+ return body
+end
+
+function MediaWikiApi.parseXmlDom(xmlDomInstance)
+ local value = nil
+ if xmlDomInstance:type() == 'element' then
+ value = {}
+ for key, attribute in pairs(xmlDomInstance:attributes()) do
+ value[key] = attribute.value
+ end
+ for i = 1, xmlDomInstance:childCount() do
+ local child = xmlDomInstance:childAtIndex(i)
+ local childName, childNamespace = child:name()
+ value[childName] = MediaWikiApi.parseXmlDom(child)
+ end
+ elseif xmlDomInstance:type() == 'text' then
+ value = xmlDomInstance:text()
+ end
+ return value
+end
+
+function MediaWikiApi.performRequest(arguments)
+ arguments.format = 'xml'
+ local requestBody = MediaWikiApi.createRequestBody(arguments)
+ local requestHeaders = {
+ {
+ field = 'User-Agent',
+ value = MediaWikiApi.userAgent,
+ },
+ {
+ field = 'Content-Type',
+ value = 'application/x-www-form-urlencoded',
+ },
+ }
+
+ local resultBody, resultHeaders = LrHttp.post(MediaWikiApi.apiPath, requestBody, requestHeaders)
+
+ if resultHeaders.status ~= 200 then
+ LrErrors.throwUserError(LOC('$$$/LrMediaWiki/Api/HttpError=Received HTTP status ^1.', resultHeaders.status))
+ end
+
+ local resultXml = MediaWikiApi.parseXmlDom(LrXml.parseXml(resultBody))
+ if resultXml.error then
+ LrErrors.throwUserError(LOC('$$$/LrMediaWiki/Api/MediaWikiError=The MediaWiki error ^1 occured: ^2', resultXml.error.code, resultXml.error.info))
+ end
+ return resultXml
+end
+
+function MediaWikiApi.login(username, password, token)
+ local arguments = {
+ action = 'login',
+ lgname = username,
+ lgpassword = password,
+ }
+ if token then
+ arguments.lgtoken = token
+ end
+ local xml = MediaWikiApi.performRequest(arguments)
+
+ local loginResult = xml.login.result
+ if loginResult == 'Success' then
+ return true
+ elseif not token and loginResult == 'NeedToken' then
+ return MediaWikiApi.login(username, password, xml.login.token)
+ end
+
+ return loginResult
+end
+
+function MediaWikiApi.getEditToken()
+ local arguments = {
+ action = 'tokens',
+ }
+ local xml = MediaWikiApi.performRequest(arguments)
+ return xml.tokens.edittoken
+end
+
+function MediaWikiApi.existsFile(fileName)
+ local arguments = {
+ action = 'query',
+ titles = 'File:' .. fileName,
+ }
+ local xml = MediaWikiApi.performRequest(arguments)
+ return xml.query and xml.query.pages and xml.query.pages.page and not xml.query.pages.page.missing
+end
+
+function MediaWikiApi.upload(fileName, sourceFilePath, text, comment, ignoreWarnings)
+ local sourceFileName = LrPathUtils.leafName(sourceFilePath)
+
+ local arguments = {
+ action = 'upload',
+ filename = fileName,
+ text = text,
+ comment = comment,
+ token = MediaWikiApi.getEditToken(),
+ format = 'xml',
+ }
+ if ignoreWarnings then
+ arguments.ignorewarnings = 'true'
+ end
+ local requestHeaders = {
+ {
+ field = 'User-Agent',
+ value = MediaWikiApi.userAgent,
+ },
+ }
+ local requestBody = {}
+ for key, value in pairs(arguments) do
+ requestBody[#requestBody + 1] = {
+ name = key,
+ value = value,
+ }
+ end
+ requestBody[#requestBody + 1] = {
+ name = 'file',
+ fileName = sourceFileName,
+ filePath = sourceFilePath,
+ contentType = 'application/octet-stream',
+ }
+
+ local resultBody, resultHeaders = LrHttp.postMultipart(MediaWikiApi.apiPath, requestBody, requestHeaders)
+
+ if resultHeaders.status ~= 200 then
+ LrErrors.throwUserError(LOC('$$$/LrMediaWiki/Api/HttpError=Received HTTP status ^1.', resultHeaders.status))
+ end
+
+ local resultXml = MediaWikiApi.parseXmlDom(LrXml.parseXml(resultBody))
+ if resultXml.error then
+ LrErrors.throwUserError(LOC('$$$/LrMediaWiki/Api/MediaWikiError=The MediaWiki error ^1 occured: ^2', resultXml.error.code, resultXml.error.info))
+ end
+
+ local uploadResult = resultXml.upload.result
+ if uploadResult == 'Success' then
+ return true
+ else
+ return uploadResult
+ end
+end
+
+return MediaWikiApi