Repository: python-telegram-bot/python-telegram-bot

Issue:
Could not send file with Chinese character
<!--
Thanks for reporting issues of python-telegram-bot!

Use this template to notify us if you found a bug, or if you want to request a new feature.
If you're looking for help with programming your bot using our library, feel free to ask your
questions in out telegram group at: https://t.me/pythontelegrambotgroup

To make it easier for us to help you please enter detailed information below.

Please note, we only support the latest version of python-telegram-bot and
master branch. Please make sure to upgrade & recreate the issue on the latest
version prior to opening an issue.
-->
### Steps to reproduce
1. generate a new text file and rename like **`测试.txt`**  and copy as **`111.txt`**

2. just send this two file
    `import telegram`
    `TGBot = telegram.Bot(TGBotToken)`
    `TGBot.sendDocument(test_chatid, document=open('测试.txt', 'rb'))`
    `TGBot.sendDocument(test_chatid, document=open('111.txt', 'rb'))`
   

### Expected behaviour
in the elder version (10.1.0) send file with Chinese charscter is success

### Actual behaviour
> /usr/local/lib/python3.5/dist-packages/telegram/bot.py in decorator(self, *args, **kwargs)
>      63     def decorator(self, *args, **kwargs):
>      64         logger.debug('Entering: %s', func.__name__)
> ---> 65         result = func(self, *args, **kwargs)
>      66         logger.debug(result)
>      67         logger.debug('Exiting: %s', func.__name__)
> 
> /usr/local/lib/python3.5/dist-packages/telegram/bot.py in decorator(self, *args, **kwargs)
>      88                 data['reply_markup'] = reply_markup
>      89
> ---> 90         result = self._request.post(url, data, timeout=kwargs.get('timeout'))
>      91
>      92         if result is True:
> 
> /usr/local/lib/python3.5/dist-packages/telegram/utils/request.py in post(self, url, data, timeout)
>     303         # Use multipart upload if we're uploading files, otherwise use JSON
>     304         if files:
> --> 305             result = self._request_wrapper('POST', url, fields=data, **urlopen_kwargs)
>     306         else:
>     307             result = self._request_wrapper('POST', url,
> 
> /usr/local/lib/python3.5/dist-packages/telegram/utils/request.py in _request_wrapper(self, *args, **kwargs)
>     221             raise Unauthorized(message)
>     222         elif resp.status == 400:
> --> 223             raise BadRequest(message)
>     224         elif resp.status == 404:
>     225             raise InvalidToken()
> 
> BadRequest: Wrong remote file id specified: wrong character in the string
> 
### Configuration
Ubuntu 16.04
Python 3.5.2
two version are both failed
python-telegram-bot==11.0.0
python-telegram-bot==11.1.0

### Logs
Insert logs here (if necessary)



Discussion:
I am facing the same problem.
Thanks for the report :D 
We will check it out and return shortly :)
This seems to be because telegram doesn't support [`RFC2231`](url) compliant Content-Disposition headers, and in V11 we switched our header generation over to urllib3 (which is what allowed us to support send_media_group and custom thumbnails). Urllib3 has a tracking issue for fixing this at https://github.com/urllib3/urllib3/issues/303.
In the meantime we are gonna patch our own vendored version (or maybe just fix it internally in our code using monkeypatching), and release a bugfix 11.1.1 shortly.
Thanks once again for reporting this issue :)

Resolving patch:
diff --git a/telegram/files/inputfile.py b/telegram/files/inputfile.py
--- a/telegram/files/inputfile.py
+++ b/telegram/files/inputfile.py
@@ -22,7 +22,6 @@
 import imghdr
 import mimetypes
 import os
-import sys
 from uuid import uuid4
 
 from telegram import TelegramError
@@ -74,10 +73,6 @@ def __init__(self, obj, filename=None, attach=None):
         if not self.filename or '.' not in self.filename:
             self.filename = self.mimetype.replace('/', '.')
 
-        if sys.version_info < (3,):
-            if isinstance(self.filename, unicode):  # flake8: noqa  pylint: disable=E0602
-                self.filename = self.filename.encode('utf-8', 'replace')
-
     @property
     def field_tuple(self):
         return self.filename, self.input_file_content, self.mimetype
diff --git a/telegram/utils/request.py b/telegram/utils/request.py
--- a/telegram/utils/request.py
+++ b/telegram/utils/request.py
@@ -36,6 +36,7 @@
     import telegram.vendor.ptb_urllib3.urllib3.contrib.appengine as appengine
     from telegram.vendor.ptb_urllib3.urllib3.connection import HTTPConnection
     from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout
+    from telegram.vendor.ptb_urllib3.urllib3.fields import RequestField
 except ImportError:  # pragma: no cover
     warnings.warn("python-telegram-bot wasn't properly installed. Please refer to README.rst on "
                   "how to properly install.")
@@ -45,6 +46,20 @@
 from telegram.error import (Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated,
                             RetryAfter, InvalidToken)
 
+
+def _render_part(self, name, value):
+    """
+    Monkey patch urllib3.urllib3.fields.RequestField to make it *not* support RFC2231 compliant
+    Content-Disposition headers since telegram servers don't understand it. Instead just escape
+    \ and " and replace any \n and \r with a space.
+    """
+    value = value.replace(u'\\', u'\\\\').replace(u'"', u'\\"')
+    value = value.replace(u'\r', u' ').replace(u'\n', u' ')
+    return u'%s="%s"' % (name, value)
+
+
+RequestField._render_part = _render_part
+
 logging.getLogger('urllib3').setLevel(logging.WARNING)
 
 USER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'
diff --git "a/tests/data/\346\265\213\350\257\225.png" "b/tests/data/\346\265\213\350\257\225.png"
new file mode 100644
Binary files /dev/null and "b/tests/data/\346\265\213\350\257\225.png" differ


Test patch:
diff --git a/tests/test_photo.py b/tests/test_photo.py
--- a/tests/test_photo.py
+++ b/tests/test_photo.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-#
+# -*- coding: utf-8 -*-
 # A library that provides a Python interface to the Telegram Bot API
 # Copyright (C) 2015-2018
 # Leandro Toledo de Souza <devs@python-telegram-bot.org>
@@ -195,6 +195,21 @@ def test_send_url_gif_file(self, bot, chat_id):
         assert isinstance(photo.file_id, str)
         assert photo.file_id != ''
 
+    @flaky(3, 1)
+    @pytest.mark.timeout(10)
+    def test_send_file_unicode_filename(self, bot, chat_id):
+        """
+        Regression test for https://github.com/python-telegram-bot/python-telegram-bot/issues/1202
+        """
+        with open(u'tests/data/测试.png', 'rb') as f:
+            message = bot.send_photo(photo=f, chat_id=chat_id)
+
+        photo = message.photo[-1]
+
+        assert isinstance(photo, PhotoSize)
+        assert isinstance(photo.file_id, str)
+        assert photo.file_id != ''
+
     @flaky(3, 1)
     @pytest.mark.timeout(10)
     def test_send_bytesio_jpg_file(self, bot, chat_id):