Advertisement
Guest User

Untitled

a guest
Jul 12th, 2016
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.91 KB | None | 0 0
  1. import getpass, imaplib, email, re
  2. import numbers
  3. import decimal
  4.  
  5.  
  6.  
  7.  
  8.    
  9. def connect():
  10.  
  11.     username = input("Username: ")
  12.     password = input("Password: ")
  13.  
  14.     print("Logging into mail server...")
  15.     M = imaplib.IMAP4_SSL('imap.gmail.com', 993)
  16.     M.login(username, password)
  17.     M.select('inbox')
  18.  
  19.     return M
  20.  
  21. def get_new_reports(M):
  22.    
  23.     print("Looking at mailbox for unseen reports...")
  24.     (retcode, messages) = M.search(None, '(UNSEEN)', 'SUBJECT "Expense Report"')
  25.     num_messages =  len(messages[0].split())
  26.     print("New Reports: ", num_messages)
  27.  
  28.     if retcode == 'OK' and num_messages > 0:
  29.         return messages
  30.     else:
  31.         return None
  32.  
  33.  
  34. def parse_reports(messages, M):
  35.     n = 1
  36.     for num in messages[0].split():
  37.         print("Fetching report: ", n)
  38.         typ, data = M.fetch(num, '(RFC822)')
  39.         raw_email = data[0][1];
  40.         n = n + 1
  41.         print("Decoding...")
  42.         raw_email_string = raw_email.decode('utf-8')
  43.         # converts byte literal to string removing b''
  44.         email_message = email.message_from_string(raw_email_string)
  45.        
  46.        
  47.         if (email_message.is_multipart()):
  48.             print("multipart")
  49.         else:
  50.             print("not multipart")
  51.  
  52.         for part in email_message.walk():
  53.                         if part.get_content_type() == "text/plain": # ignore attachments/html
  54.                                 body = str(part).replace("Content-Type: text/plain; charset=UTF-8", "");
  55.                                 print("Parsing...")
  56.                                 process(body);
  57.     i = input("")
  58.     M.close()
  59.     M.logout()
  60.  
  61. def process(body):
  62.  
  63.     expense_report = Report();
  64.         # Use a hashmap to hold entries to map account_num --> list [start_date, end_date, amount, vender, requester] all under the same project number
  65.     entries = dict();
  66.     sections = body.split("------------------------------")
  67.     # ----variables global to each report ---
  68.     project_num = '';
  69.     report_name = '';
  70.     employee_name = '';
  71.     last_code = None;
  72.     # ---------------------------------------
  73.     for sub in sections:
  74.        # If Expense report section, grab project # ------------
  75.         if ("Expense Report" in sub):
  76.             expense_report.project_num = re.findall( r'\d+\.*\d*', sub )[0]
  77.         #   print("Project #", expense_report.project_num)
  78.            # get Report name by finding index
  79.             i = sub.find("Report Name :") + 14
  80.             j = i
  81.             while(sub[j] != '\n'):
  82.                 j = j + 1
  83.             expense_report.report_name = sub[i:j]
  84.         # If Exployee Name section, grab Employee name ----------
  85.         if ("Employee Name :" in sub):
  86.             i = sub.find("Employee Name :")+16
  87.             #get index of 'Employee Name' substring
  88.             j = i
  89.             while(sub[j] != '\n'):
  90.                 #concatenate employee name
  91.                 j = j + 1
  92.             expense_report.employee_name = sub[i:j]
  93.             #split by transaction
  94.        
  95.         #divide up by expense
  96.         for expense in sub.split("Expense Type"):
  97.             #get account code unique to expense set
  98.             account_code = ''
  99.             result = (re.findall(r"\D(\d{5})\D", expense))
  100.  
  101.             if result:
  102.                 #get account code -------------------------------
  103.                 account_code = int(result[0])
  104.                 #filter out strange results
  105.                 if (account_code < 6000 or account_code > 69999):
  106.                     continue
  107.             #   print("Account Code Group:", account_code)
  108.  
  109.                 #get [Expense Type] -----------------------------
  110.                 if ("Amount" in expense):
  111.                     i = expense.find("Amount") + 20
  112.                     j = i
  113.                 while (expense[j] != "\n"):
  114.                     j = j + 1
  115.                 expense_type = expense[i:j]
  116.             #   print("Expense_type: ", expense_type)
  117.  
  118.                 #get allocations -------------------------------
  119.                 for transaction in expense.split("Allocations"):
  120.                     amount = '';
  121.                     i = -1
  122.                     j = -1
  123.                     i = transaction.find("(")
  124.                     j = transaction.find(")"); 
  125.                     if (i < 0 or j < 0):
  126.                         # if amount not found, continue to next iteration
  127.                         continue
  128.                     #set amount of allocation
  129.                     amount = float(transaction[i+2:j])
  130.                     #get date
  131.                     result = re.search("([0-9]{2}\/[0-9]{2}\/[0-9]{4})", transaction)
  132.                     date = ''
  133.                     if result is not None:
  134.                         date = result.group(1)
  135.                 #   print("Transaction Date: ", date)
  136.                 #   print("Transaction Amount: ", amount)
  137.  
  138.                     #make entry in dictionary
  139.                     expense_report.allocate(account_code, expense_type, date, amount)
  140.    
  141.     print("---------New report entry ready--------")
  142.     print("Project Number: ", expense_report.project_num)
  143.     print("Start Date: ", expense_report.getFirstDate())
  144.     print("Report name: ", expense_report.report_name)
  145.     print("Requester: ", expense_report.employee_name)
  146.     print("Approver: VP Administration")
  147.     for key in expense_report.entries:
  148.         print("Account Code: ", key, ", Date: ", expense_report.entries[key][0], ", Amount: ", expense_report.entries[key][1],  ", Expense Type: ", expense_report.entries[key][2])
  149.     print("---------------------------------------")
  150.  
  151. class Report():
  152.     print("New Report")
  153.     def __init__(self):
  154.         self.project_num = None    # instance variable unique to each instance
  155.         self.report_name = None
  156.         self.first_date = None
  157.         self.employee_name = None
  158.         self.entries = dict()
  159.     def getFirstDate(self):
  160.         if ("-" in self.report_name): # if date duration
  161.             i = self.report_name.find("-");
  162.             return self.report_name[0:i];
  163.         i = self.report_name.find(" ");
  164.         return self.report_name[0:i];
  165.     def allocate(self, account_code, expense_type, date, amount):
  166.     # check if we've already made an entry under this account code:
  167.         if (account_code in self.entries):
  168.             # we have, so just append the allocation
  169.         #   print("Allocation already made for account code: ", account_code, "Appending new allocation: ", amount)
  170.             self.entries[account_code][1] += amount;
  171.         else:
  172.             # we have not made an entry for this account code
  173.         #   print("No entry present under account code: ", account_code, "adding new entry!")
  174.  
  175.             self.entries[account_code] = list()
  176.             self.entries[account_code].append(date)
  177.             self.entries[account_code].append(amount)
  178.             self.entries[account_code].append(expense_type)
  179.  
  180. mailbox = connect();
  181. reports = get_new_reports(mailbox);
  182. # if reports is not None, parse
  183. if(reports):
  184.     parse_reports(reports, mailbox);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement