/
Andrey_Che
/
diplom
Обзор
Документация
Войти
/
Andrey_Che
/
diplom
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
programma.py
164 строки
7 KB
Andrey_Che
Create: programma.py
08 авг 2026, 20:59
Верифицирован
08 авг 2026, 20:59
a21c1f4
Код
Авторство
О чём код?
import os import smtplib from email.message import EmailMessage from pathlib import Path import pandas as pd # --- НАСТРОЙКИ --- EXCEL_PATH = r"C:\Конкурс\таблица участников конкурса.xlsx" DIPLOMAS_DIR = r"C:\Конкурс\Дипломы" SMTP_SERVER = "smtp.example.com" # Например: smtp.gmail.com SMTP_PORT = 587 # Обычно 587 (TLS) или 465 (SSL) EMAIL_ADDRESS = "MAVROSCHE@yandex.ru" EMAIL_PASSWORD = "RQj-8cT-vvt-9WQ" FROM_NAME = "Организационный комитет" def load_participants_data(excel_path): """Загружает таблицу участников.""" try: df = pd.read_excel(excel_path, engine='openpyxl') required_cols = {'номер участника', 'ФИО', 'email'} if not required_cols.issubset(df.columns.str.lower()): raise ValueError(f"В таблице должны быть столбцы: {required_cols}") # Приводим названия колонок к нижнему регистру для удобства df.columns = [col.strip().lower() for col in df.columns] return df except Exception as e: print(f"Ошибка при чтении файла Excel: {e}") return None def find_diploma_file(diplomas_dir, participant_number): """Ищет файл диплома по номеру участника.""" p = Path(diplomas_dir) # Ищем файлы вида "1.pdf", "01.pdf", "1.PDF" и т.д. pattern_variants = [ f"{participant_number}.pdf", f"{int(participant_number)}.pdf", # если в экселе число, а не строка f"{str(int(participant_number))}.pdf" # убираем ведущие нули для поиска ] for file in p.glob("*.pdf"): if file.name.lower() in [v.lower() for v in pattern_variants]: return str(file) # Дополнительная проверка: ищем просто по началу имени (на случай лишних нулей в именах файлов) target_name = f"{int(participant_number)}.pdf" for file in p.glob("*.pdf"): if file.stem.lstrip('0') == str(int(participant_number)): return str(file) return None def send_email(to_address, to_name, subject, body_text, attachment_path): """Формирует и отправляет письмо.""" msg = EmailMessage() msg["Subject"] = subject msg["From"] = f"{FROM_NAME} <{EMAIL_ADDRESS}>" msg["To"] = to_address # Текст письма full_body = f"{body_text},\n\nПоздравляем вас с успешным участием!\nС уважением,\nОрганизационный комитет" msg.set_content(full_body) # Прикрепление файла try: with open(attachment_path, "rb") as f: file_data = f.read() file_name = os.path.basename(attachment_path) msg.add_attachment(file_data, maintype="application", subtype="pdf", filename=file_name) except FileNotFoundError: raise RuntimeError(f"Файл диплома не найден: {attachment_path}") # Отправка через SMTP with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server: server.starttls() # Шифрование соединения server.login(EMAIL_ADDRESS, EMAIL_PASSWORD) server.send_message(msg) def main(): participants_df = load_participants_data(EXCEL_PATH) if participants_df is None: return total_sent = 0 failed_emails = [] missing_files = [] # Настраиваем соединение один раз для всей рассылки (оптимизация) try: smtp_conn = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) smtp_conn.starttls() smtp_conn.login(EMAIL_ADDRESS, EMAIL_PASSWORD) except Exception as e: print(f"Критическая ошибка: не удалось подключиться к почтовому серверу ({e}). Рассылка невозможна.") return print("Начинается рассылка...") for index, row in participants_df.iterrows(): part_num = str(row['номер участника']).strip() fio = str(row['фио']).strip() email_addr = str(row['email']).strip() diploma_path = find_diploma_file(DIPLOMAS_DIR, part_num) if not diploma_path: print(f"[ПРОПУСК] Для участника №{part_num} ({fio}) не найден файл диплома.") missing_files.append({"number": part_num, "name": fio, "email": email_addr}) continue subject = f"Диплом участника конкурса - {fio}" body = f"Диплом участника конкурса {fio}" try: # Используем уже открытое соединение msg = EmailMessage() msg["Subject"] = subject msg["From"] = f"{FROM_NAME} <{EMAIL_ADDRESS}>" msg["To"] = email_addr msg.set_content(body + ",\n\nПоздравляем вас с успешным участием!\n\nС уважением,\nОрганизационный комитет") with open(diploma_path, "rb") as f: msg.add_attachment(f.read(), maintype="application", subtype="pdf", filename=os.path.basename(diploma_path)) smtp_conn.send_message(msg) print(f"[ОТПРАВЛЕНО] Участнику №{part_num} ({fio}) на почту {email_addr}") total_sent += 1 except Exception as e: err_msg = f"Ошибка отправки участнику №{part_num} ({fio}) на почту {email_addr}: {e}" print(err_msg) failed_emails.append({"number": part_num, "name": fio, "email": email_addr, "error": str(e)}) finally: # Небольшая пауза, чтобы почтовые сервисы не приняли нас за спам-бота import time time.sleep(1) # Закрываем соединение try: smtp_conn.quit() except: pass # --- ОТЧЁТ --- print("\n--- РАССЫЛКА ЗАВЕРШЕНА ---") print(f"Всего обработано записей: {len(participants_df)}") print(f"Успешно отправлено писем: {total_sent}") print(f"Пропущено из-за отсутствия файлов: {len(missing_files)}") print(f"Не удалось отправить (ошибки почты): {len(failed_emails)}") if failed_emails: print("\nСписок адресов, куда не удалось доставить письмо:") for fail in failed_emails: print(f"- Участник №{fail['number']} ({fail['name']}), Почта: {fail['email']}, Ошибка: {fail['error']}") if missing_files: print("\nСписок участников, для которых не найдены файлы дипломов:") for miss in missing_files: print(f"- Номер: {miss['number']}, ФИО: {miss['name']}, Почта: {miss['email']}") if __name__ == "__main__": main()