386 msg = mail.parsebytes(data) |
386 msg = mail.parsebytes(data) |
387 except emailerrors.MessageParseError as inst: |
387 except emailerrors.MessageParseError as inst: |
388 raise error.Abort(inst) |
388 raise error.Abort(inst) |
389 |
389 |
390 # store sender and subject |
390 # store sender and subject |
391 sender = msg[r'From'] |
391 sender = msg['From'] |
392 subject = msg[r'Subject'] |
392 subject = msg['Subject'] |
393 if sender is not None: |
393 if sender is not None: |
394 sender = mail.headdecode(sender) |
394 sender = mail.headdecode(sender) |
395 if subject is not None: |
395 if subject is not None: |
396 subject = mail.headdecode(subject) |
396 subject = mail.headdecode(subject) |
397 del msg[r'From'], msg[r'Subject'] |
397 del msg['From'], msg['Subject'] |
398 |
398 |
399 if not msg.is_multipart(): |
399 if not msg.is_multipart(): |
400 # create fresh mime message from scratch |
400 # create fresh mime message from scratch |
401 # (multipart templates must take care of this themselves) |
401 # (multipart templates must take care of this themselves) |
402 headers = msg.items() |
402 headers = msg.items() |
405 msg = mail.mimeencode(self.ui, payload, self.charsets, self.test) |
405 msg = mail.mimeencode(self.ui, payload, self.charsets, self.test) |
406 # reinstate custom headers |
406 # reinstate custom headers |
407 for k, v in headers: |
407 for k, v in headers: |
408 msg[k] = v |
408 msg[k] = v |
409 |
409 |
410 msg[r'Date'] = encoding.strfromlocal( |
410 msg['Date'] = encoding.strfromlocal( |
411 dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2") |
411 dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2") |
412 ) |
412 ) |
413 |
413 |
414 # try to make subject line exist and be useful |
414 # try to make subject line exist and be useful |
415 if not subject: |
415 if not subject: |
419 s = ctx.description().lstrip().split(b'\n', 1)[0].rstrip() |
419 s = ctx.description().lstrip().split(b'\n', 1)[0].rstrip() |
420 subject = b'%s: %s' % (self.root, s) |
420 subject = b'%s: %s' % (self.root, s) |
421 maxsubject = int(self.ui.config(b'notify', b'maxsubject')) |
421 maxsubject = int(self.ui.config(b'notify', b'maxsubject')) |
422 if maxsubject: |
422 if maxsubject: |
423 subject = stringutil.ellipsis(subject, maxsubject) |
423 subject = stringutil.ellipsis(subject, maxsubject) |
424 msg[r'Subject'] = encoding.strfromlocal( |
424 msg['Subject'] = encoding.strfromlocal( |
425 mail.headencode(self.ui, subject, self.charsets, self.test) |
425 mail.headencode(self.ui, subject, self.charsets, self.test) |
426 ) |
426 ) |
427 |
427 |
428 # try to make message have proper sender |
428 # try to make message have proper sender |
429 if not sender: |
429 if not sender: |
430 sender = self.ui.config(b'email', b'from') or self.ui.username() |
430 sender = self.ui.config(b'email', b'from') or self.ui.username() |
431 if b'@' not in sender or b'@localhost' in sender: |
431 if b'@' not in sender or b'@localhost' in sender: |
432 sender = self.fixmail(sender) |
432 sender = self.fixmail(sender) |
433 msg[r'From'] = encoding.strfromlocal( |
433 msg['From'] = encoding.strfromlocal( |
434 mail.addressencode(self.ui, sender, self.charsets, self.test) |
434 mail.addressencode(self.ui, sender, self.charsets, self.test) |
435 ) |
435 ) |
436 |
436 |
437 msg[r'X-Hg-Notification'] = r'changeset %s' % ctx |
437 msg['X-Hg-Notification'] = 'changeset %s' % ctx |
438 if not msg[r'Message-Id']: |
438 if not msg['Message-Id']: |
439 msg[r'Message-Id'] = messageid(ctx, self.domain, self.messageidseed) |
439 msg['Message-Id'] = messageid(ctx, self.domain, self.messageidseed) |
440 msg[r'To'] = encoding.strfromlocal(b', '.join(sorted(subs))) |
440 msg['To'] = encoding.strfromlocal(b', '.join(sorted(subs))) |
441 |
441 |
442 msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string() |
442 msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string() |
443 if self.test: |
443 if self.test: |
444 self.ui.write(msgtext) |
444 self.ui.write(msgtext) |
445 if not msgtext.endswith(b'\n'): |
445 if not msgtext.endswith(b'\n'): |