XZise has uploaded a new change for review. https://gerrit.wikimedia.org/r/174129
Change subject: [FIX] Upload: Convert unicode to ASCII ...................................................................... [FIX] Upload: Convert unicode to ASCII If using MIME the header must be ASCII, but when the file name is using non-ASCII letters those will be directly added and the server can't interpret them. The server returns with a rather confusing message: missingparam: One of the parameters filekey, file, url, statuskey is required This patch is encoding the parameters which aren't compatible with ASCII with the site's encoding and then using urllib(.parse).quote to convert them into ASCII strings. Change-Id: Ifb0eb96051c6f4f29676ef2d5a7d4658302ddf5c --- M pywikibot/data/api.py M tests/dry_api_tests.py 2 files changed, 20 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core refs/changes/29/174129/1 diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py index 8aa97b4..a5a52df 100644 --- a/pywikibot/data/api.py +++ b/pywikibot/data/api.py @@ -39,7 +39,7 @@ # unless the fix is not backported to py3.x versions that should # instead support PWB. basestring = (str, ) - from urllib.parse import urlencode, unquote + from urllib.parse import urlencode, quote, unquote unicode = str from io import BytesIO @@ -75,7 +75,7 @@ MIMEMultipart = CTEBinaryMIMEMultipart else: - from urllib import urlencode, unquote + from urllib import urlencode, quote, unquote from email.mime.multipart import MIMEMultipart _logger = "data.api" @@ -803,7 +803,8 @@ return message == ERR_MSG @staticmethod - def _generate_MIME_part(key, content, keytype=None, headers=None): + def _generate_MIME_part(encoding, key, content, keytype=None, + headers=None): if not keytype: try: content.encode("ascii") @@ -813,7 +814,15 @@ submsg = MIMENonMultipart(*keytype) content_headers = {'name': key} if headers: - content_headers.update(headers) + for header_key, header_value in headers.items(): + try: + header_value.encode('ascii') + except UnicodeError: + header_value = header_value.encode(encoding) + except AttributeError: + pass # header_value is already a bytes object + header_value = quote(header_value) + content_headers[header_key] = header_value submsg.add_header("Content-disposition", "form-data", **content_headers) @@ -824,7 +833,7 @@ return submsg @staticmethod - def _build_mime_request(params, mime_params): + def _build_mime_request(params, mime_params, encoding): """Construct a MIME multipart form post. @param params: HTTP request params @@ -837,10 +846,10 @@ # construct a MIME message containing all API key/values container = MIMEMultipart(_subtype='form-data') for key, value in params.items(): - submsg = Request._generate_MIME_part(key, value) + submsg = Request._generate_MIME_part(encoding, key, value) container.attach(submsg) for key, value in mime_params.items(): - submsg = Request._generate_MIME_part(key, *value) + submsg = Request._generate_MIME_part(encoding, key, *value) container.attach(submsg) # strip the headers to get the HTTP message body @@ -919,7 +928,8 @@ try: if self.mime: (headers, body) = Request._build_mime_request( - self._encoded_items(), self.mime_params) + self._encoded_items(), self.mime_params, + self.site.encoding()) use_get = False # MIME requests require HTTP POST else: headers = {'Content-Type': 'application/x-www-form-urlencoded'} diff --git a/tests/dry_api_tests.py b/tests/dry_api_tests.py index 3b3afe4..a63fd3f 100644 --- a/tests/dry_api_tests.py +++ b/tests/dry_api_tests.py @@ -192,7 +192,7 @@ with open(local_filename, 'rb') as f: file_content = f.read() submsg = Request._generate_MIME_part( - 'file', file_content, ('image', 'png'), + 'utf8', 'file', file_content, ('image', 'png'), {'filename': local_filename}) self.assertEqual(file_content, submsg.get_payload(decode=True)) @@ -203,7 +203,7 @@ body = Request._build_mime_request({}, { 'file': (file_content, ('image', 'png'), {'filename': local_filename}) - })[1] + }, 'utf8')[1] self.assertNotEqual(body.find(file_content), -1) -- To view, visit https://gerrit.wikimedia.org/r/174129 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ifb0eb96051c6f4f29676ef2d5a7d4658302ddf5c Gerrit-PatchSet: 1 Gerrit-Project: pywikibot/core Gerrit-Branch: master Gerrit-Owner: XZise <commodorefabia...@gmx.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits