views:

428

answers:

2

I have the following code:

    TYPES = {'hotmail':{'type':'hotmail', 'lookup':'mixed', 'dkim': 'no', 'signatures':['|S|Return-Path: [email protected]','|R|^Return-Path:\s*[^@]+@(?:hot|msn)','^Received: from .*hotmail.com$']},
             'gmail':{'type':'gmail', 'lookup':'mixed', 'dkim': 'yes', 'signatures':['|S|Subject: unsubscribe','','','']}
            }

    for type_key, type in TYPES.iteritems():
        for sub_type_key, sub_type in type.iteritems():
            for sig in sub_type['signatures']:
                if ("|S|" in sig):
                    #String based matching
                    clean_sig = sig[3:len(sig)]
                    if (clean_sig in file_contents):
                        sig_match += 1
                elif ("|R|" in sig):
                    clean_sig = sig[3:len(sig)]
                    #REGMATCH later
            if (sig_match == sig.count):
                return sub_type['type']

     return None

However, it generates the error:

for sig in sub_type['signatures']:
TypeError: string indices must be integers, not str

I assume that it would see the list being pulled from dictionary element, and allow me to loop over that?

Python newbie is a newbie :(

+6  A: 
for type_key, type in TYPES.iteritems():
    for sub_type_key, sub_type in type.iteritems():
        for sig in sub_type['signatures']:

should be:

for type_key, type in TYPES.iteritems():
        for sig in type['signatures']:

But 'type' is a poor name choice in this case... you don't want to shadow a builtin.

Essentially, 'type_key' has the name (either 'hotmail' or 'gmail'), and 'type' has the dictionary that is the value associated with that key. So type['signatures'] is what you're wanting.

Also, you may not need to have 'gmail' inside the nested dictionary; just return 'type_key' instead of type['type'].

Bringing it all together, maybe this will work better: (Warning: untested)

providers = {
    'hotmail':{
        'type':'hotmail',
        'lookup':'mixed',
        'dkim': 'no',
        'signatures':[
            '|S|Return-Path: [email protected]',
            '|R|^Return-Path:\s*[^@]+@(?:hot|msn)',
            '^Received: from .*hotmail.com$']
    },
    'gmail':{
        'type':'gmail',
        'lookup':'mixed',
        'dkim': 'yes',
        'signatures':['|S|Subject: unsubscribe','','','']
    }
}

for provider, provider_info in providers.iteritems():
    for sig in provicer_info['signatures']:
        if ("|S|" in sig):
            #String based matching
            clean_sig = sig[3:len(sig)]
            if (clean_sig in file_contents):
                sig_match += 1
        elif ("|R|" in sig):
            clean_sig = sig[3:len(sig)]
            #REGMATCH later
    if (sig_match == sig.count):
        return provider

 return None
retracile
Yep, works of course. I am face-palming myself now. Thank you!
Terry Felkrow
+3  A: 
Roger Pate
+1 Yes, the formatting matters.
retracile
I had no idea! Very useful, everything reformatted! Thanks again!
Terry Felkrow