Python - creating same sender email/sender in Random email/conversation generator - python

I'm super new to Python and just trying my hand at a random email generator.
I'm just using json files with datasets in them, so there may be a better way to do this.
I can get the script to work no problems, but I need some advice on something. I want the senders email to be the same as the sign off name.
I.E. david_jones#hotmail etc comes from Regards, David Jones. At the moment i've got it generating a separate random email, and separate sign off name. I need to link the two. Everything else is ok at the moment.
Can anyone help me with a better way to do this?
Code:
import json
import random
f = open("C:/Users/*/Desktop/Email.txt", "a")
sentfrom = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Send.json').read())
send = sentfrom [random.randint(0,4)]
carboncopy = "CC:"
receiver = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/To.json').read())
to = receiver[random.randint(0,4)]
datesent = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Date.json').read())
date = datesent[random.randint(0,4)]
subjects = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Subject.json').read())
subject = subjects[random.randint(0,4)]
greetings = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Greeting.json').read())
greeting= greetings[random.randint(0,4)]
firstsentence = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Sent1.json').read())
sent1 = firstsentence[random.randint(0,4)]
secondsentence = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Sent2.json').read())
sent2 = secondsentence[random.randint(0,4)]
thirdsentence = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Sent3.json').read())
sent3 = thirdsentence[random.randint(0,4)]
fourthsentence = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Sent4.json').read())
sent4 = fourthsentence[random.randint(0,4)]
farewell = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Goodbye.json').read())
goodbye = farewell[random.randint(0,4)]
regards = json.loads(open('C:/Users/*/Desktop/*/Scripts/Test/Sender.json').read())
salutation = regards[random.randint(0,4)]
conversation = send +'\n'+ to +'\n'+ carboncopy +'\n'+ date +'\n'+ subject +'\n'+ '\n' + greeting +', \n'+ '\n' + sent1 +'\n'+ '\n' + sent2 +'\n'+'\n'+ sent3 +'\n'+'\n'+ sent4 +'\n'+'\n'+ goodbye +'\n'+'\n'+ salutation
f.write(conversation)
f.close()
Thanks in advance,
Buzz

Assuming that regards is what contains the sign off name..
You want to first get rid of the sign off name, instead of 'Regards, John Doe', Have all of them be 'Regards', 'Best', 'Thanks!' etc. maybe just create a list instead of reading it from json:
regards = ['Regards,', 'Best,', 'Thanks!' ...]
Assuming everyone's format in email is the same, i.e. john_doe#whatever.com, you can get the name from this:
my_name = to.split('#')[0].replace('_', ' ').title()
# my_name will be 'John Doe'
And then add my_name to the conversation after salutation.

Related

Make name variable print the corrent name with an automated email

I've been trying to make a python script to send a happy birthday email on a given date, that notifies me who it sent an email to via text message.
I have 3 files.
First I have a brithdays.csv file which I enter all the birthday data that is going to use.
Here's an example of what's inside the file:
name,email,year,month,day
Ivy,Testemail#mail.com,1,3,25
Rose,Testemail#mail.com,1,3,28
Kimberly,Testemail#mail.com,1,4,10
Then I have a letter template which the script reads and replaces [NAME] with the name in the CSV file :
Greetings,
Im wishing [NAME] a very happy birthday! [NAME], &#128522 I hope you enjoy your day and wishing you more life.
Thank you,
And then I have my actual code
############## IMPORTS ##############
import smtplib
import datetime as dtime
import pandas as pd
import random
from time import strftime
from email.mime.text import MIMEText
############## Reading Data and Check Current Day & Month ##############
# READ CSV BIRTHDAY FILE
df = pd.read_csv("birthdays.csv")
# PRINT CURRENT DAY
current_day = dtime.datetime.now().day
current_month = dtime.datetime.now().month
##################ENTER LOGIN HERE#############################
LOGIN = "EMAIL"
PASS = "PASSWORD"
############## LOGIC ##############
# save the rows that has the current day in new variable
new_df = df.loc[df['day'] == current_day]
# check the length of new_df of the current month so if the result is larger than 1
# so there is birthdays on this day
if len(new_df.loc[new_df['month'] == current_month]) > 0:
# check the length of people having birthday in this day
for i in range(len(new_df.loc[new_df['month'] == current_month])):
# OPEN BIRTHDAY TEMPLATE
with open(f"./letter_1.txt") as letter_file:
# READING FILE
letter_contents = letter_file.read()
#CREATE NAME VARIABLE
name = df["name"][i]
# replace [NAME] with actual name on the data
if len(new_df["name"]) > 1:
the_letter = letter_contents.replace("[NAME]", new_df["name"][i])
the_email = new_df["email"][i]
else:
the_letter = letter_contents.replace("[NAME]", new_df["name"].item())
the_email = new_df["email"].item()
# SMTPLIB LOGIN TO SEND EMAIL
# CONNECTION
with smtplib.SMTP("smtp.outlook.com") as con:
# START
con.starttls()
# LOGIN
con.login(user=LOGIN, password=PASS)
# create the msg
msg = MIMEText(the_letter, 'html')
msg["From"] = LOGIN
msg["To"] = the_email
msg["Subject"] = "Happy Birthday " + name + "!!!"
msg["Cc"] = "CC EMAILS"
# SEND EMAIL
con.send_message(msg)
#SENDS TEXT MESSAGE CONFIRMATION
msg = MIMEText ("Sent Happy Birthday Email to " + name + " on " + str(text.strftime('%Y-%m-%d %H:%M:%S %p')))
msg["From"] = LOGIN
msg["To"] = "VERIZONPHONENUMBER#vtext.com"
# SEND TEXT
con.send_message(msg)
# LOGS OUT OF EMAIL
con.quit()
I think the issue lies in Line 45 where I create the name variable.
My issue is that every time it sends an email, the name in the Subject of the email and in the text message I receive it's the first name of the list.
For example if I run the script, the email would look something like this
Happy Birthday Ivy!!!
Greetings,
Im wishing Rose a very happy birthday! Rose, &#128522 I hope you enjoy your day and wishing you more life.
I'm trying to make the name that appears on the subject match with the name that appears on the body of text.
msg = MIMEText ("Sent Happy Birthday Email to " + name + " on " + str(text.strftime('%Y-%m-%d %H:%M:%S %p')))
Here you are using the name variable when generating the body but earlier in your code you have:
name = df["name"][i]
Which grabs the name from the unfiltered DataFrame but you use the filtered DataFrame to generate the subject line here:
# replace [NAME] with actual name on the data
if len(new_df["name"]) > 1:
the_letter = letter_contents.replace("[NAME]", new_df["name"][i])
the_email = new_df["email"][i]
else:
the_letter = letter_contents.replace("[NAME]", new_df["name"].item())
the_email = new_df["email"].item()
The i-th element in the filtered DataFrame might not be the i-th element in your original DataFrame so you need to declare name as follows:
name = new_df["name"][i]

How can I send a routine email using a list as input?

I'm trying to write code in Python to help with sending an email that I send about twice a week, with the same format every time and just a few elements that differ between emails, so I wrote the following code to help with this:
def visitor():
visitors = []
number_of = int(input("How many visitors are you signing in? "))
time = input("What time are they coming? ")
comments = """
Please type the name of the first visitor, and their nationality on the next line, the name of the second visitor
and their nationality on the next line, until you wrote down all the names and nationalities.
If you wanna stop the program and execute the code with the names & nationalities, just type quit
"""
print(comments)
name, i = "", 1
while name != "quit":
name = str(input("Ignore: "))
visitors.append(name)
visitors = visitors.pop(-1)
email = f"""
Hello,
I have {number_of} visitors coming today at {time}.
Name: {visitors[i]}
Nationality: {visitors[i + 1]}
"""
for i in range(len(visitors)):
to_add = f"""
Name: {visitors[i]}
Nationality: {visitors[i + 1]}
"""
email += to_add
ending = "Awaiting your approval\nThank you"
email += ending
return email
visitor()
However, upon running this code, I run into a problem in line 25, saying "Index out of range" ( line 25 is Nationality: {visitors[i + 1]} ). This normally shouldn't happen since the list has more than one element. Can someone help with this?
P.S. I have another, way longer code written for this that works, but I wanted to try and improve it by making it less sloppy.
The visitors list is acceeded at offset i+1, and i go up to len(visitors)-1 (upper limit specified for the loop through range()), so there is an access out of range when i = len(visitors) - 1

How can I search the Outlook (2010) Global Address List for multiple names?

I've read this post How can I search the Outlook (2010) Global Address List for a name? and found a working solution for getting a name from Outlook GAL.
I have 3 questions:
I can get the contact if the search_string is an email address. When it's a name, the search doesn't work. It would return False for resolved, but True for sendable. Then I get error when using ae object. What am I doing wrong?
I don't understand the code enough to modify it for searching multiple names. I simply created a for loop but maybe there is a more efficient way? For example, can I reuse the outlook.Session object between different searches?
Is the line recipient.Resolve() necessary?
Thanks in advance!
My attempt is below.
from __future__ import print_function
import win32com.client
search_strings = ['Doe John', 'Doe Jane']
outlook = win32com.client.gencache.EnsureDispatch('Outlook.Application')
for search_string in search_strings:
recipient = outlook.Session.CreateRecipient(search_string)
recipient.Resolve()
print('Resolved OK: ', recipient.Resolved)
print('Is it a sendable? (address): ', recipient.Sendable)
print('Name: ', recipient.Name)
ae = recipient.AddressEntry
email_address = None
if 'EX' == ae.Type:
eu = ae.GetExchangeUser()
email_address = eu.PrimarySmtpAddress
if 'SMTP' == ae.Type:
email_address = ae.Address
print('Email address: ', email_address)
Can't believe I found the solution so quickly after posting the question. Since it's hard to find the answer. I'm sharing my findings here.
It's inspired by How to fetch exact match of addressEntry object from GAL (Global Address List), though it's in c# rather than python.
This method uses exact match of displayname rather than relying on outlook to resolve the name. Though, it's possible to loop through the global address list and do partial match yourself.
import win32com.client
search_string = 'Doe John'
outlook = win32com.client.gencache.EnsureDispatch('Outlook.Application')
gal = outlook.Session.GetGlobalAddressList()
entries = gal.AddressEntries
ae = entries[search_string]
email_address = None
if 'EX' == ae.Type:
eu = ae.GetExchangeUser()
email_address = eu.PrimarySmtpAddress
if 'SMTP' == ae.Type:
email_address = ae.Address
print('Email address: ', email_address)

Python - Replacing a specific value in a CSV file while keeping the rest

So I have a CSV file that looks something like this:
Username,Password,Name,DOB,Fav Artist,Fav Genre
Den1994,Denis1994,Denis,01/02/1994,Eminem,Pop
Joh1997,John1997,John,03/04/1997,Daft Punk,House
What I need to be able to do is let the user edit and change their Fav Artist and Fav Genre so that their new values are saved to the file in place of the old ones. I'm not the very advanced when it comes to CSV so I'm not sure where to begin with it, therefore any help and pointers will be greatly appreciated.
Thanks guys.
EDIT:
Adding the code I have so far so it doesn't seem like I'm just trying to get some easy way out of this, generally not sure what to do after this bit:
def editProfile():
username = globalUsername
file = open("users.csv", "r")
for line in file:
field = line.split(",")
storedUsername = field[0]
favArtist = field[4]
favGenre = field[5]
if username == storedUsername:
print("Your current favourite artist is:", favArtist,"\n" +
"Your current favourite genre is:",favGenre,"\n")
wantNewFavArtist = input("If you want to change your favourite artist type in Y, if not N: ")
wantNewFavGenre = input("If you want to change your favourite genre type in Y, if not N: ")
if wantNewFavArtist == "Y":
newFavArtist = input("Type in your new favourite artist: ")
if wantNewFavGenre == "Y":
newFavGenre = input("Type in your new favourite genre: ")
This is how it would look like using pandas
import pandas as pd
from io import StringIO
# Things you'll get from a user
globalUsername = "Den1994"
field = 'Fav Artist'
new_value = 'Linkin Park'
# Things you'll probably get from a data file
data = """
Username,Password,Name,DOB,Fav Artist,Fav Genre
Den1994,Denis1994,Denis,01/02/1994,Eminem,Pop
Joh1997,John1997,John,03/04/1997,Daft Punk,House
"""
# Load your data (e.g. from a CSV file)
df = pd.read_csv(StringIO(data)).set_index('Username')
print(df)
# Now change something
df.loc[globalUsername][field] = new_value
print(df)
Here df.loc[] allows you to access a row by the index. In this case Username is set as index. Then, [field] selects the column in that row.
Also, consider this:
df.loc[globalUsername][['Fav Artist', 'Fav Genre']] = 'Linkin Park', 'Nu Metal'
In case you have a my-data.csv file you can load it with:
df = pd.read_csv('my-data.csv')
The code above will return
Password Name DOB Fav Artist Fav Genre
Username
Den1994 Denis1994 Denis 01/02/1994 Eminem Pop
Joh1997 John1997 John 03/04/1997 Daft Punk House
and
Password Name DOB Fav Artist Fav Genre
Username
Den1994 Denis1994 Denis 01/02/1994 Linkin Park Pop
Joh1997 John1997 John 03/04/1997 Daft Punk House
Try this
import pandas as pd
data = pd.read_csv("old_file.csv")
data.loc[data.Username=='Den1994',['Fav Artist','Fav Genre']] = ['Beyonce','Hard rock']
data.to_csv('new_file.csv',index=False)
python has a built-in module dealing with csv, there are examples in the docs that will guide you right.
One way to do is to use the csv module to get the file you have into a list of lists, then you can edit the individual lists (rows) and just rewrite to disk what you have in memory.
Good luck.
PS: in the code that you have posted there is no assignment to the "csv in memory" based on the user-input
a minimal example without the file handling could be:
fake = 'abcdefghijkl'
csv = [list(fake[i:i+3]) for i in range(0, len(fake), 3)]
print(csv)
for row in csv:
if row[0] == 'd':
row[0] = 'changed'
print(csv)
the file handling is easy to get from the docs, and pandas dependance is avoided if that is on the wishlist

Python - Delete Conditional Lines of Chat Log File

I am trying to delete my conversation from a chat log file and only analyse the other persons data. When I load the file into Python like this:
with open(chatFile) as f:
chatLog = f.read().splitlines()
The data is loaded like this (much longer than the example):
'My Name',
'08:39 Chat data....!',
'Other person's name',
'08:39 Chat Data....',
'08:40 Chat data...,
'08:40 Chat data...?',
I would like it to look like this:
'Other person's name',
'08:39 Chat Data....',
'08:40 Chat data...,
'08:40 Chat data...?',
I was thinking of using an if statement with regular expressions:
name = 'My Name'
for x in chatLog:
if x == name:
"delete all data below until you get to reach the other
person's name"
I could not get this code to work properly, any ideas?
I think you misunderstand what "regular expressions" means... It doesn't mean you can just write English language instructions and the python interpreter will understand them. Either that or you were using pseudocode, which makes it impossible to debug.
If you don't have the other person's name, we can probably assume it doesn't begin with a number. Assuming all of the non-name lines do begin with a number, as in your example:
name = 'My Name'
skipLines = False
results = []
for x in chatLog:
if x == name:
skipLines = True
elif not x[0].isdigit():
skipLines = False
if not skipLines:
results.append(x)
others = []
on = True
for line in chatLog:
if not line[0].isdigit():
on = line != name
if on:
others.append(line)
You can delete all of your messages using re.sub with an empty string as the second argument which is your replacement string.
Assuming each chat message starts on a new line beginning with a time stamp, and that nobody's name can begin with a digit, the regular expression pattern re.escape(yourname) + r',\n(?:\d.*?\n)*' should match all of your messages, and then those matches can be replaced with the empty string.
import re
with open(chatfile) as f:
chatlog = f.read()
yourname = 'My Name'
pattern = re.escape(yourname) + r',\n(?:\d.*?\n)*'
others_messages = re.sub(pattern, '', chatlog)
print(others_messages)
This will work to delete the messages of any user from any chat log where an arbitrary number of users are chatting.

Categories