Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
# 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)
Example #5
0
# 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,)
Example #6
0
    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