250 '''Returns (converted) string, charset tuple. |
250 '''Returns (converted) string, charset tuple. |
251 Finds out best charset by cycling through sendcharsets in descending |
251 Finds out best charset by cycling through sendcharsets in descending |
252 order. Tries both encoding and fallbackencoding for input. Only as |
252 order. Tries both encoding and fallbackencoding for input. Only as |
253 last resort send as is in fake ascii. |
253 last resort send as is in fake ascii. |
254 Caveat: Do not use for mail parts containing patches!''' |
254 Caveat: Do not use for mail parts containing patches!''' |
|
255 sendcharsets = charsets or _charsets(ui) |
|
256 if not isinstance(s, bytes): |
|
257 # We have unicode data, which we need to try and encode to |
|
258 # some reasonable-ish encoding. Try the encodings the user |
|
259 # wants, and fall back to garbage-in-ascii. |
|
260 for ocs in sendcharsets: |
|
261 try: |
|
262 return s.encode(pycompat.sysstr(ocs)), ocs |
|
263 except UnicodeEncodeError: |
|
264 pass |
|
265 except LookupError: |
|
266 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs) |
|
267 else: |
|
268 # Everything failed, ascii-armor what we've got and send it. |
|
269 return s.encode('ascii', 'backslashreplace') |
|
270 # We have a bytes of unknown encoding. We'll try and guess a valid |
|
271 # encoding, falling back to pretending we had ascii even though we |
|
272 # know that's wrong. |
255 try: |
273 try: |
256 s.decode('ascii') |
274 s.decode('ascii') |
257 except UnicodeDecodeError: |
275 except UnicodeDecodeError: |
258 sendcharsets = charsets or _charsets(ui) |
|
259 for ics in (encoding.encoding, encoding.fallbackencoding): |
276 for ics in (encoding.encoding, encoding.fallbackencoding): |
260 try: |
277 try: |
261 u = s.decode(ics) |
278 u = s.decode(ics) |
262 except UnicodeDecodeError: |
279 except UnicodeDecodeError: |
263 continue |
280 continue |
264 for ocs in sendcharsets: |
281 for ocs in sendcharsets: |
265 try: |
282 try: |
266 return u.encode(ocs), ocs |
283 return u.encode(pycompat.sysstr(ocs)), ocs |
267 except UnicodeEncodeError: |
284 except UnicodeEncodeError: |
268 pass |
285 pass |
269 except LookupError: |
286 except LookupError: |
270 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs) |
287 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs) |
271 # if ascii, or all conversion attempts fail, send (broken) ascii |
288 # if ascii, or all conversion attempts fail, send (broken) ascii |