SPAM Schleuder Version 2.0 :-)

Die vor fast 3 Jahren entwickelte Spam-Schleuder hat aus aktuellem Anlass (und natürlich aus Spass am Experimentieren) ein Facelift erhalten. Neue Features:

  • kann nun UTF-8 codierte Textdateien (incl. Umlauten/Sonderzeichen) korrekt senden
  • optional Begrenzung der Anzahl Mails pro Durchlauf (SPAM Vorsorge)
  • Commandline Parsing via getopt()
  • Gender Guess - Anrede kann auf Wunsch aufgrund des Vornamens ermittelt werden ('Liebe' oder 'Lieber')
  • Dateien können als Anhang mitgesendet werden
Installationshinweise: Die Datei bulkmail.py sollte am besten irgendwo in $PATH zu finden sein, z.B. in /usr/local/bin. Sie benötigt neben den python-Standard-Paketen nun zusätzlich gender-detector, das am einfachsten mit pip installiert werden kann: 'pip install gender-detector'. Falls pip nicht vorhanden ist, muss dieses natürlich vorher installiert werden. Alsdann: fröhliches SPAMMEN :-)

#!/usr/bin/python
# ....bulkmail.py: send bulk email to recipients in RecListFileName
# ....Werner Joss, 2017,2018
# ....License: GPL
# ....Message is from MsgFileName, preceeded by 'Hallo <Name>,\n'
# ....RecListFileName must contain one Recipient per line in the form 'Vorname Name <email>'
# ....Default Subject may be overridden in MsgFile (line starting with 'Subject:'
# ....this can send messages with utf-8 encoding, not just ascii (as bulkmail_asc.py) 30.04.17
# ....add max No of Msgs sent per run (SPAM Protection) 10.03.18
# ....guess gender :) - see https://pypi.python.org/pypi/gender-detector 10.03.18
# ....getopt Argument Parser 11.03.18
# ....add Attach File Option 11.03.18
# ....fix some bugs 18.03.18

import getopt, sys
import smtplib
import datetime
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
import codecs
from gender_detector import GenderDetector

def send_email(FROM, TO, SUBJECT, TEXT, att_file):

    date = datetime.datetime.now().strftime('%d %b %Y %H:%M')

    # Prepare actual message

    #msg = MIMEText(TEXT.encode('utf-8'), charset='utf-8')  # geht nicht !!
    msg = MIMEMultipart()
    msg['Subject'] = SUBJECT
    msg['From'] = FROM
    msg['To'] = TO[0]
    msg['Date'] = date

    text = MIMEText(TEXT.encode('utf-8'), 'plain', 'utf-8')
    msg.attach(text)

    # add attachment
    if len(att_file) > 0:
        anhang = MIMEApplication(open(att_file, "rb").read())
        anhang.add_header('Content-Disposition', 'attachment', filename=att_file)
        msg.attach(anhang)

    try:
        server = smtplib.SMTP(smtp_server, 25)  # be sure to use correct port (25 for std smtp)
        server.ehlo()
        server.starttls()
        server.login(user, pwd)
        server.sendmail(FROM, TO, msg.as_string('utf-8'))
        server.close()
    except:
        logtext = 'failed to send mail to %s' % TO
        print logtext
        if CreateLogFile:
            LogFile.write(logtext)

def usage(progname):
    print 'usage: %s [-l -s -n] -r <RecListFileName> -m <MsgFileName>' % progname
    print '(-l = create Logfile, -s = Simulate, -n = Nice)'
    sys.exit(2)

#  Config (global variables):
FROM = 'George Bush &lt;ghwbush@whitehouse.gov&gt;'
# your smtp server credentials:
smtp_server = "smtp.whitehouse.gov"
user = "ghwbush"
pwd = "obama"

# ....Defaults:

Simulate = False    # nomen est omen :)
Nice = False #  True: Anrede 'Liebe(r)' statt 'Hallo' :)
CreateLogFile = False
TO = [FROM]  # must be a list
SUBJECT = 'Test bulk email'
TEXT = 'Test sending bulk-mail using smtp server'
RecListFileName = 'Recipients.lst'
MaxMsgNum = 100 # max. no# of messages to be sent in one run (SPAM Protection!) 10.03.18

RecListFileName = ''
MsgFileName = ''
AttachFileName = ''
try:
    progname = sys.argv[0]
    argv = sys.argv[1:] # wichtig !
    opts, args = getopt.getopt(argv,"lsnhr:m:a:",["RecListFileName=","MsgFileName=","AttachFileName="])
    #print 'opts',opts
    #print 'argv',argv
except getopt.GetoptError as err:
    print str(err)
    usage(progname)
for opt, arg in opts:
    if opt == '-h':
        usage(progname)
    elif opt in ("-r", "--RecListFileName"):
        RecListFileName = arg
    elif opt in ("-m", "--MsgFileName"):
        MsgFileName = arg
    elif opt in ("-a", "--AttachFileName"):
        AttachFileName = arg
    elif opt == '-l':
        CreateLogFile = True
        #   print 'CreateLogFile'
    elif opt == '-n':
        Nice = True
        #   print 'Nice'
    elif opt == '-s':
        Simulate = True
        # print 'Simulate'
    else:
        print 'invalid option ', arg
        sys.exit(2)

#print 'Recipients file is ', RecListFileName
#print 'Message file is ', MsgFileName
#print 'Attach file is ', AttachFileName
#   sys.exit()
if (len(MsgFileName) < 1) and (len(RecListFileName) < 1):
    usage(progname)
if len(MsgFileName) < 1:
    print 'no msg file specified'
    usage(progname)
if len(RecListFileName) < 1:
    print 'no recipients file specified'
    usage(progname)

# read message (and subject) from MsgFile
detector = GenderDetector('us') # no 'de' available :-(

Msg = ''
try:
    MsgFile = codecs.open(MsgFileName, 'r', 'UTF-8')
    line = MsgFile.readline()  # read 1st line
    if CreateLogFile:
        LogFile = codecs.open(LogFileName, 'w', 'UTF-8')
    while line:
        sline = line.strip()
        if sline.startswith('Subject:'):
        # extract Subject
            SUBJECT = sline.replace('Subject:', '')
        else:
            Msg += line
        line = MsgFile.readline()

    LogMsg = 'Message:\n' + Msg + '\nhas been sent to:\n'
    if CreateLogFile:
        LogFile.write(LogMsg)
    MsgFile.close()
except:
    print 'could not read %s - exiting' % MsgFileName
    if CreateLogFile:
        LogFile.write('could not read %s - exiting' % MsgFileName)
    sys.exit()

# process RecListFile, send emails to each recipient

try:
    RecListFile = open(RecListFileName, 'r')
    line = RecListFile.readline();  # read 1st line
    print line
    lineNum = 1
    while line:
        line = line.strip()
        if len(line) > 0 and not line.startswith('#'):
            parts = line.split(' ')
            Vorname = parts[0]
            Name = parts[1]
            mailadr = parts[2]
            TO = []
            TO.append(Vorname + ' ' + Name + ' <' + mailadr + '>')
            gender = detector.guess(Vorname)
            Greet = 'Hallo' # default
            if (Nice):
                if (gender == 'male'):
                    Greet = 'Lieber'
                elif (gender == 'female'):
                    Greet = 'Liebe'
            TEXT = '%s %s,\n%s ' % (Greet, Vorname, Msg)
            print '%s %s\n' % (Greet, Vorname)
            if (not Simulate):
                send_email(FROM, TO, SUBJECT, TEXT, AttachFileName)
                print 'Message %d from %s has been sent to: %s' % (lineNum, MsgFileName, TO)
            else:
                print 'Message %d from %s would be sent to: %s' % (lineNum, MsgFileName, TO)
            lineNum += 1
            LogMsg += line + '\n'
            if CreateLogFile:
                LogFile.write(line + '\n')
            if (lineNum > MaxMsgNum):
                line = 'max No of Messages (%d) for run 1 reached, sending stopped!' % (MaxMsgNum)
                LogMsg += line + '\n'
                if CreateLogFile:
                    LogFile.write(line + '\n')
                break

        line = RecListFile.readline()
except:
    line = 'could not read %s - exiting' % RecListFileName
    print line
    if CreateLogFile:
        LogFile.write(line)
    sys.exit()
RecListFile.close()
if CreateLogFile:
    LogFile.close()

# Log Message as email to Sender
TO = [FROM]
if (not Simulate):
    send_email(FROM, TO, SUBJECT, LogMsg, AttachFileName)

Das Programm gibts als Download auch hier.