forked from GC-Guy/staples_egc_extractor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextractor.py
122 lines (96 loc) · 4.9 KB
/
extractor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os
import email
import re
import csv
from datetime import datetime
from imaplib import IMAP4, IMAP4_SSL
from bs4 import BeautifulSoup
from selenium import webdriver
import config
# Fetch codes from DOM
def fetch_codes(browser):
# Get the type of card
card_type = browser.find_element_by_xpath('//*[@id="main"]/p/strong').text.strip()
card_type = re.compile(r"Your (.*) eGift card").match(card_type).group(1)
# Get the card amount
card_amount = browser.find_element_by_xpath('//*[@id="main"]/div[1]/div[2]/h2').text.strip()
# Get the card number
card_number = browser.find_element_by_xpath('//*[@id="cardNumber2"]').text
card_number = re.sub(r"\s+", '', card_number)
# Get the barcode number
barcode_number = browser.find_element_by_xpath('//*[@id="barcodeData"]').get_attribute("innerHTML")
barcode_number = re.sub(r"\s+", '', barcode_number)
return (card_type, card_amount, card_number, barcode_number)
# Connect to the server
if config.IMAP_SSL:
mailbox = IMAP4_SSL(host=config.IMAP_HOST, port=config.IMAP_PORT)
else:
mailbox = IMAP4(host=config.IMAP_HOST, port=config.IMAP_PORT)
# Log in and select the configured folder
mailbox.login(config.IMAP_USERNAME, config.IMAP_PASSWORD)
mailbox.select(config.FOLDER)
# Search for matching emails
status, messages = mailbox.search(None, '(FROM {})'.format(config.FROM_EMAIL))
if status == "OK":
# Convert the result list to an array of message IDs
messages = messages[0].split()
if len(messages) < 1:
# No matching messages, stop
print("No matching messages found, nothing to do.")
exit()
# Open the CSV for writing
with open('cards_' + datetime.now().strftime('%m-%d-%Y_%H%M%S') + '.csv', 'w', newline='') as csv_file:
# Start the browser and the CSV writer
browser = webdriver.Chrome(config.CHROMEDRIVER_PATH)
csv_writer = csv.writer(csv_file)
# Create a directory for screenshots if it doesn't already exist
screenshots_dir = os.path.join(os.getcwd(), 'screenshots')
if not os.path.exists(screenshots_dir):
os.makedirs(screenshots_dir)
# For each matching email...
for msg_id in messages:
print("---> Processing message id {}...".format(msg_id.decode('UTF-8')))
# Fetch it from the server
status, data = mailbox.fetch(msg_id, '(RFC822)')
if status == "OK":
# Convert it to an Email object
msg = email.message_from_bytes(data[0][1])
# Get the HTML body payload
msg_html = msg.get_payload(1).get_payload(decode=True)
# Save the email timestamp
datetime_received = datetime.fromtimestamp(
email.utils.mktime_tz(email.utils.parsedate_tz(msg.get('date'))))
# Parse the message
msg_parsed = BeautifulSoup(msg_html, 'html.parser')
# Find the "View Gift" link
egc_link = msg_parsed.find("a", title="View Gift")
if egc_link is not None:
# Open the link in the browser
browser.get(egc_link['href'])
card_type, card_amount, card_number, barcode_number = fetch_codes(browser)
while card_number != barcode_number:
print("WARNING: Erroneous code found. Retrying.")
print("card_number: {}; barcode_number: {}".format(card_number, barcode_number))
browser.get(egc_link['href'])
card_type, card_amount, card_number, barcode_number = fetch_codes(browser)
# Get the card PIN if it exists, otherwise set to N/A
elem = browser.find_elements_by_xpath('//*[@id="main"]/div[2]/div[2]/p[2]/span')
if len(elem) > 0:
card_pin = re.sub(r"\s+", '', browser.find_element_by_xpath('//*[@id="main"]/div[2]/div[2]/p[2]/span').text)
else:
card_pin = 'N/A'
# Save a screenshot
browser.save_screenshot(os.path.join(screenshots_dir, card_number + '.png'))
# Write the details to the CSV
csv_writer.writerow([card_amount, card_number, card_pin, card_type, datetime_received, egc_link['href']])
# Print out the details to the console
print("{}: {} {}, {}, {}".format(card_amount, card_number, card_pin, card_type, datetime_received))
else:
print("ERROR: Unable to find eGC link in message {}, skipping.".format(msg_id.decode('UTF-8')))
else:
print("ERROR: Unable to fetch message {}, skipping.".format(msg_id.decode('UTF-8')))
# Close the browser
browser.close()
else:
print("FATAL ERROR: Unable to fetch list of messages from server.")
exit(1)