from selenium import webdriver from selenium.webdriver.common.by import By from common import MailProvider, MailMessage from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import ElementNotInteractableException import json from time import sleep class ProtonWebmail(MailProvider): xpaths = { "username_box": "/html/body/div[1]/div[4]/div[1]/main/div[1]/div[2]/form/div[2]/div[1]/div/div/input", "password_box": "/html/body/div[1]/div[4]/div[1]/main/div[1]/div[2]/form/div[3]/div[1]/div/div[1]/input", "sign_in": "/html/body/div[1]/div[4]/div[1]/main/div[1]/div[2]/form/button", "messages": "/html/body/div[1]/div[3]/div/div[2]/div/div[2]/div/div/div/main/div/div/div/div/div/div[2]/div[2]", "messagebody": "/html/body/div[1]/div[3]/div/div[2]/div/div[2]/div/div/div/main/div/div/section/div/div[3]/div/div/article/div[2]", "backbutton": "//*[text()[contains(., 'Back')]]", "reply": "/html/body/div[1]/div[3]/div/div[2]/div/div[2]/div/div/div/main/div/div/section/div/div[3]/div/div/article/div[1]/div[4]/div[2]/button[1]", "replytextarea": "/html/body/div[1]/div[4]/div/div/div/div/section/div/div[1]/div/div/textarea", "replysubmit": "/html/body/div[1]/div[4]/div/div/div/footer/div/div[1]/button[1]", } def transform_message_header(self, header): return header.replace('\n', ' - ').replace('Unread email - ', '') def get(self): self.messages_failed = 0 self.read_data() self._get_webdriver() self.webdriver.get("https://account.proton.me/login") self._wait_for_elem(self.xpaths["username_box"]) sleep(0.5) self._type_in_elem(self.xpaths["username_box"], self.username) self._click_elem(self.xpaths["password_box"]) self._type_in_elem(self.xpaths["password_box"], self.password) self._click_elem(self.xpaths["sign_in"]) self._wait_for_elem(self.xpaths["messages"]) for i in self._get_elem_children(self._to_elem(self.xpaths["messages"])): index = self.transform_message_header(i.text) if not self.is_seen(index): text = i.text # we can interact with it, just selenium doesn't like it try: self._click_elem(i) except ElementNotInteractableException: pass self._wait_for_elem(self.xpaths["messagebody"]) sleep(5) self.webdriver.switch_to.frame( self._to_elem(self.xpaths["messagebody"]) \ .find_elements(By.XPATH, "//iframe")[0] ) splitted = index.split(' - ') message = MailMessage( index = self.transform_message_header(text), sender = splitted[0], subject = splitted[3], maintext = self.webdriver.page_source, ) self.add_to_seen(message) self.webdriver.switch_to.default_content() sleep(2) self._click_elem(self.xpaths["backbutton"]) sleep(2) else: # check if we have to reply to this email print("checking if we have to reply") search = self.transform_message_header(i.text) selected = None for message in self.seen_messages: if message.index == search: selected = message if not selected: continue for message_to_send in self.to_send: print('loop iter 1') print(message_to_send.in_response_to_id, selected.id) if message_to_send.in_response_to_id == selected.id: # we do have to reply print("sending reply to message id {}".format(str(selected.id))) try: self._click_elem(i) except ElementNotInteractableException: pass self._wait_for_elem(self.xpaths["messagebody"]) sleep(5) self._click_elem(self.xpaths["reply"]) sleep(1) replytextarea = self._to_elem(self.xpaths["replytextarea"]) replytextarea.clear() replytextarea.send_keys(message_to_send.body) sleep(1) self._click_elem(self.xpaths["replysubmit"]) sleep(2) self._click_elem(self.xpaths["backbutton"]) sleep(2) self.write_data() self.webdriver.quit() return self