API talk:Upload
Add topicFlag: Don't overwrite existing file
[edit]It would be nice if there was a flag that said: Don't overwrite any already existing file. This could help in preventing errors in bots, especially as Special:Upload mangles the filename a bit, so it's not entirely trivial to make sure a file of a given name does not already exist. --Tbleher 20:20, 14 February 2008 (UTC)
- Good one. I'll keep this in mind. --Catrope 21:32, 17 February 2008 (UTC)
File Contents?
[edit]Could you be more specific on the file contents? Is it just a bunch of bytes, UUEncoded, HEX, or what?
- Assuming you mean direct upload, the file content should be sent as part of the request in multipart/form-data format, so essentially yes, just a bunch of bytes. Gurch 05:03, 30 October 2009 (UTC)
I'm trying to do this with curl, but am having no luck with any kind of file content inclusion. Can you give an example? Here are some things I'm trying:
curl -b cookies.txt -d "action=upload&filename=exported.xml&file=$(cat exported.xml)&format=xml&token=$UPLOADTOKEN" http://lookipedia.net/w/api.php curl -b cookies.txt -d "action=upload&filename=exported.xml&file=<xml>text</xml>&format=xml&token=$UPLOADTOKEN" http://lookipedia.net/w/api.php curl -b cookies.txt -d "action=upload&filename=exported.xml&file=TEST&format=xml&token=$UPLOADTOKEN" http://lookipedia.net/w/api.php curl -b cookies.txt -d "action=upload&filename=exported.xml&file=@exported.xml&format=xml&token=$UPLOADTOKEN" http://lookipedia.net/w/api.php
In all cases I get this error:
<error code="missingparam" info="One of the parameters sessionkey, file, url, statuskey is required"/>
Pjrich 17:48, 10 October 2011 (UTC)
Upload by URL
[edit]I'm not having much more luck than you with uploading by URL. I did try retrieving httpstatus using the session key, and got the following result:
{u'upload': {u'content_length': u'5706', u'loaded': 5706, u'upload_session_key': u'12345'}}
But the file wasn't actually uploaded, and I don't see any way of determining what went wrong. --R'n'B 18:45, 29 October 2009 (UTC)
- It was broken before, was fixed in r58337 -- Gurch 05:11, 30 October 2009 (UTC)
badtoken
[edit]my script for accessing my mediawiki works with edits, moves and deletes. upload does not work - i get a badtoken response:
/api/error/@code=badtoken /api/error/@info=Invalid token
The doc says the token should be requested with prop=info, while regular edit tokens that i use have prop=info|revisions. The titles param given in the api doc is Foo which is not helpful - what is the title to be used? It would be great to have a full working example. -- Seppl2013 (talk) 08:52, 28 August 2013 (UTC)
Unrecognized value for parameter action: upload
[edit]I'm trying to upload a file via wget. Login and fetching token is OK, but on upload...
wget --load-cookies cookies.txt -O upload.xml \ --post-data "action=upload&filename=atlasmw-export.xml&file=[content goes here]&token=$EDITTOKEN" \ $API
I get this:
<error code="unknown_action" info="Unrecognized value for parameter 'action': upload" xml:space="preserve">
Documentation says:
api.php ? action=upload & filename=Test.txt & file=file_contents_here & token=+\
What's wrong? Using MediaWiki 1.15.1. Jpatokal 03:32, 20 November 2009 (UTC)
- It's a 1.16 feature. Max Semenik 05:45, 20 November 2009 (UTC)
overwrite: text parameter ignored
[edit]is there a good reason the text parameter is ignored when overwriting an existing file? imho it would make sense to overwrite the description, too. -- ∂ 23:55, 23 April 2010 (UTC)
Mediawiki Push Extension
[edit]Is anyone here familiar with the MW Push extension?
Trying to get it to work and not having much success.
The extension author has been less than helpful:
"In any case, I don't know what your issue is, so can't really help you any further."
I keep getting the same error:
Could not obtain an edit token on the target wiki
After reading and reading I suspect it might have something to do with the API Upload.
Any thoughts?
I had the same problem, it was something to do with my target media wiki installation, I re-installed a clean version (version 1.19.2) and it worked for me. This is a little vague sorry but perhaps that might help you if it isn't too much to do that, certainly something to try if you don't have any better options.
--Cgeroux (talk) 16:54, 15 October 2012 (UTC)
I'm not sure if this is the place to ask but I can only find one mention of the where the WikiMedia API can do a push. I'd like to know if you can get wikipedia to push a API request to a client to trigger an action? If so can you direct me to the API document(s) that discusses this?
--lukejmorrison (talk) 13:34, 2 June 2014 (EST New York)
Reverting to an earlier revision?
[edit]I'm not sure if this is the right place, but: Does anyone know if it's possible to revert to an earlier revision? A workaround using archived image URLs comes to mind, but the particular wiki has URL uploads disabled. --84.186.216.128 00:07, 24 February 2012 (UTC)
Async uploads
[edit]After digging through the code to find that wgAllowAsyncCopyUploads
iswas the correct parameter to allow an async upload, I now get the following error back:
Asynchronous copy uploads are no longer possible as of r81612
Is there any plan to re-introduce this option? --Brian McNeil (talk) 12:13, 18 September 2012 (UTC)
Real World Examples
[edit]Although not an API example, the Html2Wiki extension invokes the internal methods for uploading a file in it's saveImage() method.
$title = $this->makeTitle( NS_FILE ); $image = wfLocalFile( $title ); $result = $image->upload($tmpFile, $comment, $pageText);
Is there any real world example out there (as for the login API) how to use the upload API correctly? This could help many peoples. --Steviex2 (talk) 22:08, 7 February 2013 (UTC)
- Real-world examples include:
- Extension:UploadWizard (JavaScript using XHR)
- Apps/Commons (Java and Objective-C implementations)
- Wiki Loves Monuments app from last year[1] (JavaScript using PhoneGap FileTransfer API)
- --brion (talk) 01:02, 8 February 2013 (UTC)
...And Mobile Frontend. They are all big projects which I checked. What I really mean is a simple, basic code snipped like for the Login-API. The extensions are way too big to simply adapt it for own projects. Uploading into MediaWiki is a core feature which should be documented as well as the Login-API for developers.
Since more and more people are coding in PHP and JQuery, I would be happy to see simple examples to use the Upload-API with this languages.
This should be a small step for a professional MW-dev but a big step for the community :-).
PS: I can't understand why the internet is full of misunderstandings and time consuming trial and errors about this topic, while the original developers should know this few lines of code in every provided language very well. I also would appreciate informations wether we are talking about a file stream or a representation on disk. For example could we use $_FILES['userfile']['temp_name']
and or file_get_contents()
.
What would be a complete CURL-Realisation? Is the same possible with JQuery? What about the "same origin policy" in this context?
--Steviex2 (talk) 01:44, 8 February 2013 (UTC)
- I'll see about whipping up some PHP and JS examples... In the meantime, the thing to know about cross-origin policy is that you probably won't be able to make a successful authenticated POST request to the API from JavaScript on another domain unless it's on the short whitelist of Wikimedia sites. That is, you could upload a file to Commons from a gadget on Wikipedia, but not from an arbitrary web site. but if you route through your server, your PHP code can certainly do it. -- brion (talk) 16:30, 8 February 2013 (UTC)
Aha this is a very important point for people having more then one Wiki-installs and want to exchange files accross different domains. To choose the wrong tech here, could easily result in hours- may be days of useless efforts :-).
- Note that for your own wiki installs, you can customize $wgCrossSiteAJAXdomains to whitelist more sites. --brion (talk) 21:08, 8 February 2013 (UTC)
Okay this makes sense now. Yesterday I was wondering when I made a little external login page for my Wikis- thank you. For the Upload-API I would prefer the CURL-way like many others too. By the way in general what about this XML-chunks in the API-Documentation? How would they be used? Is it only an abstraction to reflect the different programming languages, or can we use them in PHP too?
- Example results we can get with good PHP-knowledge but less propper documentation level :-)
- One of the parameters filekey, file, url, statuskey is required
- post request failed The requested URL returned error: 41422
- request failed: URI too long (longer than 8190)
- The parameters url, filekey, statuskey can not be used together
- Invalid Content-Length
- No upload module set
...after many many hours of trial and errors...still can't get it working with PHP-CURL while successfully login, getting the right edit token etc..
PS: Some remarkable behaviors:
- The error "One of the parameters filekey, file, url, statuskey is required" is fired even we specify a file-parameter in the url may be because "file" is double checked against class WebRequestUpload which implies uploads can not simulated with CURL, the api needs server var "$_FILES['filename']" and therefor a real form upload which could lead to some serious confusions without mentioning it. ;-)
- If we put file contents into the url this mostly exceeds the allowed length of an url. I can't believe that this is meant to be the standard way. I think in "PHP-CURL" param file in the url-notation is more a string then real "File contents".
Update: After two days of trial and error, investigations, code reviewing etc. I got it working. I will need another day to clean up and fine tune...I guess this could be mutch easier with a better documentation level.
PS: Anyway...I would like to see the promised code samples (for example JQuery) and will happily assist- If someone has the same problems.
--Steviex2 (talk) 22:37, 8 February 2013 (UTC)
- I am having similar problems with PHP implementations, is it possible for you to share the code for this?
--Nischayn22 (talk) 08:11, 4 May 2013 (UTC) What about an example for calling the api internally(like edit)
$api = new ApiMain( new DerivativeRequest( $wgRequest, array( 'action' => 'upload', 'file' => 'blub', 'filename' => 'bla', 'url' => '', 'token' => $_POST["token"] ), false // was posted? ), true // enable write? ); $api->execute();
- Does this work? I did not get internal API to work for uploads. --Osnard (talk) 07:47, 19 December 2014 (UTC)
Seems like the url-parameter is needed otherwise i get "One of the parameters filekey, file, url, statuskey is required" message. What is needed for the url-parameter?
--Michael MPI (talk) 08:08, 13 March 2013 (UTC)
Javascript/jQuery
[edit]Working, rather minimal example using HTML5 APIs and jQuery
function handleFileSelect(evt) {
var file = evt.target.files[0]; // get (first) File
var fileName = evt.target.files[0].name;
doApiCall(file, fileName);
}
function doApiCall(fileToUpload,fileName){
formdata = new FormData(); //see https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects?redirectlocale=en-US&redirectslug=Web%2FAPI%2FFormData%2FUsing_FormData_Objects
formdata.append("action", "upload");
formdata.append("filename", fileName);
formdata.append("token", mw.user.tokens.get( 'editToken' ) );
formdata.append("file", fileToUpload);
//as we now have created the data to send, we send it...
$.ajax( { //http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery
url: mw.util.wikiScript( 'api' ), //url to api.php
contentType:false,
processData:false,
type:'POST',
data: formdata,//the formdata object we created above
success:function(data){
//do what you like, console logs are just for demonstration :-)
console.log("success!");
console.log(data);
},
error:function(xhr,status, error){
console.log(error)
}
});
}
document.getElementById('files').addEventListener('change', handleFileSelect, false); //is a <input type="file" id="files" name="files[]" multiple />
my thanks to the api mailinglist and Steviex2 --Simulo (talk) 15:03, 2 June 2013 (UTC)
Python with requests
[edit]The following should work with Python's requests
module:
# The following code is PD-self & CC-zero
import requests
api_url = 'https://project/w/api.php'
USER,PASS=u'BotUsername@Instancename',u'[[Special:BotPasswords]] password'
#Ensure bot instance is permissioned for createeditmovepage, uploadfile, uploadeditmovefile
FILENAME='/path/to/file'
REMOTENAME='remote_filename.ext'
USER_AGENT='Descriptive User Agent per [[:meta:User-Agent_policy]]'
# get login token and log in
payload = {'action': 'query', 'format': 'json', 'utf8': '',
'meta': 'tokens', 'type': 'login'}
r1 = requests.post(api_url, data=payload)
login_token=r1.json()['query']['tokens']['logintoken']
login_payload = {'action': 'login', 'format': 'json', 'utf8': '',
'lgname': USER, 'lgpassword': PASS, 'lgtoken': login_token}
r2 = requests.post(api_url, data=login_payload, cookies=r1.cookies)
cookies=r2.cookies.copy()
# We have now logged in and can request edit tokens thusly:
def get_edit_token(cookies):
edit_token_response=requests.post(api_url, data={'action': 'query',
'format': 'json',
'meta': 'tokens'}, cookies=cookies)
return edit_token_response.json()['query']['tokens']['csrftoken']
# Now actually perform the upload:
upload_payload={'action': 'upload',
'format':'json',
'filename':REMOTENAME,
'comment':'<MY UPLOAD COMMENT>',
'text':'Text on the File: page... description, license, etc.',
'token':get_edit_token(cookies)}
files={'file': (REMOTENAME, open(FILENAME,'rb'))}
headers={'User-Agent': USER_AGENT}
upload_response=requests.post(api_url, data=upload_payload,files=files,cookies=cookies,headers=headers)
Hopefully it can save others time and headaches. Storkk (talk) 13:58, 8 December 2016 (UTC)
Filetype mime mismatch
[edit]Hi, I'm trying to upload an image with a multipart/form-data request, however I keep getting told that the file type isn't the same, whereas I am sure that it is. This is what I am sending to api.php:
-----------------------------8d02f9ba3ddf82b Content-Disposition: form-data; name="action" upload -----------------------------8d02f9ba3ddf82b Content-Disposition: form-data; name="filename" 150px-6025526.png -----------------------------8d02f9ba3ddf82b Content-Disposition: form-data; name="token" XXXXXXXXXXXXXXXXXXXXXXXX+\ -----------------------------8d02f9ba3ddf82b Content-Disposition: form-data; name="format" json -----------------------------8d02f9ba3ddf82b Content-Disposition: form-data; name="file"; filename="150px-6025526.png" Content-Type: image/png <IMAGE DATA HERE> -----------------------------8d02f9ba3ddf82b--
I cannot find the reason why I am being told the file type doesn't match. Any help would be greatly appreciated. CASIO F-91W (talk) 22:50, 4 June 2013 (UTC)
Real world example with PHP
[edit]As It took some time for me to figure out how to upload file with API, and I'm not alone, I'm providing my example.
This is just example for one to get a clue, it does work, but is far from being tidy, secure, universal, best possible method, able to process warnings, etc..
function uploadFile($localfilename, $filename, $comment, $text, $token, $cookies) {
$handle = fopen($localfilename, "rb");
$file_body = fread($handle, filesize($localfilename));
fclose($handle);
$destination = "http://hy.wikisource.org/w/api.php";
$eol = "\r\n";
$data = '';
$header = '';
$mime_boundary=md5(time());
$params = array ('action'=>'upload',
'filename'=>$filename,
'text'=>$text,
'comment'=>$comment,
//'ignorewarnings'=>'yes', //if uncommented will ignore warnings and will overwrite existing files. Think twice.
'token'=>$token,
'format'=>'xml');
//parameters
foreach ($params as $key=>$value){
$data .= '--' . $mime_boundary . $eol;
$data .= 'Content-Disposition: form-data; name="' . $key . '"' . $eol;
$data .= 'Content-Type: text/plain; charset=UTF-8' . $eol;
$data .= 'Content-Transfer-Encoding: 8bit' . $eol . $eol;
$data .= $value . $eol;
}
//file
$data .= '--' . $mime_boundary . $eol;
$data .= 'Content-Disposition: form-data; name="file"; filename="'.$filename.'"' . $eol; //Filename here
$data .= 'Content-Type: application/octet-stream; charset=UTF-8' . $eol;
$data .= 'Content-Transfer-Encoding: binary' . $eol . $eol;
$data .= $file_body . $eol;
$data .= "--" . $mime_boundary . "--" . $eol . $eol; // finish with two eol's
//headers
$header .= 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)' . $eol;
$header .= 'Content-Type: multipart/form-data; boundary='.$mime_boundary . $eol;
$header .= 'Host: hy.wikisource.org'. $eol;
$header .= 'Cookie: '. $cookies . $eol;
$header .= 'Content-Length: ' . strlen($data) . $eol;
$header .= 'Connection: Keep-Alive';
$params = array('http' => array(
'method' => 'POST',
'header' => $header,
'content' => $data
));
$ctx = stream_context_create($params);
//var_dump($params);
$response = @file_get_contents($destination, FILE_TEXT, $ctx);
return $response;
}
You'll need to get edit token, and also provide cookies. Hope it will save an hour or two for some people. --Xelgen (talk) 02:33, 6 March 2014 (UTC)
Real world wiki functions in VBscript/Windows Shell
[edit]After many hours of working my way through this I thought it might be helpful to provide the functions I've created that allow uploading a file. Yes it's long and not pretty, but is functional and should help provide pointers in the right direction.
- Variable types are commented out as this was developed in MsAccess and then ported to Windows shell script (I was apparently bad in a past life).
- Code written to upload images but should work for anything - the file to be uploaded is usually referred to as strImageFileName
- File paths assumed to have a trailing slash (eg "C:\data\upload\")
- Functions wikiLogin() and getEditToken() included for completeness
Const MULTIPART_BOUNDARY = "---------------------------0123456789012"
'This string shouldn't occur in the file or data you are using
'Function uploadFileToWiki(strUser As String, strPassword As String, strPagename As String, strImageFileName As String, strError As String) As Boolean
Function uploadFileToWiki(strUser, strPassword, strPagename, strPath, strImageFileName, strError)
Dim xmlhttp 'As MSXML2.ServerXMLHTTP
Dim xDoc 'As MSXML2.DOMDocument
Dim strEditToken 'As String
Dim vPostData 'As Variant
Dim bResult 'As Boolean
Dim strDataPairs 'As String
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")
bResult = wikiLogin(xmlhttp, strUser, strPassword, strError)
If (bResult = False) Then
wscript.echo "Login failed: [" & strError & "]"
Exit Function
End If
bResult = getEditToken(xmlhttp, strPagename, strEditToken, strError)
strDataPairs = ""
strDataPairs = strDataPairs & "token=" & strEditToken & "|"
strDataPairs = strDataPairs & "ignorewarnings=1|"
strDataPairs = strDataPairs & "format=xml|"
strDataPairs = strDataPairs & "filename=" & strImageFileName
vPostData = generateImageUploadPostData(strDataPairs, strPath, strImageFileName)
'---- submit update --------------------------------
xmlhttp.Open "POST", WIKI_URL & "api.php?action=upload" & "&token=" & URLEncode(strEditToken)
'WIKI_URL is your equivalent of "https://en.wikipedia.org/w/"
'URLEncode() is a function to encode special characters - not hard to find one
xmlhttp.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
xmlhttp.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & MULTIPART_BOUNDARY
xmlhttp.setRequestHeader "Host", WIKI_HOST 'eg mywiki.hostname.com
xmlhttp.setRequestHeader "Content-Length", CStr(Len(vPostData))
xmlhttp.setRequestHeader "Connection", "Keep-Alive"
xmlhttp.send vPostData
'---- retrieve and print result --------------------------------
Set xDoc = CreateObject("MSXML2.DOMDocument")
xDoc.LoadXML (xmlhttp.responseText)
strError = Left(xmlhttp.responseText, 700)
'wscript.echo strError
If ("Success" = xDoc.SelectSingleNode("api").SelectSingleNode("upload").Attributes.getNamedItem("result").Text) Then
uploadFileToWiki = True
Else
uploadFileToWiki = False
End If
Set xmlhttp = Nothing
End Function
Private Function wikiLogin(ByRef xmlhttp, strUser, strPass, strError)
'Private Function wikiLogin(ByRef xmlhttp As MSXML2.ServerXMLHTTP, strUser As String, strPass As String, strError As String) As Boolean
Dim xDoc 'As MSXML2.DOMDocument
wikiLogin = False
Dim strResponse 'As String
Dim strPostData 'As String
Dim strLoginToken 'As String
strPostData = "format=xml&lgname=" & URLEncode(strUser) & "&lgpassword=" & URLEncode(strPass) & "&lgdomain=" & URLEncode("LDAP")
'---- login start --------------------------------
xmlhttp.Open "POST", WIKI_URL & "api.php?action=login", False
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send strPostData
Set xDoc = CreateObject("MSXML2.DOMDocument")
xDoc.loadXML (xmlhttp.responseText)
strLoginToken = "&lgtoken=" & URLEncode(xDoc.selectSingleNode("api").selectSingleNode("login").Attributes.getNamedItem("token").Text)
strPostData = strPostData & strLoginToken
'---- (re-)login with wiki provided token --------------------------------
xmlhttp.Open "POST", WIKI_URL & "api.php?action=login", False
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send strPostData
Set xDoc = CreateObject("MSXML2.DOMDocument")
xDoc.loadXML (xmlhttp.responseText)
strResponse = lcase(xDoc.selectSingleNode("api").selectSingleNode("login").Attributes.getNamedItem("result").Text)
'---- login complete --------------------------------
'wscript.echo xmlhttp.responseText
If (strResponse = "success") Then
wikiLogin = True
Else
wikiLogin = False
strError = strResponse
End If
End Function
Private Function getEditToken(ByRef xmlhttp, strPageTitle, ByRef strEditToken, strError)
'Private Function getEditToken(ByRef xmlhttp As MSXML2.ServerXMLHTTP, strPageTitle As String, ByRef strEditToken As String, strError As String) As Boolean
Dim xDoc 'As MSXML2.DOMDocument
'---- get edit token --------------------------------
xmlhttp.Open "GET", WIKI_URL & "api.php?action=query&format=xml&prop=info&intoken=edit&titles=" & URLEncode(strPageTitle), False
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send 'strPostData
Set xDoc = CreateObject("MSXML2.DOMDocument")
xDoc.loadXML (xmlhttp.responseText)
On Error Resume Next
strEditToken = ""
strEditToken = xDoc.selectSingleNode("api").selectSingleNode("query").selectSingleNode("pages").selectSingleNode("page").Attributes.getNamedItem("edittoken").Text
On Error GoTo 0
'wscript.echo Left(xmlhttp.responseText, 700)
If strEditToken = "" Then
getEditToken = False
Else
getEditToken = True
End If
End Function
'Private Function generateImageUploadPostData(strDataPairs As String, strPath As String, strFileName As String) As Variant
Private Function generateImageUploadPostData(strDataPairs, strPath, strFileName)
'more or less from http://code.huypv.net/2012/06/vbs-upload-file-http-post.html
Dim ado 'As ADODB.Stream
Dim rs 'As ADODB.Recordset
Dim lngCount
Dim bytFormData 'As Variant
Dim bytFormStart 'As Variant
Dim bytFormEnd 'As Variant
Dim bytFile 'As Variant
Dim strFormStart 'As Variant
Dim strFormEnd 'As Variant
Dim strDataPair 'As Variant
Const adLongVarBinary = 205
'Read the file into a byte array
Set ado = CreateObject("ADODB.Stream")
ado.Type = 1
ado.Open
ado.LoadFromFile strPath & strFileName
bytFile = ado.Read
ado.Close
'Create the multipart form data.
'Define the end of form
strFormEnd = vbCrLf & "--" & MULTIPART_BOUNDARY & "--" & vbCrLf
'First add any ordinary form data pairs
strFormStart = ""
For Each strDataPair In Split(strDataPairs, "|")
strFormStart = strFormStart & "--" & MULTIPART_BOUNDARY & vbCrLf
strFormStart = strFormStart & "Content-Disposition: form-data; "
strFormStart = strFormStart & "name=""" & Split(strDataPair, "=")(0) & """" & vbCrLf
strFormStart = strFormStart & "Content-Type: text/plain; charset=UTF-8" & vbCrLf
strFormStart = strFormStart & "Content-Transfer-Encoding: 8bit"
strFormStart = strFormStart & vbCrLf & vbCrLf
strFormStart = strFormStart & Split(strDataPair, "=")(1)
strFormStart = strFormStart & vbCrLf
Next
'Now add the header for the uploaded file
strFormStart = strFormStart & "--" & MULTIPART_BOUNDARY & vbCrLf
strFormStart = strFormStart & "Content-Disposition: form-data; "
strFormStart = strFormStart & "name=""" & "file" & """; "
strFormStart = strFormStart & "filename=""" & strFileName & """"
strFormStart = strFormStart & vbCrLf
strFormStart = strFormStart & "Content-Type: application/octet-stream" '; charset=UTF-8"
strFormStart = strFormStart & vbCrLf
strFormStart = strFormStart & "Content-Transfer-Encoding: binary"
strFormStart = strFormStart & vbCrLf & vbCrLf
'Create a recordset large enough to hold everything
Set rs = CreateObject("ADODB.Recordset")
rs.Fields.Append "FormData", adLongVarBinary, Len(strFormStart) + LenB(bytFile) + Len(strFormEnd)
rs.Open
rs.AddNew
'Convert form data so far to zero-terminated byte array
For lngCount = 1 To Len(strFormStart)
bytFormStart = bytFormStart & ChrB(Asc(Mid(strFormStart, lngCount, 1)))
Next
rs("FormData").AppendChunk bytFormStart & ChrB(0)
bytFormStart = rs("formData").GetChunk(Len(strFormStart))
rs("FormData") = ""
'Get the end boundary as a zero-terminated byte array
For lngCount = 1 To Len(strFormEnd)
bytFormEnd = bytFormEnd & ChrB(Asc(Mid(strFormEnd, lngCount, 1)))
Next
rs("FormData").AppendChunk bytFormEnd & ChrB(0)
bytFormEnd = rs("formData").GetChunk(Len(strFormEnd))
rs("FormData") = ""
'Now merge it all
rs("FormData").AppendChunk bytFormStart
rs("FormData").AppendChunk bytFile
rs("FormData").AppendChunk bytFormEnd
bytFormData = rs("FormData")
rs.Close
generateImageUploadPostData = bytFormData 'strFormStart
End Function
Hope it helps -- Qwaddles (talk) 23 April 2014
mw.Api
[edit]Is it at all possible to use mw.Api with this part of the API? It seems to only accepts an object, whereas this needs a FormData object. I'd rather not loose the benefits of mw.Api and use bare $.ajax. 124.180.3.50 07:51, 24 August 2014 (UTC)
Uploading Local Files with non-English characters in name
[edit]Uploading Local Files with non-English characters in name, with python 3.4.3 + requests 2.7 plugin.
MW version 1.23.1.
I get this error:
{'error': {'code': 'badupload_file', 'info': 'File upload param file is not a file upload; be sure to use multipart/form-data for your POST and include a filename in the Content-Disposition header.'}}
— Preceding unsigned comment added by Boxsnake (talk • contribs)
- We are now on MediaWiki version 1.35.0-wmf1 but here's the answer for python3: the requests module relies on urllib3 in order to handle the filename, and things go awry there. You can work around the issue by rfc2047-encoding the title and using that converted title as the value of the title (first field) in the tuple set as the value of 'file'. That is, you would do
{'file': (converted_title, open(path, 'rb'), 'multipart/form-data')}
. See the requests bug on github for more info and for sample code. -- ArielGlenn (talk) 19:48, 16 October 2019 (UTC)
Verify SSL
[edit]Is there a possibility to disable checking ssl certificates?
Mostly CURLOPT_SSL_VERIFYPEER => false
would solve this problem.
$user = $this->getUser(); doesn't get a user
[edit]Here's the first bit of my apiupload script. The only changed bit is the wfdebug line.
42: $user = $this->getUser();
43: wfDebug( "ApiUpload: ".$user->getId()." , I guess.");
It returns:
ApiUpload: 0 , I guess.
Any idea why it seems like there should be a use stuck in that object, because it's whats causing my image uploads to fail, but I don't know why there isn't one. BTW, yes, I'm logged in.
Minimal working JavaScript
[edit]Here is a really simple no-frills working example in JavaScript, without event handling etc. It assumes the following:
1) an HTML input element that is of type "file" and has ID = "localfile", name = "localfile"
2) a valid csrf token in variable "yourCsrfToken" (this is not something specific to file upload. Look elsewhere if you don't know about csrf tokens in Mediawiki)
3) the URL of your wiki's API in variable "yourMediaWikiApiUrl"
4) a file named "somefile.jpg" has not already been uploaded to the wiki.
var yourCsrfToken = <VALID_CSRF_TOKEN>; var yourMediaWikiApiUrl = <YOUR_API_URL>; var localfile = document.getElementById("localfile"); var file = localfile.files[0]; var fileName = "blueflower.jpg"; var comment = ` =={{int:filedesc}}== {{Information |description={{en|1=A blue flower}} |date={{subst:{{CURRENTYEAR}}-{{CURRENTMONTH}}-{{CURRENTDAY2}}}} |source={{own}} |author=~~~ |permission= |other versions= }} =={{int:license-header}}== {{self|cc-by-sa-4.0}} ` var request = new XMLHttpRequest(); request.open('POST', yourMediaWikiApiUrl, false); var formData = new FormData(); formData.append("action", "upload"); formData.append("filename", fileName); formData.append("comment", comment); formData.append("token", yourCsrfToken); formData.append("file", file); request.setRequestHeader("Content-Disposition", "form-data"); request.send(formData); console.log(request.response);
Assuming the user has selected a file through the input element named "localfile", this will upload that file to the wiki, giving it the name "somefile.jpg". You can check the response in your console. --Henryfunk (talk) 21:06, 13 May 2018 (UTC)
- Thanks Henryfunk. I encourage you to also add the page desciption.
comment
: Upload comment. Also used as the initial page text for new files if text is not specified.
- Yug (talk) 17:06, 21 September 2020 (UTC)
- I added it. Yug (talk) 17:16, 21 September 2020 (UTC)
uploading images stored as base64 data
[edit]I am trying to use the api to upload an image that has been extracted from an html document which is in base64 data format.
Could you tell me:
- is api upload able to upload images in this format?
- what parameters do I need to give the api call (preferably in javascript using ajax to make the api call)
Many thanks DuncanCrane (talk) 14:49, 12 June 2020 (UTC)
Structured data?
[edit]What should be the way to add structured data (eg when uploading images to Wikimedia Commons)? I'm not very familiar with it but it seems Wikimedia is moving that way and some of the data that's uploaded in the image page description (eg geocoordinates) could also be added as structured data at upload time given a field in this API call.
Structured data is not part of the page description nor the documented API call so I guess it can't currently be added as part of the upload call.
Usually a bot will pick it up but that doesn't seem to be the right way, nor is making a separate API call.
--Trougnouf (talk) 14:05, 18 March 2021 (UTC)
Is a BOT really necessary?
[edit]Hello to all. I am building a tool on Toolforge where users are supposed to be allowed to send their images of objects of a Museum collection. I was trying to implement this functionallity and wasn't successful. Reading the examples, it seems that I have to request a Bot? Until today, I only created tools using OAuth consumers; The users logged in, allowed the tool, and then every contribution used the API on Wikidata. Below is what I tried to implement. I'm using Python and Flask. Ederporto (talk) 00:21, 23 May 2021 (UTC)
- This page is not really watched (I followed this from phabricator). If you ask at Project:Support_desk, there's a better chance of you getting a response. Ammarpad (talk) 20:56, 25 May 2021 (UTC)
- Ammarpad I made a post there, as you suggested. Thank you! Good contributions, Ederporto (talk) 21:51, 25 May 2021 (UTC)
code
|
---|
client_key = app.config['CONSUMER_KEY']
client_secret = app.config['CONSUMER_SECRET']
session = OAuth1Session(client_key,
client_secret=client_secret,
resource_owner_key=session['owner_key'],
resource_owner_secret=session['owner_secret'])
url = "https://test.wikipedia.org/w/api.php"
crsf_token = get_token()
params = {
"action": "upload",
"filename": <filename>,
"format": "json",
"token": csrf_token,
"ignorewarnings": 1
}
file = {'file': (<filename>, open(<filepath>, 'rb'), 'multipart/form-data')}
response = session.post(url, files=file, data=params)
data = response.json()
return data
|
result
|
---|
{
"error":
{
"code":"permissiondenied",
"docref":"See https://commons.wikimedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes.",
"info":"The action you have requested is limited to users in one of the groups: *, [[Commons:Users|Users]]."
},
"servedby":"mw1278"
}
|
Doc: Upload warnings - duplicate
[edit]At "Upload warnings" it says:
"duplicate: The uploaded file exists under a different (or the same) name. ..."
The "(or the same)" part seems potentially incorrect. (depending on the used mw-verion I guess)
As:
While test uploading a duplicate file to its current location/img-page-name.
I did get the "exists"(+name) & "nochange"(+timestamp) warnings. (Doc say "no-change" btw)
But there was no "duplicate" warning. (which seems a bit overkill away considering exists+nochange comes down to the same thing.)
(MediaWiki: 1.36.1)
... Hmm: (message editing) Switching from Visual to Source like to eats <br> statements.
... Erm: And then suddenly I lost all linebreaks in my message. ??? ... Ok!. Only double hard-line breaks it is.
MvGulik (talk) 16:03, 8 October 2022 (UTC)
Upload duplicate
[edit]Hello,
I am trying hard to get this API work, but I have a really annoying problem.
I have some custom extension which requires new revision for files on some calls (rare, actually, but very important).
To avoid working with the DB directly, I decided to run via API call with this Upload API. My operation requires just create new revision for the existing file, so I send URL with one of the existing files from my wiki and try to re-upload it to beautifully create new revision. I use ignorewarnings=1. But all the time I get an error:
{"error":{"code":"fileexists-no-change","info":"The upload is an exact duplicate of the current version of...
Is there any chance to bypass this error, without hacking my wiki or writing custom complete upload API?
This is a very important! Please, help! Arsenii Gorkin (talk) 22:33, 1 November 2023 (UTC)