Python MAPI Outlook read emails for a particular year - python

This func is for Year alone. (Doesn't work)
def daterange(args):
user_inp = datetime.strptime(args,'%Y')
rmail = object.Restrict("[ReceivedTime] == '" + user_inp.strftime('%Y')+"'")
return rmail
The Restrict code doesn't work with = , throws error with == and only works with >=
My requirement is all mails from user_inp(2020) or 2019 etc
Please Help !!!

The Restrict code doesn't work with = , throws error with == and only works with >=
Using the equal operator is not really a good idea. Instead, you need to specify the time and date range. The difference can be a minute, but not equal.
Read more about the date and time comparisons in Outlook on the Filtering Items Using a Date-time Comparison page.

Related

Date Parsing problem while Integrating to Oracle PMS

I'm recieving date in PMS message something like this |GA090616|GD090617|
which means Guest Arrival is at 09-06-16 and Guest Deprature is at 09-06-17
I wanted to parse it as date using python.
I've also visited stack oveflow[1, 2 ...] for this but as solution I've found
from datetime import datetime
self.DATE_FROMAT='%d/%m/%y'
arrival_date=datetime.strptime('90616', self.DATE_FROMAT).date()
print(arrival_date)
and it's not possible to parse it like this due to its unclear format.
I'm not sure if 09 is a month or a date, but from what I've seen in documents and PDFs, it appears to be a month.
Is there any better solution for this kind of date parsing? or suggestions for my expectations.
09-06-16,
09-06-17
Note:
Please Just take the date from the string 090617 and parse it as a date. That will be helpful.
You can do this with regex matching, you can either split the string with msg.split("|") or not, but that depends on your use case.
import re
from datetime import datetime
msg = "GA090616|GD090617|"
DATE_FORMAT='%d%m%y'
ar = re.match("GA(\d{6})", msg)
dp = re.match("GD(\d{6})", msg)
guest_arrival = datetime.strptime(ar.group(1), DATE_FORMAT).date()
guest_departure = datetime.strptime(dp.group(1), DATE_FORMAT).date()
Although not fully tested, this should be a boilerplate as to how to retrieve the date from the message. Remember to remove the \ from the date format, as that is not included in the message.

Can I iterate through a whole CSV checking only one column

I know the main question is simple sounding, but I am specifically trying to iterate a whole CSV to find a certain variable while maintaining all the other columns connected to it. I am trying to create a file that essentially checks a certain date and then emails reminders or other templates to a list of students that qualify (based on the date or course) for the reminders. Currently with my code, I can't figure a way to keep the variables linked. I can get a list of students that I want to email, but am having trouble with the names staying linked to the emails I want.
import pandas as pd
import datetime as dt
from datetime import timedelta
import os
from email.message import EmailMessage
df = pd.read_excel('Students.xlsx')
EMAIL_ADDRESS = os.environ.get('EMAIL_USER')
EMAIL_PASSWORD = os.environ.get('EMAIL_PASS')
MAIL_LIST = ''
STUDENT_MAIL = df.student_email
DUE_DATE = df.course_completion_date
COURSE = df.course_section
START_DATE = dt.date.today()
END_DATE = START_DATE + timedelta(days=6)
I then have my codes for basic templates which I have tested and used prior so I know work.
But then I have tried several loops to try and add student emails to it through a loop so for example I would want all students finishing within a week to receive an email
for date in DUE_DATE:
if START_DATE <= date <= END_DATE:
MAIL_LIST = MAIL_LIST + STUDENT_EMAIL
else:
Now I know this looks dumb but this was just my last attempt at trying to get it to work. But I have tried several other ways to get it to work but the problem I run into is that the for loop has to be a single column to make a list it can check against but I need it connected to the second column of their emails to make the mailing list. Am I overcomplicating this I feel like I'm kind of going crazy
Using the DataFrame already will keep the variables linked like you would for index in rows and columns.
If you are trying to just grab the row matching the email you can use .loc to find the matching row for students to emails.
something like:
df.loc[x]['MAIL_LIST']
pandas.DataFrame.loc

Script works in CodeCademy but not at command line

I am a novice programmer teaching myself Python using CodeCademy. I wrote a script on my own in order to check the knowledge that I have learned thus far. The intention of this script is to print the names of people that are available on a certain weekend, based on a user-input date and cross-referenced with lists of dates that I wrote in the script.
The strange part is that this script functions exactly as intended in CodeCademy's Python environment, with no errors. It returns exactly the results I expect every single time. However, this is not the case when I try to run the script manually using Python 3.6.1 on my computer via the command line. Rather, it returns the same result every single time no matter what. Here is my code:
#script to tell who is free on a certain weekend
input_date = input("Please input the weekend on which you are looking for in
the format mm.dd (ex. weekend of June 30th is 06.30): ")
ben_dates = [06.16,06.23,06.30,07.07,07.14,08.04,08.11]
david_dates = [06.16,06.23,06.30,07.14,07.28,08.04,08.11]
danyall_dates = [06.30,07.07,07.14,07.21,07.28,08.04,08.11]
kevin_dates= [06.16,06.23,06.30,07.07,07.14,07.21,07.28,08.04,08.11,08.18]
manan_dates=[06.16,07.14,07.21,07.28,08.04]
jack_dates=[06.30,07.07,07.14,07.21,07.28,08.04]
free_people = "The people free on this date are: "
free_people_orig = free_people
for date in ben_dates:
if input_date == date:
free_people = free_people + "Ben, "
for date in david_dates:
if input_date == date:
free_people = free_people + "David, "
for date in danyall_dates:
if input_date == date:
free_people = free_people + "Danyall, "
for date in kevin_dates:
if input_date == date:
free_people = free_people + "Kevin, "
for date in manan_dates:
if input_date == date:
free_people = free_people + "Manan, "
for date in jack_dates:
if input_date == date:
free_people = free_people + "Jack, "
if len(free_people) == len(free_people_orig):
free_people = "No one is free on this weekend."
print(free_people)
So, for example, if the user inputs '06.30' on CodeCademy, the program will print 'The people free on this date are: Ben, David, Danyall, Kevin, Jack,' and this would be the correct result.
However, if run in command line, the same input will print 'No one is free on this weekend' and I have absolutely no idea why this is happening.
I have tried several different variations of while and for loops, using if, elif, and else statements, changing the conditions and format of the free_people string and what triggers it to be modified, as well as many other tactics for going about this specific solution, yet none have been able to make the script run properly. What am I doing wrong here that it works in CodeCademy but not on my computer?
Also, I am aware that this is far from the best way to create a script for this task, and even then my implementation could certainly be better. However, I am a beginner, and am writing this script with the primary concern of testing specific skills that I have learned by writing a script that could have some modicum of basic use for myself. I am only interested in figuring out why this specific version of this specific script does not work.
P.S. This is my first post on StackOverflow, my apologies if I formatted this post incorrectly.
The issue is that you are inputting a string, when it needs to be a float. Every element in your lists are floats, and you are trying to see if an element of type string exists in any of those lists, which is False.
Try this:
input_date = float(input("Please input the weekend on which you are looking for in the "
"format mm.dd (ex. weekend of June 30th is 06.30): "))

listing Outlook emails by specific date in Python

I'm using Python 3.
I'm trying to extract (list / print show) outlook emails by date.
I was trying a loop.. maybe WHILE or IF statement.
Can it be done since ones a string and the other is a date.
Please concide what I've got so far: Thanks.
1. import win32com.client, datetime
2.
3. # Connect with MS Outlook - must be open.
4. outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
5. # connect to Sent Items
6. sent = outlook.GetDefaultFolder(5).Items # "5" refers to the sent item of a folder
7.
8. # Get yesterdays date
9. y = (datetime.date.today () - datetime.timedelta (days=1))
10. # Get emails by selected date
11. if sent == y:
12. msg = sent.GetLast()
13. # get Subject line
14. sjl = msg.subject
14. # print it out
15. print (sjl)
Ive completed the code. Thanks for help.
`import sys, win32com.client, datetime
# Connect with MS Outlook - must be open.
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace
("MAPI")
# connect to Sent Items
s = outlook.GetDefaultFolder(5).Items # "5" refers to the sent item of a
folder
#s.Sort("s", true)
# Get yesterdays date for the purpose of getting emails from this date
d = (datetime.date.today() - datetime.timedelta (days=1)).strftime("%d-%m-%
y")
# get the email/s
msg = s.GetLast()
# Loop through emails
while msg:
# Get email date
date = msg.SentOn.strftime("%d-%m-%y")
# Get Subject Line of email
sjl = msg.Subject
# Set the critera for whats wanted
if d == date and msg.Subject.startswith("xx") or msg.Subject.startswith
("yy"):
print("Subject: " + sjl + " Date : ", date)
msg = s.GetPrevious() `
This works. However if no message according to the constraint if found, it doesnt exit. Ive tried break which just finds one message and not all, Im wondering if and how to do an exception? or if i try a else d != date it doenst work either (it will not find anything).
I cant see that a For loop will work using a date with a msg(string).
I not sure -- biginner here :)
??
The outlook API has a method, Items.Find, for searching the contents of .Items. If this is the extent of what you want to do, that's probably how you should do it.
Right now it seems like your if statement is checking whether set of emails is equal to yesterday.
Microsoft's documentation says .Items is returning a collection of emails which you first must iterate through using a few different methods including Items.GetNext or by referencing a specific index with Items.Item.
You can then take the current email and access the .SentOn property.
currentMessage = sent.GetFirst()
while currentMessage:
if currentMessage.SentOn == y:
sjl = currentMessage.Subject
print(sjl)
currentMessage = sent.GetNext()
This should iterate through all messages in the sent folder until sent.GetNext() has no more messages to return. You will have to make sure y is the same formatting as what .SentOn returns.
If you don't want to iterate through every message, you could probably also nest two loops that goes back in messages until it gets to yesterday, iterates until it is no longer within "yesterday", and then breaks.
The COM API documentation is fairly thorough, you can see the class list for example here. It also documents the various methods you can use to manipulate the objects it has. In your particular example what you are after is to restrict your set of items via date. You will see that there is already a function for that in the items class here. Conveniently it is called Restrict. The only gotcha I can see with that function is that you need to specify the filter that you would like on your items in string form, thus requiring you to construct the string yourself.
So for example to continue your code and restrict by time:
#first create the string filter, here you would like to filter on sent time
#assuming you wanted emails after 5 pm as an example and your date d from the code above
sFilter = "[SentOn] > '{0} 5:00 PM'".format(d)
#then simply retrieve your restricted items
filteredEmails = s.Restrict(sFilter)
You can of course restrict by all sorts of criteria, just check the documentation on the function. This way if you restrict and it returns an empty set of items you can handle that case in the code rather than having to work with exceptions. So for example:
#you have restricted your selection now want to check if you have anything
if filteredEmails.Count == 0:
#handle this situation however you would like

Getting a count of action from today's date from filtered results in Python

I have an action that a user can do many times a day. I'm trying to get a count of how many times the user has taken that action, but only for today's date. Here's the way I'm currently solving this, but is there an easier way? I feel like I should be able to fit this in one line. :)
today_slaps = 0
slaps = Slap.objects.filter(from_user=request.user.id)
for slap in slaps:
if slap.date.date() == datetime.now().date():
today_slaps += 1
The logic I'm looking for is:
slaps = Slap.objects.filter(from_user=2, date.date()=datetime.now().date()).count()
But that's obviously throwing an error that a keyword can't be an expression. Sorry if this is a basic one, but thoughts?
slap_count = Slap.objects.filter(from_user=request.user, \
date__gte=datetime.date.today()).count()
# specifically setting datetimefield=datetime.date.today() won't work
# gte = will work for datetimefield vs datetime object starting at that date
# it's also assumed there will never be a slap from the future.
Generates the following SQL:
SELECT ... FROM ... WHERE ... date >= 2011-02-26 00:00:00
So it's safe to say you will only get today's slaps, again, unless you have slaps from the future. If you do, I'd set every date__day, date__year, date__month explicitly.
Thanks to Yuji (below) we came up with this answer:
slap_count = Slap.objects.filter(from_user=request.user.id, date__gte=datetime.today().date()).count()

Categories

Resources