diff --git a/src/mail_order_bot/email_handler/context.py b/src/mail_order_bot/context.py similarity index 97% rename from src/mail_order_bot/email_handler/context.py rename to src/mail_order_bot/context.py index 9e9dd86..9d6c8dd 100644 --- a/src/mail_order_bot/email_handler/context.py +++ b/src/mail_order_bot/context.py @@ -17,6 +17,7 @@ class Context(metaclass=_SingletonMeta): def __init__(self): # будет вызван только при первом создании self.context = {} + self.email_client = None def clear_context(self): """Очищает self.context, устанавливая его в None или пустой словарь""" diff --git a/src/mail_order_bot/email_client/client.py b/src/mail_order_bot/email_client/client.py index c5e1065..c176f31 100644 --- a/src/mail_order_bot/email_client/client.py +++ b/src/mail_order_bot/email_client/client.py @@ -11,38 +11,13 @@ from email.header import decode_header import imaplib import smtplib -from .objects import EmailMessage, EmailAttachment + +# from .objects import EmailMessage, EmailAttachment class EmailClient: - """ - Класс для работы с электронной почтой по протоколам IMAP и SMTP. - - Пример использования: - client = EmailClient( - imap_host='imap.gmail.com', - smtp_host='smtp.gmail.com', - email='your_email@gmail.com', - password='your_password' - ) - - # Получить новые письма - new_emails = client.get_emails() - - # Отправить письмо - msg = EmailMessage( - from_addr='sender@example.com', - subj='Test', - dt=datetime.now(), - body='Hello!', - attachments=[] - ) - client.send_email(msg, to_addr='recipient@example.com') - """ - def __init__(self, imap_host: str, smtp_host: str, email: str, password: str, imap_port: int = 993, smtp_port: int = 587): - self.imap_host = imap_host self.smtp_host = smtp_host self.email = email @@ -50,15 +25,15 @@ class EmailClient: self.imap_port = imap_port self.smtp_port = smtp_port self.imap_conn = None - + def connect(self): - """Установить IMAP соединение""" + """Установkение IMAP соединения""" if self.imap_conn is None: self.imap_conn = imaplib.IMAP4_SSL(self.imap_host, self.imap_port) self.imap_conn.login(self.email, self.password) def disconnect(self): - """Закрыть IMAP соединение""" + """Закрытие IMAP соединения""" if self.imap_conn: try: self.imap_conn.disconnect() @@ -67,7 +42,48 @@ class EmailClient: pass self.imap_conn = None - def _decode_header(self, header_value: str) -> str: + def __enter__(self): + """Поддержка контекстного менеджера""" + self.connect() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + """Поддержка контекстного менеджера""" + self.disconnect() + + def get_emails_id(self, folder: str = "INBOX", only_unseen: bool = True) -> List[int]: + """Получить список новых электронных писем.""" + self.connect() + self.imap_conn.select(folder, readonly=False) + # Ищем письма + search_criteria = "(UNSEEN)" if only_unseen else "ALL" + status, messages = self.imap_conn.search(None, search_criteria) + + # ToDo сделать обработку ошибок, подумать нужна ли она! + if status != "OK": + return [] + + email_ids = messages[0].split() + return email_ids + + def get_email(self, email_id, mark_as_read: bool = True): + """Получить список новых электронных писем.""" + self.connect() + status, msg_data = self.imap_conn.fetch(email_id, "(RFC822)") + if status != "OK": + pass + + # Парсим письмо + raw_email = msg_data[0][1] + msg = email.message_from_bytes(raw_email) + + # Помечаем письмо как прочитанное + if mark_as_read: + self.imap_conn.store(email_id, '+FLAGS', '\\Seen') + + return msg + + def decode_header(self, header_value: str) -> str: """Декодировать заголовок письма.""" if header_value is None: return "" @@ -84,215 +100,5 @@ class EmailClient: decoded_parts.append(part.decode('utf-8', errors='ignore')) else: decoded_parts.append(str(part)) - - return ''.join(decoded_parts) - - def _extract_body(self, msg: email.message.Message) -> str: - """Извлечь текст письма из любого типа содержимого, кроме вложений""" - body = "" - if msg.is_multipart(): - for part in msg.walk(): - content_disposition = str(part.get("Content-Disposition", "")) - # Пропускаем вложения - if "attachment" in content_disposition.lower(): - continue - try: - charset = part.get_content_charset() or 'utf-8' - payload = part.get_payload(decode=True) - if payload: - body_piece = payload.decode(charset, errors='ignore') - body += body_piece - except Exception: - pass - else: - try: - charset = msg.get_content_charset() or 'utf-8' - payload = msg.get_payload(decode=True) - if payload: - body = payload.decode(charset, errors='ignore') - except Exception: - pass - - return body - - def __extract_email(self, text: str) -> str: - match = re.search(r'<([^<>]+)>', text) - if match: - return match.group(1) - return None - - def _extract_first_sender(self, body: str): - """Извлекает адреса отправителей из пересылаемого сообщения. Нужно для отладки""" - # Ищем email внутри скобок после строки "Пересылаемое сообщение" - pattern = r"Пересылаемое сообщение.*?\((.*?)\)" - match = re.search(pattern, body, re.DOTALL) - if match: - return match.group(1) - return None - - def _extract_attachments(self, msg: email.message.Message) -> List[EmailAttachment]: - """Извлечь вложения из письма.""" - attachments = [] - - for part in msg.walk(): - content_disposition = str(part.get("Content-Disposition", "")) - - if "attachment" in content_disposition: - filename = part.get_filename() - if filename: - # Декодируем имя файла - filename = self._decode_header(filename) - # Получаем содержимое - content = part.get_payload(decode=True) - if content: - attachments.append(EmailAttachment(filename=filename, content=content)) - return attachments - - def get_emails_id(self, folder: str = "INBOX", only_unseen: bool = True, mark_as_read: bool = True) -> List[ - EmailMessage]: - """Получить список новых электронных писем.""" - self.connect() - - # Выбираем папку - self.imap_conn.select(folder, readonly=False) - - # Ищем письма - search_criteria = "(UNSEEN)" if only_unseen else "ALL" - status, messages = self.imap_conn.search(None, search_criteria) - - if status != "OK": - return [] - - email_ids = messages[0].split() - return email_ids - - - - - - def get_emails(self, folder: str = "INBOX", only_unseen: bool = True, mark_as_read: bool = True) -> List[EmailMessage]: - """Получить список новых электронных писем.""" - self.connect() - - # Выбираем папку - self.imap_conn.select(folder, readonly=False) - - # Ищем письма - search_criteria = "(UNSEEN)" if only_unseen else "ALL" - status, messages = self.imap_conn.search(None, search_criteria) - - if status != "OK": - return [] - - email_ids = messages[0].split() - emails = [] - - for email_id in email_ids: - try: - # Получаем письмо - status, msg_data = self.imap_conn.fetch(email_id, "(RFC822)") - - if status != "OK": - continue - - # Парсим письмо - raw_email = msg_data[0][1] - msg = email.message_from_bytes(raw_email) - - # Извлекаем данные - from_addr = self._decode_header(msg.get("From", "")) - subject = self._decode_header(msg.get("Subject", "")) - - from_email = self.__extract_email(from_addr) - - # Получаем дату - date_str = msg.get("Date", "") - try: - date_tuple = email.utils.parsedate_tz(date_str) - if date_tuple: - timestamp = email.utils.mktime_tz(date_tuple) - dt = datetime.fromtimestamp(timestamp) - else: - dt = datetime.now() - except: - dt = datetime.now() - - # Извлекаем тело письма - body = self._extract_body(msg) - - #print(body) - first_sender = self._extract_first_sender(body) - - # Извлекаем вложения - attachments = self._extract_attachments(msg) - - # Создаем объект письма - email_obj = EmailMessage( - from_addr=from_addr, - from_email=from_email, - subj=subject, - dt=dt, - body=body, - attachments=attachments, - first_sender=first_sender - ) - - emails.append(email_obj) - - # Помечаем письмо как прочитанное - if mark_as_read: - self.imap_conn.store(email_id, '+FLAGS', '\\Seen') - - except Exception as e: - print(f"Ошибка при обработке письма {email_id}: {e}") - continue - - return emails - - def send_email(self, message: EmailMessage, to_addr: str, cc: Optional[List[str]] = None, bcc: Optional[List[str]] = None): - """Отправить электронное письмо""" - # Создаем multipart сообщение - msg = MIMEMultipart() - msg['From'] = self.email - msg['To'] = to_addr - msg['Subject'] = message.subj - - if cc: - msg['Cc'] = ', '.join(cc) - - # Добавляем тело письма - msg.attach(MIMEText(message.body, 'plain', 'utf-8')) - - # Добавляем вложения - for attachment in message.attachments: - part = MIMEBase('application', 'octet-stream') - part.set_payload(attachment.content) - encoders.encode_base64(part) - part.add_header( - 'Content-Disposition', - f'attachment; filename= {attachment.filename}' - ) - msg.attach(part) - - # Формируем список всех получателей - recipients = [to_addr] - if cc: - recipients.extend(cc) - if bcc: - recipients.extend(bcc) - - # Отправляем письмо - with smtplib.SMTP(self.smtp_host, self.smtp_port) as server: - server.starttls() - server.login(self.email, self.password) - server.sendmail(self.email, recipients, msg.as_string()) - - def __enter__(self): - """Поддержка контекстного менеджера""" - self.connect() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - """Поддержка контекстного менеджера""" - self.disconnect() + return ''.join(decoded_parts) \ No newline at end of file diff --git a/src/mail_order_bot/email_client/email_magic.py b/src/mail_order_bot/email_client/email_magic.py new file mode 100644 index 0000000..c8e6370 --- /dev/null +++ b/src/mail_order_bot/email_client/email_magic.py @@ -0,0 +1,99 @@ +import re +from datetime import datetime +from typing import List, Optional +from dataclasses import dataclass +import email +from email import encoders +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.mime.base import MIMEBase +from email.header import decode_header +import imaplib +import smtplib + + + +class EmailMagic: + def __init__(self, email): + self.email = email + + def _decode_header(self, header_value: str) -> str: + """Декодировать заголовок письма.""" + if header_value is None: + return "" + + decoded_parts = [] + for part, encoding in decode_header(header_value): + if isinstance(part, bytes): + if encoding: + try: + decoded_parts.append(part.decode(encoding)) + except: + decoded_parts.append(part.decode('utf-8', errors='ignore')) + else: + decoded_parts.append(part.decode('utf-8', errors='ignore')) + else: + decoded_parts.append(str(part)) + + return ''.join(decoded_parts) + + def _extract_body(self, msg: email.message.Message) -> str: + """Извлечь текст письма из любого типа содержимого, кроме вложений""" + body = "" + if msg.is_multipart(): + for part in msg.walk(): + content_disposition = str(part.get("Content-Disposition", "")) + # Пропускаем вложения + if "attachment" in content_disposition.lower(): + continue + try: + charset = part.get_content_charset() or 'utf-8' + payload = part.get_payload(decode=True) + if payload: + body_piece = payload.decode(charset, errors='ignore') + body += body_piece + except Exception: + pass + else: + try: + charset = msg.get_content_charset() or 'utf-8' + payload = msg.get_payload(decode=True) + if payload: + body = payload.decode(charset, errors='ignore') + except Exception: + pass + + return body + + def __extract_email(self, text: str) -> str: + match = re.search(r'<([^<>]+)>', text) + if match: + return match.group(1) + return None + + def _extract_first_sender(self, body: str): + """Извлекает адреса отправителей из пересылаемого сообщения. Нужно для отладки""" + # Ищем email внутри скобок после строки "Пересылаемое сообщение" + pattern = r"Пересылаемое сообщение.*?\((.*?)\)" + match = re.search(pattern, body, re.DOTALL) + if match: + return match.group(1) + return None + + def _extract_attachments(self, msg: email.message.Message) -> List[EmailAttachment]: + """Извлечь вложения из письма.""" + attachments = [] + + for part in msg.walk(): + content_disposition = str(part.get("Content-Disposition", "")) + + if "attachment" in content_disposition: + filename = part.get_filename() + if filename: + # Декодируем имя файла + filename = self._decode_header(filename) + # Получаем содержимое + content = part.get_payload(decode=True) + if content: + attachments.append(EmailAttachment(filename=filename, content=content)) + return attachments diff --git a/src/mail_order_bot/email_handler/__init__.py b/src/mail_order_bot/email_handler/__init__.py deleted file mode 100644 index 920cb04..0000000 --- a/src/mail_order_bot/email_handler/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .email_processor import EmailProcessor \ No newline at end of file diff --git a/src/mail_order_bot/email_processor/__init__.py b/src/mail_order_bot/email_processor/__init__.py new file mode 100644 index 0000000..1c72469 --- /dev/null +++ b/src/mail_order_bot/email_processor/__init__.py @@ -0,0 +1 @@ +from .processor import EmailProcessor \ No newline at end of file diff --git a/src/mail_order_bot/email_handler/handlers/__init__.py b/src/mail_order_bot/email_processor/handlers/__init__.py similarity index 100% rename from src/mail_order_bot/email_handler/handlers/__init__.py rename to src/mail_order_bot/email_processor/handlers/__init__.py diff --git a/src/mail_order_bot/email_handler/handlers/abcp_clients/check_stock.py b/src/mail_order_bot/email_processor/handlers/abcp_clients/check_stock.py similarity index 88% rename from src/mail_order_bot/email_handler/handlers/abcp_clients/check_stock.py rename to src/mail_order_bot/email_processor/handlers/abcp_clients/check_stock.py index 69475ed..07bef4d 100644 --- a/src/mail_order_bot/email_handler/handlers/abcp_clients/check_stock.py +++ b/src/mail_order_bot/email_processor/handlers/abcp_clients/check_stock.py @@ -1,7 +1,7 @@ import random import logging -from mail_order_bot.email_handler.handlers.abstract_task import AbstractTask +from mail_order_bot.email_processor.handlers.abstract_task import AbstractTask logger = logging.getLogger(__name__) diff --git a/src/mail_order_bot/email_handler/handlers/abcp_clients/create_order.py b/src/mail_order_bot/email_processor/handlers/abcp_clients/create_order.py similarity index 89% rename from src/mail_order_bot/email_handler/handlers/abcp_clients/create_order.py rename to src/mail_order_bot/email_processor/handlers/abcp_clients/create_order.py index 945484d..14192e5 100644 --- a/src/mail_order_bot/email_handler/handlers/abcp_clients/create_order.py +++ b/src/mail_order_bot/email_processor/handlers/abcp_clients/create_order.py @@ -1,7 +1,7 @@ import logging import requests -from mail_order_bot.email_handler.handlers.abstract_task import AbstractTask -from mail_order_bot.email_handler.order.auto_part_order import OrderStatus +from mail_order_bot.email_processor.handlers.abstract_task import AbstractTask +from mail_order_bot.email_processor.order.auto_part_order import OrderStatus logger = logging.getLogger(__name__) diff --git a/src/mail_order_bot/email_handler/handlers/abstract_task.py b/src/mail_order_bot/email_processor/handlers/abstract_task.py similarity index 92% rename from src/mail_order_bot/email_handler/handlers/abstract_task.py rename to src/mail_order_bot/email_processor/handlers/abstract_task.py index 0ddd22b..a7760bb 100644 --- a/src/mail_order_bot/email_handler/handlers/abstract_task.py +++ b/src/mail_order_bot/email_processor/handlers/abstract_task.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import Dict, Any -from mail_order_bot.email_handler.context import Context +from mail_order_bot.context import Context class AbstractTask(ABC, Context): diff --git a/src/mail_order_bot/email_handler/handlers/email/send_email.py b/src/mail_order_bot/email_processor/handlers/email/send_email.py similarity index 100% rename from src/mail_order_bot/email_handler/handlers/email/send_email.py rename to src/mail_order_bot/email_processor/handlers/email/send_email.py diff --git a/src/mail_order_bot/email_handler/handlers/excel_parcers/order_parcer_basic.py b/src/mail_order_bot/email_processor/handlers/excel_parcers/order_parcer_basic.py similarity index 96% rename from src/mail_order_bot/email_handler/handlers/excel_parcers/order_parcer_basic.py rename to src/mail_order_bot/email_processor/handlers/excel_parcers/order_parcer_basic.py index c6f1548..41d78ea 100644 --- a/src/mail_order_bot/email_handler/handlers/excel_parcers/order_parcer_basic.py +++ b/src/mail_order_bot/email_processor/handlers/excel_parcers/order_parcer_basic.py @@ -3,8 +3,8 @@ import pandas as pd from typing import Dict, Any, Optional from decimal import Decimal from io import BytesIO -#from mail_order_bot.email_handler.handlers.order_position import OrderPosition -from mail_order_bot.email_handler.handlers.abstract_task import AbstractTask +#from mail_order_bot.email_processor.handlers.order_position import OrderPosition +from mail_order_bot.email_processor.handlers.abstract_task import AbstractTask from ...order.auto_part_position import AutoPartPosition diff --git a/src/mail_order_bot/email_handler/handlers/excel_parcers/sheet_parcer.py b/src/mail_order_bot/email_processor/handlers/excel_parcers/sheet_parcer.py similarity index 96% rename from src/mail_order_bot/email_handler/handlers/excel_parcers/sheet_parcer.py rename to src/mail_order_bot/email_processor/handlers/excel_parcers/sheet_parcer.py index c6f1548..41d78ea 100644 --- a/src/mail_order_bot/email_handler/handlers/excel_parcers/sheet_parcer.py +++ b/src/mail_order_bot/email_processor/handlers/excel_parcers/sheet_parcer.py @@ -3,8 +3,8 @@ import pandas as pd from typing import Dict, Any, Optional from decimal import Decimal from io import BytesIO -#from mail_order_bot.email_handler.handlers.order_position import OrderPosition -from mail_order_bot.email_handler.handlers.abstract_task import AbstractTask +#from mail_order_bot.email_processor.handlers.order_position import OrderPosition +from mail_order_bot.email_processor.handlers.abstract_task import AbstractTask from ...order.auto_part_position import AutoPartPosition diff --git a/src/mail_order_bot/email_handler/handlers/notifications/test_notifier.py b/src/mail_order_bot/email_processor/handlers/notifications/test_notifier.py similarity index 84% rename from src/mail_order_bot/email_handler/handlers/notifications/test_notifier.py rename to src/mail_order_bot/email_processor/handlers/notifications/test_notifier.py index 9c47674..151b6b9 100644 --- a/src/mail_order_bot/email_handler/handlers/notifications/test_notifier.py +++ b/src/mail_order_bot/email_processor/handlers/notifications/test_notifier.py @@ -1,6 +1,6 @@ import logging -from mail_order_bot.email_handler.handlers.abstract_task import AbstractTask +from mail_order_bot.email_processor.handlers.abstract_task import AbstractTask logger = logging.getLogger(__name__) diff --git a/src/mail_order_bot/email_handler/handlers/validators/price_quantity_ckecker.py b/src/mail_order_bot/email_processor/handlers/validators/price_quantity_ckecker.py similarity index 91% rename from src/mail_order_bot/email_handler/handlers/validators/price_quantity_ckecker.py rename to src/mail_order_bot/email_processor/handlers/validators/price_quantity_ckecker.py index 67377f3..9417ff9 100644 --- a/src/mail_order_bot/email_handler/handlers/validators/price_quantity_ckecker.py +++ b/src/mail_order_bot/email_processor/handlers/validators/price_quantity_ckecker.py @@ -1,7 +1,7 @@ import random import logging -from mail_order_bot.email_handler.handlers.abstract_task import AbstractTask -from mail_order_bot.email_handler.order.auto_part_order import OrderStatus +from mail_order_bot.email_processor.handlers.abstract_task import AbstractTask +from mail_order_bot.email_processor.order.auto_part_order import OrderStatus from decimal import Decimal import random logger = logging.getLogger(__name__) diff --git a/src/mail_order_bot/email_handler/order/__init__.py b/src/mail_order_bot/email_processor/order/__init__.py similarity index 100% rename from src/mail_order_bot/email_handler/order/__init__.py rename to src/mail_order_bot/email_processor/order/__init__.py diff --git a/src/mail_order_bot/email_handler/order/auto_part_order.py b/src/mail_order_bot/email_processor/order/auto_part_order.py similarity index 100% rename from src/mail_order_bot/email_handler/order/auto_part_order.py rename to src/mail_order_bot/email_processor/order/auto_part_order.py diff --git a/src/mail_order_bot/email_handler/order/auto_part_position.py b/src/mail_order_bot/email_processor/order/auto_part_position.py similarity index 100% rename from src/mail_order_bot/email_handler/order/auto_part_position.py rename to src/mail_order_bot/email_processor/order/auto_part_position.py diff --git a/src/mail_order_bot/email_handler/email_processor.py b/src/mail_order_bot/email_processor/processor.py similarity index 67% rename from src/mail_order_bot/email_handler/email_processor.py rename to src/mail_order_bot/email_processor/processor.py index cb5cb2c..a843925 100644 --- a/src/mail_order_bot/email_handler/email_processor.py +++ b/src/mail_order_bot/email_processor/processor.py @@ -6,12 +6,9 @@ from pathlib import Path logger = logging.getLogger(__name__) -from .order.auto_part_order import AutoPartOrder -from .context import Context +from mail_order_bot.context import Context from enum import Enum -from .handlers import * - class RequestStatus(Enum): NEW = "new" @@ -28,10 +25,20 @@ class EmailProcessor(Context): self.configs_path = configs_path self.status = RequestStatus.NEW + def process_email(self, email): + # Очистить контекст + self.context.clear() - def process(self, email_id): - config = self._load_config(client) + # Сохранить письмо в контекст + self.context["email"] = email + # Определить клиента + + + # Определить конфиг для пайплайна + config = {} + + # Запустить обработку пайплайна for stage in config["pipeline"]: handler_name = stage["handler"] logger.info(f"Processing handler: {handler_name}") @@ -42,6 +49,4 @@ class EmailProcessor(Context): """Загружает конфигурацию из YAML или JSON""" path = os.path.join(self.configs_path, client + '.yml') with open(path, 'r', encoding='utf-8') as f: - return yaml.safe_load(f) - - def _load_email(self): + return yaml.safe_load(f) \ No newline at end of file diff --git a/src/mail_order_bot/excel_processor/__init__.py b/src/mail_order_bot/excel_parcer/__init__.py similarity index 100% rename from src/mail_order_bot/excel_processor/__init__.py rename to src/mail_order_bot/excel_parcer/__init__.py diff --git a/src/mail_order_bot/excel_processor/configurable_parser.py b/src/mail_order_bot/excel_parcer/configurable_parser.py similarity index 100% rename from src/mail_order_bot/excel_processor/configurable_parser.py rename to src/mail_order_bot/excel_parcer/configurable_parser.py diff --git a/src/mail_order_bot/excel_processor/custom_parser_autoeuro.py b/src/mail_order_bot/excel_parcer/custom_parser_autoeuro.py similarity index 100% rename from src/mail_order_bot/excel_processor/custom_parser_autoeuro.py rename to src/mail_order_bot/excel_parcer/custom_parser_autoeuro.py diff --git a/src/mail_order_bot/excel_processor/excel_parser.py b/src/mail_order_bot/excel_parcer/excel_parser.py similarity index 100% rename from src/mail_order_bot/excel_processor/excel_parser.py rename to src/mail_order_bot/excel_parcer/excel_parser.py diff --git a/src/mail_order_bot/excel_processor/order_position.py b/src/mail_order_bot/excel_parcer/order_position.py similarity index 100% rename from src/mail_order_bot/excel_processor/order_position.py rename to src/mail_order_bot/excel_parcer/order_position.py diff --git a/src/mail_order_bot/excel_processor/parser_factory.py b/src/mail_order_bot/excel_parcer/parser_factory.py similarity index 100% rename from src/mail_order_bot/excel_processor/parser_factory.py rename to src/mail_order_bot/excel_parcer/parser_factory.py diff --git a/src/mail_order_bot/excel_processor/processor.py b/src/mail_order_bot/excel_parcer/processor.py similarity index 100% rename from src/mail_order_bot/excel_processor/processor.py rename to src/mail_order_bot/excel_parcer/processor.py diff --git a/src/mail_order_bot/main.py b/src/mail_order_bot/main.py index 9e70ceb..e6a3eef 100644 --- a/src/mail_order_bot/main.py +++ b/src/mail_order_bot/main.py @@ -7,39 +7,49 @@ import os from dotenv import load_dotenv from email_client import EmailClient -from excel_proceccor import ExcelProcessor +from email_processor import EmailProcessor + +from context import Context logger = logging.getLogger() - class MailOrderBot(ConfigManager): def __init__(self, *agrs, **kwargs): super().__init__(*agrs, **kwargs) + + # Объявить почтового клиента self.email_client = EmailClient( imap_host=os.getenv('IMAP_HOST'), smtp_host=os.getenv('SMTP_HOST'), email=os.getenv('EMAIL_USER'), password=os.getenv('EMAIL_PASSWORD'), - imap_port=os.getenv('IMAP_PORT'), - smtp_port=os.getenv('SMTP_PORT') + imap_port=int(os.getenv('IMAP_PORT', default="993")), + smtp_port=int(os.getenv('SMTP_PORT', default="587")), ) + # Сохранить почтовый клиент в контекст + self.context = Context() + self.context.email_client = self.email_client + + # Обработчик писем + self.email_processor = EmailProcessor() + def execute(self): logger.debug(f"Check emails for new orders") - emails = self.email_client.get_emails(folder="spareparts", only_unseen=True, mark_as_read=True) + # Получить список айдишников письма + unread_email_ids = self.email_client.get_emails_id(folder="spareparts") + logger.info(f"Новых писем - {len(unread_email_ids)}") - for email in emails: - logger.info(email.subj) - logger.info(email.from_addr) - logger.info(email.dt) - logger.info(email.body) - logger.info(email.first_sender) - logger.info('--------------------------------') - logger.critical("mail checked") + # Обработать каждое письмо по идентификатору + for email_id in unread_email_ids: + logger.debug(f"Обработка письма с идентификатором {email_id}") + # Получить письмо по идентификатору и запустить его обработку + email = self.email_client.get_email(email_id) + self.email_processor.process_email(email) logger = logging.getLogger() diff --git a/tests/abcp_api/test_abcp_api.py b/tests/abcp_api/test_abcp_api.py index 6dd900b..376012c 100644 --- a/tests/abcp_api/test_abcp_api.py +++ b/tests/abcp_api/test_abcp_api.py @@ -1,8 +1,8 @@ import os from dotenv import load_dotenv from mail_order_bot.abcp_api.abcp_provider import AbcpProvider -from mail_order_bot.email_handler.order.auto_part_order import AutoPartOrder -from mail_order_bot.email_handler.order.auto_part_position import AutoPartPosition +from mail_order_bot.email_processor.order.auto_part_order import AutoPartOrder +from mail_order_bot.email_processor.order.auto_part_position import AutoPartPosition if __name__ == "__main__": print(__name__)# подгружаем переменные окружения load_dotenv() diff --git a/tests/excel_processor/hanler_test.py b/tests/excel_processor/hanler_test.py index ca7099d..049f97b 100644 --- a/tests/excel_processor/hanler_test.py +++ b/tests/excel_processor/hanler_test.py @@ -1,7 +1,7 @@ import os import chardet # pip install chardet import traceback -from mail_order_bot.email_handler import EmailProcessor +from mail_order_bot.email_processor import EmailProcessor import datetime # установим рабочую директорию import os diff --git a/tests/excel_processor/processor_test.py b/tests/excel_processor/processor_test.py index dd74ea0..f8a7d2b 100644 --- a/tests/excel_processor/processor_test.py +++ b/tests/excel_processor/processor_test.py @@ -1,7 +1,7 @@ import os import chardet # pip install chardet import traceback -from mail_order_bot.excel_processor import ExcelProcessor +from mail_order_bot.excel_parcer import ExcelProcessor # установим рабочую директорию import os