Source

woocode / sa-auto / sh / sendmail / sendmail.py

Full commit
# -*-coding:utf-8-*-

"""
    Desc: Send Mail to QQ mail box

    Author: kk
"""
# import email
import datetime
import re
import os
import time
import random
import sys

from urllib import urlencode
from random import choice

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage

from utils import smtplib, logger
from config import CONFIG

log = logger.get_logger('sendmail.log')

# TODO:
# 发送礼包ID
# subject urlencode
# 统计发送数量

COUNT = {}

def get_img(index):
    img_dct = {
        '1': '1',
        '2': '2',
        '3': '3',
        '4': 'tg',
        }
    if index in img_dct:
        return '20111222_%s.jpg' % str(img_dct[index])
    else:
        return '20111222_%s.jpg' % choice(['1', '2', '3', 'tg'])

def gen_date():
    return datetime.datetime.now().strftime('%Y-%m-%d')

def get_card_num(card_file):
    with open(card_file, 'r') as fb:
        for line in fb:
            line = line.strip()
            yield line

card_nums = get_card_num(os.path.join('card/card.txt'))

def countKeyword(key, subkey):
    '''统计key调用的次数 '''
    if key not in COUNT:
        COUNT[key] = {subkey: 1}
    else:
        if subkey not in COUNT[key]:
            COUNT[key][subkey] = 1
        else:
            COUNT[key][subkey] += 1

def randomSubject():
    '''随机组合邮件主题
    '''
    sub_name = random.choice(CONFIG['sub_names'])
    sub_title = random.choice(CONFIG['sub_titles'])

    subject = sub_name + sub_title

    countKeyword('sub_name', sub_name)
    countKeyword('sub_title', sub_title)
    countKeyword('subject', subject)

    return (sub_name, sub_title, subject)

def createMsg(tomsg):
    # Create the root message and fill in the from, to, and subject headers
    msgRoot = MIMEMultipart('related')
    msgRoot.add_header('From', CONFIG['from'])
    # msgRoot['From'] = CONFIG['from']
    msgRoot['To'] = tomsg[0]
    # msgRoot['Subject'] = CONFIG['Subject']
    # 获得随机组合的主题
    sub_name, sub_title, subject = randomSubject()
    msgRoot['Subject'] = subject
    # 随机组合邮件主题内容
    msgRoot.preamble = CONFIG['preamble']

    msgAlternative = MIMEMultipart('alternative')
    msgRoot.attach(msgAlternative)

    msgText = MIMEText('This is the alternative plain text message.')
    msgAlternative.attach(msgText)

    unquote_qq = lambda x: x.split('@')[0].strip()
    with open(CONFIG['tmpFile']) as fb:
        tplContent = fb.read()
    # 发送给统计后台的参数
    ex = {
          'pd': gen_date(),
          # 推广统计ID
          # 'p': 12,
          'p': 13,
          'ex': 'qq=' + unquote_qq(tomsg[0]) + '&sub_name=' + sub_name.encode('utf8') + '&sub_title=' + sub_title.encode('utf8') ,
    }

    ex_s = urlencode(ex)
    log.debug('ex: %s' % ex_s)
    tplContent = tplContent.replace('#ex#', ex_s)
    tplContent = tplContent.replace('#img#', get_img(CONFIG['target']))

    #
    # card = card_nums.next()
    # log.debug('generate card: %s' % card)
    # if not card:
    #     log.error('card number not enought')
    #     sys.exit(1)
    # log.info('card num: %s' % card)
    # tplContent = tplContent.replace('#card#', card.encode('utf8'))

    msgText = MIMEText(tplContent, 'html')
    msgAlternative.attach(msgText)

    pattern=re.compile(r"cid:(?P<file>[\w+]*[\W+][\w+]*)")
    groups = pattern.findall(tplContent)
    for picFile in groups:
        filename = os.path.join('static', picFile)
        with open(filename, 'rb') as fp:
            #part = email.MIMEBase.MIMEBase('application', 'octet-stream')
            #part.set_payload(fp.read())
            #email.Encoders.encode_base64(part)
            part = MIMEImage(fp.read())
            part.add_header('Content-ID', picFile)
            msgRoot.attach(part)

    return msgRoot

smtpList={}
def loginMail(strFrom, bindip):
    """ login the email
    """
    # if strFrom[2] in smtpList:
    #     smtp = smtpList[strFrom[2]]
    # else:
    smtp = smtplib.SMTP(host=strFrom[0],
                            port=strFrom[1],
                            local_hostname= CONFIG['local_hostname'],
                            bindip=bindip)
        #smtp.set_debuglevel(1)
    try:
        smtp.starttls()
    except:
        pass
    smtp.login(strFrom[2], strFrom[3])
    smtpList[strFrom[2]] = smtp
    return smtp
#end sendMail

def sendMail(strFrom, strTo, smtp):
    """ Send the email
    """
    msgRoot = createMsg(strTo)
    #strTo.append(CONFIG['flagMail'])
    log.info("Sending mail to:" + str(strTo))
    smtp.sendmail(strFrom[2], strTo, msgRoot.as_string())
    smtp.close()
#end sendMail


def getRobotList():
    robotList = []
    with open(CONFIG['robot']) as tmpFile:
        for line in tmpFile:
            line = line.strip().split(",")
            if line:
                robotList.append(line)
    return robotList
#end getRobotList


def getMailList():
    """Get QQ mail list
    """
    maillist = []
    SUFFIX = '@qq.com'
    with open(CONFIG['maillist']) as tmpFile:
        for line in tmpFile:
            qqNum = line.strip()
            if qqNum:
                if '@' in qqNum:
                    if '@.vip' in qqNum:
                        SUFFIX = '@vip.qq.com'
                    else:
                        SUFFIX = '@qq.com'
                    qq = qqNum.split('@')[0].strip()
                    qqNum = qq + SUFFIX
                else:
                    qqNum += SUFFIX
                #maillist.append(qqNum + '@qq.com')
                maillist.append(qqNum)
    return maillist
#end getMailList

def policyConfig(robotList, mailList):
    """ 根据邮件策略进行发送
    """
    serverlist = CONFIG['serverlist']
    complete = False

    while not complete:
        for bindip in serverlist:
            for robot in robotList:
                log.info('use robot %s' % str(robot))
                start = CONFIG['offset']
                log.info('counting  %s' % str(start))
                end = CONFIG['offset'] + CONFIG['mailListLength']
                if end > len(mailList):
                    #end = len(mailList)
                    complete = True
                    break;
                smtp = loginMail(robot, bindip)
                try:
                    sendMail(robot, mailList[start:end], smtp)
                except Exception,e:
                    log.error("Sending error: " + str(e))

                #     smtpList.pop(robot[2])
                #     smtp = loginMail(robot, bindip)
                #     sendMail(robot, mailList[start:end], smtp)

                CONFIG['offset'] += CONFIG['mailListLength']

                time.sleep(3)

def main():
    robotList = getRobotList()
    mailList = getMailList()

    policyConfig(robotList, mailList)
    print "End..."

if __name__ == "__main__":
    main()