pythonpython-2.7variablesoffice365smp

Wrong variable data type?


I have class, which intended to grab user name and his email from Git commits:

class BitbucketData(object):

    def get_user_name(self):

        proc = subprocess.Popen("git --no-pager show -s --format='%an'", stdout=subprocess.PIPE)
        committer_name = proc.stdout.read()

        if committer_name:
            return committer_name

    def get_user_email(self):

        proc = subprocess.Popen("git --no-pager show -s --format='%aE'", stdout=subprocess.PIPE)
        committer_email = proc.stdout.read()

        if committer_email:
            return committer_email

It used then to send notifications for users (bottom is working version - without variables - all sender and receiver data set explicitly, not in variables - they commented here):

class Services(object):


    def sendmail(self, event):

        repo = BitbucketData()

        #to_address = repo.get_user_email()
        #to_address = 'user@domain.com'
        #to_name = repo.get_user_name()
        #to_name = 'Test user'

        subject = 'Bamboo build and deploy ready'
        sender = 'Bamboo agent <user@domain.com>'

        text_subtype = 'plain'
        message = """
        Hello, {}.

        Your build ready.
        Link to scenario: URL
        Link to build and deploy results: {})

        """.format('Test user', os.environ['bamboo_resultsUrl'])

        msg = MIMEText(message, text_subtype)
        msg['Subject'] = subject
        msg['From'] = sender
        msg['To'] = 'Test user <user@domain.com>'

        smtpconnect = smtplib.SMTP('outlook.office365.com', 587)
        smtpconnect.set_debuglevel(1)
        smtpconnect.starttls()
        smtpconnect.login('user@domain.com', 'password')
        smtpconnect.sendmail('user@domain.com', 'user@domain.com', msg.as_string())
        smtpconnect.quit()

        print('Mail sent')

        print(repo.get_user_email())

Problem is - if I'm using data from variables (e.g. to_address = 'user@domain.com' or using BitbucketData() class with to_address = repo.get_user_email() - I got an error from Office365 server:

...
reply: '250 2.1.0 Sender OK\r\n'
reply: retcode (250); Msg: 2.1.0 Sender OK
send: "rcpt TO:<'user@domain.com'>\r\n"
reply: '501 5.1.3 Invalid address\r\n'
reply: retcode (501); Msg: 5.1.3 Invalid address
...
  File "C:\Python27\lib\smtplib.py", line 742, in sendmail
    raise SMTPRecipientsRefused(senderrs)
smtplib.SMTPRecipientsRefused: {"'user@domain.com'\n": (501, '5.1.3 Invalid address')}

When using variables code looks like next:

class Services(object):


    def sendmail(self, event):

        repo = BitbucketData()

        to_address = repo.get_user_email()
        #to_address = 'user@domain.com'
        to_name = repo.get_user_name()
        #to_name = 'Test user'
        from_address = 'user@domain.com'

        subject = 'Bamboo build and deploy ready'
        sender = 'Bamboo agent <user@domain.com>'

        text_subtype = 'plain'
        message = """
        Hello, {}.

        Your build ready.
        Link to scenario: URL
        Link to build and deploy results: {})

        """.format(to_name, os.environ['bamboo_resultsUrl'])

        msg = MIMEText(message, text_subtype)
        msg['Subject'] = subject
        msg['From'] = sender
        msg['To'] = to_name

        smtpconnect = smtplib.SMTP('outlook.office365.com', 587)
        smtpconnect.set_debuglevel(1)
        smtpconnect.starttls()
        smtpconnect.login('user@domain.com', 'password')
        smtpconnect.sendmail(from_address, to_address, msg.as_string())
        smtpconnect.quit()

        print('Mail sent')

        print(repo.get_user_email())

What I'm (or Microsoft SMTP...) doing wrong here?

UPD

def sendmail(self, event):

    repo = BitbucketData()
    print(repr(repo.get_user_email()))
    ...

Gives me:

...
Creating new AutoEnv config
"'user@domain.com'\n"
send: 'ehlo pc-user.kyiv.domain.net\r\n'
...

Solution

  • Seems like you are receiving the following as output from your git commands -

    "'user@domain.com'\n"
    

    You are directly passing this to smtpconnect, which is causing the issue, as this is not a valid email address. You probably need to get the actual string from it. One way to get it is to use ast.literal_eval() function for that . Example -

    >>> import ast
    >>> e = ast.literal_eval("'user@domain.com'\n")
    >>> print(e)
    user@domain.com
    

    You would need to do this when returning the email from the get_user_email() function . Most probably committer_name also has this issue, so you may want to do this for that as well.


    From documentation of ast.literal_eval() -

    ast.literal_eval(node_or_string)

    Safely evaluate an expression node or a Unicode or Latin-1 encoded string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.