Skip to content

Instantly share code, notes, and snippets.

@broschke
Created March 12, 2019 18:17
Show Gist options
  • Save broschke/dd61de0a208cd21e5c327665c81487f7 to your computer and use it in GitHub Desktop.
Save broschke/dd61de0a208cd21e5c327665c81487f7 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we import then neccessary packages. When working with Microsoft services, win32 package is handy. We'll also need datetime and pandas. "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import win32com.client as win32\n",
"import datetime\n",
"import pandas as pd"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We create the objects needed to work with MS Outlook. I'm using a shared inbox that gets a copy of every email. You can pass in the email name for folder object and repeat for the actual Inbox of that email. Finally we grab all the inbox items and the current date. "
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"outlook = win32.Dispatch(\"Outlook.Application\").GetNamespace(\"MAPI\")\n",
"folder = outlook.Folders(\"my-shared-email-name\")\n",
"inbox = folder.Folders(\"Inbox\")\n",
"messages = inbox.Items\n",
"email_date = datetime.datetime.now()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now it is time for our function. Create an empty list to capture the function results. We also have a counter to print out how many messages it has processed so you know how long it's been running. For this blog post, I commented out that portion.\n",
"\n",
"The function starts a while loop and checks the first message's date to the current date. If they equal, we go to the next condition. The subject of each email that we want begins with the property's five digit ID and we append those to our empty list. All other emails in the inbox are skipped. This loop repeats to the next message until we have processed all messages of today's date. "
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"subject_list = []\n",
"\n",
"def scan_inbox(m):\n",
" counter = 0\n",
" m = messages.GetFirst()\n",
" while m.CreationTime.date() == email_date.date():\n",
" if m.subject[:13] !='Undeliverable' and m.subject[:5] !='Daily':\n",
" subject_list.append(m.subject)\n",
" m = messages.GetNext()\n",
"# counter += 1\n",
"# print(counter)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Call our function, passing in the messages object."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"scan_inbox(messages)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result of the function is a list with every email subject. We only want the first five characters of each list item. So we create another empty list and strip out and append the first five digits. "
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"emails_sent = []\n",
"for i in subject_list:\n",
" emails_sent.append(i[:5])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we import the master list of properties that should receive the daily report into a dataframe. "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv('report_properties.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We use the not \"~\" to check which prop ids are not in our emails_sent list. The tilde reverses the isin. "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"df_props_no_email = df[~df.prop.isin(emails_sent)]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we output the result to a csv. I like python's chaining abilities with the dot notation. We first sort the list by id and then output without the dataframe index. "
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"df_props_no_email.sort_values(by=['prop']).to_csv('props_no_email.csv',index=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we're able to start our triage of the process break down. We know if a property did not receive the email and can further diagnose the issue. Happy Pythoning!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment