def _create_from_to_cc(cls, idx, session, trees): config = session.config ahp = AddressHeaderParser() ref_from, ref_to, ref_cc = [], [], [] result = {'from': '', 'to': [], 'cc': []} def merge_contact(ai): vcard = config.vcards.get_vcard(ai.address) if vcard: ai.merge_vcard(vcard) return ai # Parse the headers, so we know what we're working with. We prune # some of the duplicates at this stage. for addrs in [t['addresses'] for t in trees]: alist = [] for dst, addresses in ((ref_from, addrs.get('reply-to') or addrs.get('from', [])), (ref_to, addrs.get('to', [])), (ref_cc, addrs.get('cc', []))): alist += [d.address for d in dst] dst.extend([a for a in addresses if a.address not in alist]) # 1st, choose a from address. from_ai = config.vcards.choose_from_address( config, ref_from, ref_to, ref_cc) # Note: order matters! if from_ai: result['from'] = ahp.normalized(addresses=[from_ai], force_name=True) def addresses(addrs, exclude=[]): alist = [from_ai.address] if (from_ai) else [] alist += [a.address for a in exclude] return [ merge_contact(a) for a in addrs if a.address not in alist and not a.address.startswith( 'noreply@') and '@noreply' not in a.address ] # If only replying to messages sent from chosen from, then this is # a follow-up or clarification, so just use the same headers. if (from_ai and len([ e for e in ref_from if e and e.address == from_ai.address ]) == len(ref_from)): if ref_to: result['to'] = addresses(ref_to) if ref_cc: result['cc'] = addresses(ref_cc) # Else, if replying to other people: # - Construct To from the From lines, excluding own from # - Construct Cc from the To and CC lines, except new To/From else: result['to'] = addresses(ref_from) result['cc'] = addresses(ref_to + ref_cc, exclude=ref_from) return result
def _create_from_to_cc(cls, idx, session, trees): config = session.config ahp = AddressHeaderParser() ref_from, ref_to, ref_cc = [], [], [] result = {'from': '', 'to': [], 'cc': []} def merge_contact(ai): vcard = config.vcards.get_vcard(ai.address) if vcard: ai.merge_vcard(vcard) return ai # Parse the headers, so we know what we're working with. We prune # some of the duplicates at this stage. for addrs in [t['addresses'] for t in trees]: alist = [] for dst, addresses in ( (ref_from, addrs.get('reply-to') or addrs.get('from', [])), (ref_to, addrs.get('to', [])), (ref_cc, addrs.get('cc', []))): alist += [d.address for d in dst] dst.extend([a for a in addresses if a.address not in alist]) # 1st, choose a from address. from_ai = config.vcards.choose_from_address( config, ref_from, ref_to, ref_cc) # Note: order matters! if from_ai: result['from'] = ahp.normalized(addresses=[from_ai], force_name=True) def addresses(addrs, exclude=[]): alist = [from_ai.address] if (from_ai) else [] alist += [a.address for a in exclude] return [merge_contact(a) for a in addrs if a.address not in alist and not a.address.startswith('noreply@') and '@noreply' not in a.address] # If only replying to messages sent from chosen from, then this is # a follow-up or clarification, so just use the same headers. if (from_ai and len([e for e in ref_from if e and e.address == from_ai.address]) == len(ref_from)): if ref_to: result['to'] = addresses(ref_to) if ref_cc: result['cc'] = addresses(ref_cc) # Else, if replying to other people: # - Construct To from the From lines, excluding own from # - Construct Cc from the To and CC lines, except new To/From else: result['to'] = addresses(ref_from) result['cc'] = addresses(ref_to + ref_cc, exclude=ref_from) return result
def _create_from_to_cc(cls, idx, session, trees): config = session.config ahp = AddressHeaderParser() ref_from, ref_to, ref_cc = [], [], [] result = {'from': '', 'to': [], 'cc': []} def merge_contact(ai): vcard = session.config.vcards.get_vcard(ai.address) if vcard: ai.merge_vcard(vcard) return ai # Parse the headers, so we know what we're working with. We prune # some of the duplicates at this stage. for addrs in [t['addresses'] for t in trees]: alist = [] for dst, addresses in ( (ref_from, addrs.get('reply-to') or addrs.get('from', [])), (ref_to, addrs.get('to', [])), (ref_cc, addrs.get('cc', []))): alist += [d.address for d in dst] dst.extend([a for a in addresses if a.address not in alist]) # 1st, choose a from address. We'll use the system default if # nothing is found, but hopefully we'll find an address we # recognize in one of the headers. from_address = (session.config.prefs.default_email or session.config.profiles[0].email) profile_emails = [p.email for p in session.config.profiles if p.email] for src in (ref_from, ref_to, ref_cc): matches = [s for s in src if s.address in profile_emails] if matches: from_address = matches[0].address break result['from'] = ahp.normalized(addresses=[AddressInfo(p.email, p.name) for p in session.config.profiles if p.email == from_address], force_name=True) def addresses(addrs, exclude=[]): alist = [from_address] + [a.address for a in exclude] return ahp.normalized_addresses(addresses=[merge_contact(a) for a in addrs if a.address not in alist and not a.address.startswith('noreply@') and '@noreply' not in a.address], with_keys=True, force_name=True) # If only replying to messages sent from chosen from, then this is # a follow-up or clarification, so just use the same headers. if len([e for e in ref_from if e.address == from_address] ) == len(ref_from): if ref_to: result['to'] = addresses(ref_to) if ref_cc: result['cc'] = addresses(ref_cc) # Else, if replying to other people: # - Construct To from the From lines, excluding own from # - Construct Cc from the To and CC lines, except new To/From else: result['to'] = addresses(ref_from) result['cc'] = addresses(ref_to + ref_cc, exclude=ref_from) return result
# wild. The wild can be pretty wild. # # This parser is NOT fully RFC2822 compliant - in particular it will get # confused by nested comments (see FIXME in tests below). # import sys import traceback from mailpile.mailutils import AddressHeaderParser as AHP ahp_tests = AHP(AHP.TEST_HEADER_DATA) print '_tokens: {0!s}'.format(ahp_tests._tokens) print '_groups: {0!s}'.format(ahp_tests._groups) print '{0!s}'.format(ahp_tests) print 'normalized: {0!s}'.format(ahp_tests.normalized()) headers, header, inheader = {}, None, False for line in sys.stdin: if inheader: if line in ('\n', '\r\n'): for hdr in ('from', 'to', 'cc'): val = headers.get(hdr, '').replace('\n', ' ').strip() if val: try: nv = AHP(val, _raise=True).normalized() if '\\' in nv: print 'ESCAPED: {0!s}: {1!s} (was {2!s})'.format(hdr, nv, val) else: print '{0!s}'.format(nv)
# wild. The wild can be pretty wild. # # This parser is NOT fully RFC2822 compliant - in particular it will get # confused by nested comments (see FIXME in tests below). # import sys import traceback from mailpile.mailutils import AddressHeaderParser as AHP ahp_tests = AHP(AHP.TEST_HEADER_DATA) print '_tokens: %s' % ahp_tests._tokens print '_groups: %s' % ahp_tests._groups print '%s' % ahp_tests print 'normalized: %s' % ahp_tests.normalized() headers, header, inheader = {}, None, False for line in sys.stdin: if inheader: if line in ('\n', '\r\n'): for hdr in ('from', 'to', 'cc'): val = headers.get(hdr, '').replace('\n', ' ').strip() if val: try: nv = AHP(val, _raise=True).normalized() if '\\' in nv: print 'ESCAPED: %s: %s (was %s)' % (hdr, nv, val) else: print '%s' % (nv,)
def _create_from_to_cc(cls, idx, session, trees): config = session.config ahp = AddressHeaderParser() ref_from, ref_to, ref_cc = [], [], [] result = {'from': '', 'to': [], 'cc': []} def merge_contact(ai): vcard = session.config.vcards.get_vcard(ai.address) if vcard: ai.merge_vcard(vcard) return ai # Parse the headers, so we know what we're working with. We prune # some of the duplicates at this stage. for addrs in [t['addresses'] for t in trees]: alist = [] for dst, addresses in ((ref_from, addrs.get('reply-to') or addrs.get('from', [])), (ref_to, addrs.get('to', [])), (ref_cc, addrs.get('cc', []))): alist += [d.address for d in dst] dst.extend([a for a in addresses if a.address not in alist]) # 1st, choose a from address. We'll use the system default if # nothing is found, but hopefully we'll find an address we # recognize in one of the headers. from_address = (session.config.prefs.default_email or session.config.profiles[0].email) profile_emails = [p.email for p in session.config.profiles if p.email] for src in (ref_from, ref_to, ref_cc): matches = [s for s in src if s.address in profile_emails] if matches: from_address = matches[0].address break result['from'] = ahp.normalized(addresses=[ AddressInfo(p.email, p.name) for p in session.config.profiles if p.email == from_address ], force_name=True) def addresses(addrs, exclude=[]): alist = [from_address] + [a.address for a in exclude] return ahp.normalized_addresses(addresses=[ merge_contact(a) for a in addrs if a.address not in alist and not a.address.startswith( 'noreply@') and '@noreply' not in a.address ], with_keys=True, force_name=True) # If only replying to messages sent from chosen from, then this is # a follow-up or clarification, so just use the same headers. if len([e for e in ref_from if e.address == from_address]) == len(ref_from): if ref_to: result['to'] = addresses(ref_to) if ref_cc: result['cc'] = addresses(ref_cc) # Else, if replying to other people: # - Construct To from the From lines, excluding own from # - Construct Cc from the To and CC lines, except new To/From else: result['to'] = addresses(ref_from) result['cc'] = addresses(ref_to + ref_cc, exclude=ref_from) return result