0

So in the event that you have several optional arguments in a class, how would you loop over the optional arguments to set their values after the base instantiation is done? Also looking for any recommendations of more pythonic ways to handle this code overall. Thanks!

required args:

p = argparse.ArgumentParser()
p.add_argument('-s',
               '--server',
               type=str,
               help='smtp server',
               required='True')
p.add_argument('-p',
               '--port',
               type=int,
               help='smtp server port',

... etc.

optional args:

p.add_argument('-P',
              '--replyto',
              type=str,
              help='reply to header. rtfrfc')
p.add_argument('-R',
              '--returnpath',
              type=str,
              help='reply to header. rtfrfc')
args = p.parse_args()

init of mysmtp:

class mysmtp:
   def __init__(self, server, port, rcptto, mailfrom, subject,
                displayname='', displayemail='', xsender='',
                replyto='', returnpath=''):
       self.server = server
       self.port = port
       self.rcptto = rcptto
       self.mailfrom = mailfrom
       self.subject = subject
       self.displayname = ''
       self.displayemail = ''
       self.replyto = ''
       self.xsender = ''
       self.filename = ''
       self.returnpath = ''

main function to instantiate mysmtp

def main():
   q = mysmtp(args.server,
              args.port,
              args.rcptto,
              args.mailfrom,
              args.subject)

optional arguments

   optargs = [args.displayname,
           args.displayemail,
           args.xsender,
           args.replyto,
           args.returnpath]

trying to simplifiy setting all of these params if they are present without having a million if's:

   for arg in optargs:
      print arg
      if arg:
         q.arg
      print q
   q.send_message()


main()

how would i expand the value of arg in the for loop and place it in q.{}?

when q.send_message runs it appears that all of the optional variables are not getting set by the loop in main(), so their value is blank as they are default set in __init__:

   def send_message(self):

       msg = MIMEMultipart('alternative')
       msg['From'] = self.mailfrom
       msg['To'] = self.rcptto
       msg['Subject'] = self.subject

       if self.displayname:
         d = "{} \"<{}>\"\r\n".format(self.displayname, self.displayemail)
       else:
         d = ''
       if self.xsender:
         x = "X-Sender: {} \"<{}>\"\r\n".format(self.displayname, self.displayemail)
       else:
         x = ''
       if self.replyto:
         rto = "Reply-To: {} \"{}\"\r\n".format(self.displayname, self.replyto)
       else:
         rto = ''
       if self.returnpath:
         rpat = "Return-Path: {} \"{}\"\r\n".format(self.displayname, self.returnpath)
       else:
         rpat = ''

full source code below.

import smtplib
import socket
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import argparse

p = argparse.ArgumentParser()
p.add_argument('-s',
               '--server',
               type=str,
               help='smtp server',
               required='True')
p.add_argument('-p',
               '--port',
               type=int,
               help='smtp server port',
               required='True')
p.add_argument('-r',
               '--rcptto',
               type=str,
               help='to address',
               required='True')
p.add_argument('-m',
              '--mailfrom',
              type=str,
              help='MAIL FROM email headers. ' +
              'please note this email may need to be set ' +
              'as a valid domain you are sending from to ' +
              'bypass spf checks',
              required='True')
p.add_argument('-d',
              '--displayname',
              type=str,
              help='display name to fool mail clients. ' +
              'useful if you cant spoof your MAILFROM',
              required='True')
p.add_argument('-l',
              '--displayemail',
              type=str,
              help='display from email to fool mail clients. ' +
              'useful if you cant spoof your MAILFROM'
              )
p.add_argument('-x',
              '--xsender',
              type=str,
              help='rtfm or rtfrfc' +
              'useful if you cant spoof your MAILFROM',
              )
p.add_argument('-j',
              '--subject',
              type=str,
              help='email subject',
              required='True')
p.add_argument('-f',
              '--filename',
              type=str,
              help='file attachment')
p.add_argument('-P',
              '--replyto',
              type=str,
              help='reply to header. rtfrfc')
p.add_argument('-R',
              '--returnpath',
              type=str,
              help='reply to header. rtfrfc')
args = p.parse_args()

class mysmtp:
   def __init__(self, server, port, rcptto, mailfrom, subject,
                displayname='', displayemail='', xsender='',
                replyto='', returnpath=''):
       self.server = server
       self.port = port
       self.rcptto = rcptto
       self.mailfrom = mailfrom
       self.subject = subject
       self.displayname = ''
       self.displayemail = ''
       self.replyto = ''
       self.xsender = ''
       self.filename = ''
       self.returnpath = ''

   def send_message(self):

       msg = MIMEMultipart('alternative')
       msg['From'] = self.mailfrom
       msg['To'] = self.rcptto
       msg['Subject'] = self.subject

       if self.displayname:
         d = "{} \"<{}>\"\r\n".format(self.displayname, self.displayemail)
       else:
         d = ''
       if self.xsender:
         x = "X-Sender: {} \"<{}>\"\r\n".format(self.displayname, self.displayemail)
       else:
         x = ''
       if self.replyto:
         rto = "Reply-To: {} \"{}\"\r\n".format(self.displayname, self.replyto)
       else:
         rto = ''
       if self.returnpath:
         rpat = "Return-Path: {} \"{}\"\r\n".format(self.displayname, self.returnpath)
       else:
         rpat = ''
       print rto
       body = "{}{}{}{}sent w/ smtplib and email.mime py libs".format(d,x,rto,rpat)
       print body
       content = MIMEText(body, 'plain')
       msg.attach(content)
       if self.filename:
           f = file(self.filename)
           attachment = MIMEText(f.read())
           attachment.add_header('Content-Disposition',
                                 'attachment',
                                 filename=self.filename)
           msg.attach(attachment)
           print f
       try:
           print '[+] attempting to send message'
           s = smtplib.SMTP(self.server, self.port)
           s.sendmail(self.mailfrom, self.rcptto, msg.as_string())
           print '[$] successfully sent through {}:{}'.format(self.server,
                                                              self.port)
       except socket.error as e:
           print '[!] could not connect'


#   def __init__(self, server, port, rcptto, mailfrom, subject,
 #                  displayname='', displayemail='', xsender='',
 #                                  replyto='', returnpath=''):


def main():
   q = mysmtp(args.server,
              args.port,
              args.rcptto,
              args.mailfrom,
              args.subject)

   optargs = [args.displayname,
           args.displayemail,
           args.xsender,
           args.replyto,
           args.returnpath]

   for arg in optargs:
      print arg
      if arg:
         q.arg = arg
      print q
   q.send_message()


main()
2
  • Other than using default arguments? Commented Jul 20, 2016 at 2:34
  • yes i'm trying to set the params if they exist, if not leave them to their default empty value in __init__ Commented Jul 20, 2016 at 2:37

1 Answer 1

2

This is what you might be looking for. You can use *args when you're not sure in the problem how many arguments might pass to your function. It allows you pass an arbitrary number of arguments to your function

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.