import os
import sys
import time

import cv2
import numpy as np

from PySide6.QtCore import Qt, QThread, Signal, Slot
from PySide6.QtGui import QAction, QImage, QKeySequence, QPixmap, QFont
from PySide6.QtWidgets import (QApplication, QComboBox, QGroupBox,
                               QHBoxLayout, QLabel, QMainWindow, QPushButton,
                               QSizePolicy, QVBoxLayout, QWidget, QMessageBox, QProgressBar,
                               QGridLayout, QStatusBar)

from uithread.displayThread import DisplayThread

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Expression flag
        # 0-6 indicates:0)Natural 1)Angry 2)Disgust 3)Fear 4)Happy 5)Sad 6)Surprise
        self.emoFlag = 0

        # Title and dimensions
        self.setWindowTitle("FER System")
        self.setGeometry(300, 300, 1200, 550)

        self.dis_w = int(1920 / 4)
        self.dis_h = int(1080 / 4)

        # Menu widgets setup
        self.menu = None
        self.menu_file = None
        self.act_exit = None
        self.menu_edit = None
        self.act_dummy = None
        self.menu_help = None
        self.act_require = None
        self.act_about = None

        # mode flag
        self.use_rgb = False
        self.use_rgbd = False

        # Progress bar
        self.progress_na = QProgressBar()
        self.progress_an = QProgressBar()
        self.progress_di = QProgressBar()
        self.progress_fe = QProgressBar()
        self.progress_ha = QProgressBar()
        self.progress_sa = QProgressBar()
        self.progress_su = QProgressBar()

        self.setupMenuBar()

        # Central widgets group

        # FER results area
        self.icon_default = QImage("./resource/icon_default.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_natural = QImage("./resource/icon_natural.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_angry = QImage("./resource/icon_angry.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_disgust = QImage("./resource/icon_disgust.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_fear = QImage("./resource/icon_fear.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_happy = QImage("./resource/icon_happy.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_sad = QImage("./resource/icon_sad.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)
        self.icon_surprise = QImage("./resource/icon_surprise.png").scaled(256 / 2, 256 / 2, mode=Qt.SmoothTransformation)

        self.setupCentralWidgets()

        # Main status bar
        self.setupStatusBar()

        # 2D 3D video displaying thread
        self.dis_thread = DisplayThread(face_detect=True, fer_detect=True)
        self.dis_thread.exit(self.close())
        self.dis_thread.updateFrameSignal.connect(self.updateFrame)
        self.dis_thread.threadQMessageBoxSignal.connect(self.setQMessageBoxSlot)
        self.dis_thread.threadStatusBarSignal.connect(self.setStatusBarSlot)
        self.dis_thread.logitsSignal.connect(self.setProgressBar)
        self.dis_thread.logitsSignal.connect(self.setFERIcon)

        # Connections
        self.act_dummy.triggered.connect(self.dummySlot)
        self.act_require.triggered.connect(self.showRequireSlot)
        self.act_about.triggered.connect(self.showAboutSlot)

        self.apply_2d_set_button.clicked.connect(self.applyTexDisSet)
        self.combo_2d_face_methods.currentTextChanged.connect(self.setFaceDetectModel)

        self.RGBD_button.clicked.connect(self.applyRGBDSet)

        self.start_button.clicked.connect(self.start)
        self.stop_button.clicked.connect(self.kill_thread)

        self.stop_button.setEnabled(False)

    def setupMenuBar(self):
        """ Setup the display layout for menu bar.
        """

        self.menu = self.menuBar()

        # File menu
        self.menu_file = self.menu.addMenu("File")
        self.act_exit = QAction("Exit", self, triggered=qApp.quit, shortcut=QKeySequence("Q"))
        self.menu_file.addAction(self.act_exit)

        # Edit menu
        self.menu_edit = self.menu.addMenu("Edit")

        self.act_dummy = QAction("EditDummy", self)
        self.menu_edit.addAction(self.act_dummy)

        # Help menu
        self.menu_help = self.menu.addMenu("Help")

        self.act_require = QAction("Requirements", self)
        self.menu_help.addAction(self.act_require)

        self.act_about = QAction("About", self)
        self.menu_help.addAction(self.act_about)

    def setupCentralWidgets(self):
        """ Setup the display layout for central widgets.
        """

        # ==> Step 1. Create local widgets

        # 1)Software main title widgets
        self.title = QLabel()
        self.title.setText("Multi-Modality Facial Expression Recognition System")
        self.title.setAlignment(Qt.AlignCenter)

        # 2) widgets for 2D texture stream
        self.title_2d = QLabel()  # 2D title
        self.title_2d.setText("Texture Stream")
        self.title_2d.setAlignment(Qt.AlignCenter)

        self.display_2d = QLabel()  # 2D display
        self.display_2d.setFixedSize(self.dis_w, self.dis_h)

        face_img = QImage("./resource/camera2d.png").scaled(self.dis_w, self.dis_h, mode=Qt.SmoothTransformation)
        self.display_2d.setPixmap(QPixmap.fromImage(face_img))

        # 2D Display settings
        layout_2d_display_settings = QHBoxLayout()

        # Add 2D camera setting
        layout_2d_display_settings.addSpacing(10)
        layout_2d_display_settings.addWidget(QLabel("Camera Id."))
        self.combo_2d_cam_id = QComboBox()
        camids = ["0", "1", "2", "3", "4", "5"]
        for camid in camids:
            self.combo_2d_cam_id.addItem(camid)

        self.combo_2d_cam_id.setCurrentIndex(2)
        layout_2d_display_settings.addWidget(self.combo_2d_cam_id)
        layout_2d_display_settings.addSpacing(30)

        # Add resolution-selection
        layout_2d_display_settings.addWidget(QLabel("Resolution"))
        self.combo_2d_reso = QComboBox()
        resos = ["240 x 320", "480 x 640", "480 x 720 (DV)", "720 x 1280 (720p)", "1080 x 1920 (1080p)"]
        for reso in resos:
            self.combo_2d_reso.addItem(reso)

        self.combo_2d_reso.setCurrentIndex(1)  # 480 x 640 as default

        layout_2d_display_settings.addWidget(self.combo_2d_reso)

        self.apply_2d_set_button = QPushButton("Apply RGB")

        layout_2d_display_settings.addSpacing(26)
        layout_2d_display_settings.addWidget(self.apply_2d_set_button)

        layout_2d_display_settings.addStretch()
        # layout_2d_display_settings.addSpacing(100)

        # 2D methods box
        self.methods_2d_widget = QGroupBox("Choose 2D Methods")  # 2D methods groupBox
        self.methods_2d_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)

        layout_2d_methods = QVBoxLayout()

        # Face detection
        layout_2d_face_methods = QHBoxLayout()
        self.combo_2d_face_methods = QComboBox()
        methods_2d_face = os.listdir(cv2.data.haarcascades)
        for method in methods_2d_face:
            if method.endswith(".xml"):
                self.combo_2d_face_methods.addItem(method)

        self.combo_2d_face_methods.setCurrentText("haarcascade_frontalface_alt2.xml")
        layout_2d_face_methods.addWidget(QLabel("Face Detection"), 10)
        layout_2d_face_methods.addWidget(self.combo_2d_face_methods, 90)

        # 2D FER Nets
        layout_2d_fer_methods = QHBoxLayout()
        self.combo_2d_fer_methods = QComboBox()
        methods_2d_fer = ['None', 'LeNet', 'VGG', 'ResNet', 'ViT', 'FA-CNN']
        for method in methods_2d_fer:
            self.combo_2d_fer_methods.addItem(method)

        self.combo_2d_fer_methods.setCurrentIndex(2)  # default VGG

        layout_2d_fer_methods.addWidget(QLabel("2D FER Nets "), 10)
        layout_2d_fer_methods.addWidget(self.combo_2d_fer_methods, 90)

        layout_2d_methods.addLayout(layout_2d_face_methods)
        layout_2d_methods.addLayout(layout_2d_fer_methods)

        self.methods_2d_widget.setLayout(layout_2d_methods)

        self.texture_module_layout = QGridLayout()
        self.texture_module_layout.addWidget(self.title_2d, 0, 0, 2, 10)
        self.texture_module_layout.addWidget(self.display_2d, 2, 0, 3, 10)
        self.texture_module_layout.addLayout(layout_2d_display_settings, 5, 0, 1, 10)
        self.texture_module_layout.addWidget(self.methods_2d_widget, 6, 0, 1, 10)

        # 3) widgets for 3D depth stream
        self.title_3d = QLabel()  # 3D title
        self.title_3d.setText("Depth Stream")
        self.title_3d.setAlignment(Qt.AlignCenter)

        self.display_3d = QLabel()  # 3D display
        self.display_3d.setFixedSize(self.dis_w, self.dis_h)

        face_img = QImage("./resource/camera3d.png").scaled(self.dis_w, self.dis_h, mode=Qt.SmoothTransformation)
        self.display_3d.setPixmap(QPixmap.fromImage(face_img))

        # 3D settings
        layout_3d_display_settings = QHBoxLayout()

        # RGB-D camera
        self.RGBD_button = QPushButton("Apply RGB-D")
        layout_3d_display_settings.addWidget(self.RGBD_button)

        # 3D methods box
        self.methods_3d_widget = QGroupBox("Choose 3D Methods")  # 2D methods groupBox
        self.methods_3d_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)

        layout_3d_methods = QVBoxLayout()

        # 3D enhancement methods
        layout_3d_enh_methods = QHBoxLayout()
        self.combo_3d_enh_methods = QComboBox()
        methods_3d_enh = ['Log', 'HE', 'GEMax']
        for method in methods_3d_enh:
            self.combo_3d_enh_methods.addItem(method)

        layout_3d_enh_methods.addWidget(QLabel("Enhancement"), 10)
        layout_3d_enh_methods.addWidget(self.combo_3d_enh_methods, 90)

        # 3D FER Nets
        layout_3d_fer_methods = QHBoxLayout()
        self.combo_3d_fer_methods = QComboBox()
        methods_3d_fer = ['None', 'LeNet', 'VGG', 'ResNet', 'ViT', 'FA-CNN3D']
        for method in methods_3d_fer:
            self.combo_3d_fer_methods.addItem(method)

        self.combo_3d_fer_methods.setCurrentIndex(2)  # default VGG

        layout_3d_fer_methods.addWidget(QLabel("3D FER Nets "), 10)
        layout_3d_fer_methods.addWidget(self.combo_3d_fer_methods, 90)

        layout_3d_methods.addLayout(layout_3d_enh_methods)
        layout_3d_methods.addLayout(layout_3d_fer_methods)

        self.methods_3d_widget.setLayout(layout_3d_methods)

        depth_module_layout = QGridLayout()
        depth_module_layout.addWidget(self.title_3d, 0, 0, 2, 10)
        depth_module_layout.addWidget(self.display_3d, 2, 0, 3, 10)
        depth_module_layout.addLayout(layout_3d_display_settings, 5, 0, 1, 10)
        depth_module_layout.addWidget(self.methods_3d_widget, 6, 0, 1, 10)

        # 4) Result widgets
        # - i) result title
        self.title_res = QLabel()
        self.title_res.setText("Predicted Expression")
        self.title_res.setAlignment(Qt.AlignCenter)

        # - ii) display result image
        self.display_res = QLabel()
        self.display_res.setFixedSize(256/2, 256/2)

        self.display_res.setPixmap(QPixmap.fromImage(self.icon_default))
        self.display_res.setAlignment(Qt.AlignCenter)

        # - iii) class name and probability bar
        name_na = QLabel("Nature")
        name_an = QLabel("Angry")
        name_di = QLabel("Disgust")
        name_fe = QLabel("Fear")
        name_ha = QLabel("Happy")
        name_sa = QLabel("Sad")
        name_su = QLabel("Surprise")

        self.progress_na.setFixedWidth(196)
        self.progress_an.setFixedWidth(196)
        self.progress_di.setFixedWidth(196)
        self.progress_fe.setFixedWidth(196)
        self.progress_ha.setFixedWidth(196)
        self.progress_sa.setFixedWidth(196)
        self.progress_su.setFixedWidth(196)

        # - iv) predicted results layout
        self.res_group = QGroupBox("FER Probability Bar")
        res_layout = QGridLayout()

        res_layout.addWidget(name_na, 0, 0, 1, 1)
        res_layout.addWidget(name_an, 1, 0, 1, 1)
        res_layout.addWidget(name_di, 2, 0, 1, 1)
        res_layout.addWidget(name_fe, 3, 0, 1, 1)
        res_layout.addWidget(name_ha, 4, 0, 1, 1)
        res_layout.addWidget(name_sa, 5, 0, 1, 1)
        res_layout.addWidget(name_su, 6, 0, 1, 1)

        res_layout.addWidget(self.progress_na, 0, 2, 1, 9)
        res_layout.addWidget(self.progress_an, 1, 2, 1, 9)
        res_layout.addWidget(self.progress_di, 2, 2, 1, 9)
        res_layout.addWidget(self.progress_fe, 3, 2, 1, 9)
        res_layout.addWidget(self.progress_ha, 4, 2, 1, 9)
        res_layout.addWidget(self.progress_sa, 5, 2, 1, 9)
        res_layout.addWidget(self.progress_su, 6, 2, 1, 9)

        self.res_group.setLayout(res_layout)

        # 7) Start/Stop button
        self.group_buttons = QWidget()

        button_layout = QHBoxLayout()
        self.start_button = QPushButton("Start")
        self.stop_button = QPushButton("Stop")

        self.start_button.setFixedWidth(150)

        self.start_button.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        self.stop_button.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        button_layout.addWidget(self.start_button)
        button_layout.addWidget(self.stop_button)

        self.group_buttons.setLayout(button_layout)

        # ==> Step 2. Setup main layout and central widget
        res_control_layout = QGridLayout()
        res_control_layout.addWidget(self.title_res, 0, 0, 1, 10)
        res_control_layout.addWidget(self.display_res, 1, 2, 1, 10)
        res_control_layout.addWidget(self.res_group, 2, 0, 1, 10)
        res_control_layout.addWidget(self.group_buttons, 3, 0, 1, 10)

        main_layout = QHBoxLayout()
        main_layout.addLayout(self.texture_module_layout)
        main_layout.addLayout(depth_module_layout)
        main_layout.addLayout(res_control_layout)

        central_layout = QVBoxLayout()
        central_layout.addWidget(self.title)
        central_layout.addLayout(main_layout)

        central_widget = QWidget(self)
        central_widget.setLayout(central_layout)
        self.setCentralWidget(central_widget)

        # ==> Step 3. Apply functions
        # Thread in charge of updating the 2D image
        # self.thread2D = Thread(self)  # need to implement
        # Thread in charge of updating the 3D image
        # self.thread3D = Thread(self)  # need to implement

        pass

    def setupStatusBar(self):
        """ Setup the display layout for status bar.
        """
        status_bar = QStatusBar(self)
        self.setStatusBar(status_bar)

        self.statusBar().showMessage("Read to go ...")

        return

    @Slot()
    def setFERIcon(self, logits):
        """ Set FER result icon.
        """
        expression = np.argmax(logits)
        expression_image = None
        if expression == 0:
            expression_image = QPixmap.fromImage(self.icon_natural)
        elif expression == 1:
            expression_image = QPixmap.fromImage(self.icon_angry)
        elif expression == 2:
            expression_image = QPixmap.fromImage(self.icon_disgust)
        elif expression == 3:
            expression_image = QPixmap.fromImage(self.icon_fear)
        elif expression == 4:
            expression_image = QPixmap.fromImage(self.icon_happy)
        elif expression == 5:
            expression_image = QPixmap.fromImage(self.icon_sad)
        elif expression == 6:
            expression_image = QPixmap.fromImage(self.icon_surprise)
        else:
            raise Exception("Error max logits.")

        self.display_res.setPixmap(expression_image)
        return

    @Slot()
    def setProgressBar(self, logits):
        """ Set progress bar, set the FER logits value.
        """

        self.progress_na.setValue(logits[0]*100)
        self.progress_an.setValue(logits[1]*100)
        self.progress_di.setValue(logits[2]*100)
        self.progress_fe.setValue(logits[3]*100)
        self.progress_ha.setValue(logits[4]*100)
        self.progress_sa.setValue(logits[5]*100)
        self.progress_su.setValue(logits[6]*100)
        return

    def resetProgressBar(self):
        """ Reset progress bar, clear the FER logits value.
        """

        self.progress_na.reset()
        self.progress_an.reset()
        self.progress_di.reset()
        self.progress_fe.reset()
        self.progress_ha.reset()
        self.progress_sa.reset()
        self.progress_su.reset()

        expression_image = QPixmap.fromImage(self.icon_default)
        self.display_res.setPixmap(expression_image)
        return

    @Slot()
    def dummySlot(self):
        QMessageBox.about(self,
                          "Dummy Slot",
                          "This is a dummy Slot function. Implement it in the future.")

    @Slot()
    def showRequireSlot(self):
        QMessageBox.about(self,
                          "Developing Environment",
                          "Packages:\n"
                          "- Python >= 3.6\n"
                          "- numpy >= 1.19.5\n"
                          "- Opencv-python >= 4.5\n"
                          "- PySide6 >= 6.2.1\n"
                          "- PyTorch >= 1.10\n"
                          "- TorchVision >= 0.11\n\n"
                          "Hardware:\n"
                          "1) usb camera\n"
                          "2) Intel RealSense (optional for depth imaging)\n"
                          "3) NV GPU (optional, CPU version also works)\n"
                          )

    @Slot()
    def showAboutSlot(self):
        dev_info = "Software for Multimodality 2D+3D Facial Expression Recognition (FER). \n\nDeveloper: Yang Jiao \nEmail: yjiao.xdu@gmail.com \nXidian University \nJohns Hopkins University"
        ack_info = "Free to anyone. No commercial purpose."
        license_info = "GPL License."
        QMessageBox.about(self,
                          "Acknowledgement",
                          dev_info+"\n\n"+ack_info+"\n\n"+license_info
                          )

    @Slot()
    def setFaceDetectModel(self, method):
        self.dis_thread.set_file(method)
        return

    @Slot()
    def start(self):
        """ Start a uithread for displaying camera video.
        """

        self.statusBar().showMessage("Starting FER ...")
        self.start_button.setEnabled(False)
        self.stop_button.setEnabled(True)

        if not self.use_rgb and not self.use_rgbd:
            self.applyTexDisSet()
            self.dis_thread.set_2d_methods(self.combo_2d_face_methods.currentText(),
                                           self.combo_2d_fer_methods.currentText())

        self.dis_thread.set_mode(self.use_rgb, self.use_rgbd)
        self.dis_thread.start()

        return

    @Slot()
    def kill_thread(self):
        """ Kill the uithread which is displaying the camera video.
        """

        self.statusBar().showMessage("Finishing FER ...")
        self.start_button.setEnabled(True)
        self.stop_button.setEnabled(False)

        self.dis_thread.status = False
        time.sleep(2)  # waiting for emitting all signals

        self.dis_thread.terminate()
        time.sleep(1)

        self.statusBar().showMessage("Read to go ...")
        self.dis_thread.status = True

        return

    @Slot()
    def updateFrame(self, image, window="2d"):
        if window == "2d":
            self.display_2d.setPixmap(QPixmap.fromImage(image))

        if window == "3d":
            self.display_3d.setPixmap(QPixmap.fromImage(image))

        return

    @Slot()
    def setQMessageBoxSlot(self, something):

        self.statusBar().showMessage(something)
        QMessageBox.warning(self,
                          "RGB Signal",
                          something)

        return

    @Slot()
    def setStatusBarSlot(self, something):

        self.statusBar().showMessage(something)

        return

    @Slot()
    def applyTexDisSet(self):
        self.statusBar().showMessage("Applying RGB setting ...")
        camid = self.combo_2d_cam_id.currentText()
        reso = self.combo_2d_reso.currentText()

        self.dis_thread.set_camera(camid, reso)

        QMessageBox.about(self,
                          "RGB Apply",
                          "Camera Id = {}\nResolution = {}".format(camid, reso))
        self.statusBar().showMessage("CameraId = {}   Resolution = {}".format(camid, reso))

        self.use_rgb = True
        self.use_rgbd = False

        self.dis_thread.status = True
        self.dis_thread.set_2d_methods(self.combo_2d_face_methods.currentText(),
                                       self.combo_2d_fer_methods.currentText())

        return

    @Slot()
    def applyRGBDSet(self):
        self.statusBar().showMessage("Applying RGB-D setting ...")

        realsense_available, deviceid = self.dis_thread.check_rgbd()

        if realsense_available:
            self.statusBar().showMessage("Intel RealSense {} detected.".format(deviceid))
            QMessageBox.about(self,
                              "RGB-D Apply",
                              "Intel RealSense {} detected.\nIntel RealSense {} applied.".format(deviceid, deviceid))

        else:
            self.statusBar().showMessage("No RGB-D device detected.")
            QMessageBox.warning(self,
                              "RGB-D Apply",
                              "No RGB-D device detected.\nPlease connect Intel RealSense device.")

        self.use_rgb = False
        self.use_rgbd = True

        self.dis_thread.status = True
        self.dis_thread.set_2d_methods(self.combo_2d_face_methods.currentText(),
                                       self.combo_2d_fer_methods.currentText())
        self.dis_thread.set_3d_methods(self.combo_3d_enh_methods.currentText(),
                                       self.combo_3d_fer_methods.currentText())

        return


from tkinter import * #para importar imagem de fundo e o END no apagar assunto
import customtkinter
import re
from PIL import Image #para importar imagens

import win32com.client as win32 # biblioteca para abrir o e-mail
import pandas as pd

from flask import Flask, render_template, request
import threading
import webbrowser

#aparencia geral escura
customtkinter.set_appearance_mode("dark") #dark | light| system (para MacOs)
#customtkinter.set_default_color_theme("dark-blue")

#configuração da janela inicial
janela = customtkinter.CTk()
janela.geometry("400x550+100+10") # Largura x Altura + distancia da esquerda + distancia da direita
janela.title("Projeto e-mails")
janela.iconbitmap("icon.ico")

imagem_fundo = customtkinter.CTkImage(light_image=Image.open("fundo.png"), dark_image=Image.open("fundo.png"), size=(1600,900))
customtkinter.CTkLabel(janela, text=None, image=imagem_fundo).place(x=0,y=0)

#isto é para o editor de mensagem WYSIWYG funcionar, é para abrir a página web
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def index():
    with open("corpo_email.txt", "r", encoding = "utf-8") as corpo_email_arq:
        corpo_email = corpo_email_arq.read()
    with open("assunto.txt", "r", encoding = "utf-8") as assunto_arq:
        assunto = assunto_arq.read()
    if request.method == 'POST':
        mensagem_recebida=request.form.get("editordata_mensagem")
        assunto_recebido = request.form.get("editordata_assunto")
        #print("mensagem: ",mensagem_recebida)
        with open("corpo_email.txt","w", encoding = "utf-8") as guardar_corpo_texto_arq:
            guardar_corpo_texto = guardar_corpo_texto_arq.write(mensagem_recebida)
        with open("assunto.txt","w", encoding = "utf-8") as guardar_assunto_arq:
            guardar_assunto = guardar_assunto_arq.write(assunto_recebido)
        return 'Mensagem Guardada'
    return render_template("index.html", mensagem_mostrar = corpo_email, assunto_mostrar=assunto)

# B O T Ã O   E N V I A R   E M A I L
def clique_enviar_emails():
    try:
        # T E M P O   E N T R E   E N V I O S   D E   E M A I L S - ciclo infino enquanto for true
        with open("emails_automaticos_tempo_ativo.txt", "r", encoding = "utf-8") as emails_automaticos_tempo_arq:
            emails_automaticos_tempo_ativo = emails_automaticos_tempo_arq.read()
        #while emails_automaticos_tempo_ativo == "True":
        if emails_automaticos_tempo_ativo =="True":
            with open("emails_automaticos_tempo.txt", "r", encoding = "utf-8") as emails_automaticos_tempo_arq:
                tempo_min = emails_automaticos_tempo_arq.read()
            tempo_mil_sec= int(tempo_min)*60*1000
            #print("tempo entre envios:",tempo_min, "minutos")
            #print("tempo entre envios:", tempo_mil_sec, "miliseconds")
            janela.after(tempo_mil_sec,lambda: clique_enviar_emails())

        # primeiro importar a lista de emails
        tabela_emails= pd.read_excel("dados_emails.xlsx")
        emails_enviar = tabela_emails['emails'].tolist()

        if emails_enviar[-1] != "@@@@@":
            emails_enviar.append("@@@@@")
        #print("lista com marca final", emails_enviar)
        #print("to list:", emails_enviar)
        outlook = win32.Dispatch('outlook.application') #ligar com o outlook

        #variáveis em txt dentro do email
        with open("assunto.txt", "r", encoding = "utf-8") as assunto_arq:
            assunto = assunto_arq.read()
        with open("corpo_email.txt", "r", encoding = "utf-8") as corpo_email_arq:
            corpo_email = corpo_email_arq.read()
        with open("numero_envios.txt", "r", encoding = "utf-8") as numero_envios_arq:
            n_requerido_envios = int(numero_envios_arq.read())

        #variáveis uteis
        regex = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')
        numero_envios=1
        n_requerido_envios2= n_requerido_envios
        #print("numero de envios", n_requerido_envios)
        for email_enviar in emails_enviar:
            #print(email_enviar)
            if re.fullmatch(regex,email_enviar):
                if numero_envios <= n_requerido_envios:
                    numero_envios +=1
                    #criar um email
                    email = outlook.CreateItem(0) #associar o remetente
                    #cofigurar o email
                    email.To = email_enviar
                    email.Subject = f"{assunto}"
                    email.HTMLBody = f"{corpo_email}"

                    #abrir a localização dos anexos
                    with open("anexo1.txt", "r", encoding = "utf-8") as anexo1_arq:
                        anexo1 = anexo1_arq.read()
                    with open("anexo2.txt", "r", encoding = "utf-8") as anexo2_arq:
                        anexo2 = anexo2_arq.read()
                    with open("anexo3.txt", "r", encoding = "utf-8") as anexo3_arq:
                        anexo3 = anexo3_arq.read()
                    with open("anexo4.txt", "r", encoding = "utf-8") as anexo4_arq:
                        anexo4 = anexo4_arq.read()
                    with open("anexo5.txt", "r", encoding = "utf-8") as anexo5_arq:
                        anexo5 = anexo5_arq.read()

                    #enviar anexos se eles existirem
                    if anexo1 != " " or None:
                        email.Attachments.Add(anexo1)
                    if anexo2 != " " or None:
                        email.Attachments.Add(anexo2)
                    if anexo3 != " " or None:
                        email.Attachments.Add(anexo3)
                    if anexo4 != " " or None:
                        email.Attachments.Add(anexo4)
                    if anexo5 != " " or None:
                        email.Attachments.Add(anexo5)

                    email.Send()
                else:
                    #criar nova tela
                    janela_enviar_email = customtkinter.CTkToplevel(janela)
                    janela_enviar_email.title("Projeto e-mails")
                    janela_enviar_email.geometry("300x150+500+100")
                    #caixa de texto
                    muda_assunto_label = customtkinter.CTkLabel(master = janela_enviar_email, text = "E-mails enviados !", font = customtkinter.CTkFont(size=16, weight = "bold"))
                    muda_assunto_label.pack(padx=10, pady=(20,10))

                    botao_voltar = customtkinter.CTkButton(janela_enviar_email, text = " Voltar ", corner_radius=0, command = janela_enviar_email.destroy)
                    botao_voltar.pack(padx=10, pady=10)

                    #fechar janela automaticamente
                    janela.after(10000,lambda: janela_enviar_email.destroy())
                    break
            elif re.fullmatch("@@@@@",email_enviar):
                with open("reposicao_automatica.txt", "r", encoding = "utf-8") as reposicao_automatica_arq:
                    reposicao_automatica = reposicao_automatica_arq.read()
                if reposicao_automatica == "True":
                    #abrir excel
                    tabela= pd.read_excel("dados_emails - completo.xlsx")
                    emails = tabela['emails'] #puxar colunas
                    #guardar excel
                    file_name = 'dados_emails.xlsx'
                    emails.to_excel(file_name)

                    janela_reposicao_automatica = customtkinter.CTkToplevel(janela, fg_color="red")
                    janela_reposicao_automatica.title("Projeto e-mails - Repor lista automatica")
                    janela_reposicao_automatica.geometry("300x150+500+100")
                    #caixa de texto
                    reposicao_automatica_label = customtkinter.CTkLabel(master = janela_reposicao_automatica, text = "Emails enviados \nLista de e-mails terminou!", font = customtkinter.CTkFont(size=16, weight = "bold"))
                    reposicao_automatica_label.pack(padx=10, pady=(20,10))

                    botao_voltar = customtkinter.CTkButton(janela_reposicao_automatica, text = " Voltar ", corner_radius=0, command = janela_reposicao_automatica.destroy)
                    botao_voltar.pack(padx=10, pady=10)
                    break
                else:

                    with open("email_para_avisos.txt", "r", encoding = "utf-8") as email_para_avisos_arq:
                        email_para_avisos = email_para_avisos_arq.read()
                    email = outlook.CreateItem(0) #associar o remetente
                    #cofigurar o email
                    email.To = email_para_avisos
                    email.Subject = f"Lista Terminada"
                    email.HTMLBody = f"A lista de e-mails terminou e por isso o envio parou."
                    email.Send()

                    janela_tabela_vazia = customtkinter.CTkToplevel(janela,fg_color="red")
                    janela_tabela_vazia.title("Projeto e-mails - Repor lista automatica")
                    janela_tabela_vazia.geometry("400x150+500+100")
                    #caixa de texto
                    tabela_vazia_label = customtkinter.CTkLabel(master = janela_tabela_vazia, text = "Lista terminou, importe uma nova", font = customtkinter.CTkFont(size=16, weight = "bold"))
                    tabela_vazia_label.pack(padx=10, pady=(20,10))

                    botao_voltar = customtkinter.CTkButton(janela_tabela_vazia, text = " Voltar ", corner_radius=0, command = janela_tabela_vazia.destroy)
                    botao_voltar.pack(padx=10, pady=10)
            else:
                #email critico -- estragado
                n_requerido_envios2 += 1

        dicionario_emails_enviar= {'emails':emails_enviar}
        emails_enviar_df = pd.DataFrame(dicionario_emails_enviar )
        #n_requerido_envios2 += 1
        emails_enviar_df= emails_enviar_df.iloc[n_requerido_envios2:, : ]

        file_name_por_enviar = 'dados_emails.xlsx'
        emails_enviar_df.to_excel(file_name_por_enviar)

    except UnboundLocalError:
        #print("letra no numero de emails")
        erro_n_emails = customtkinter.CTkToplevel(janela, fg_color="red")
        erro_n_emails.title("Projeto e-mails - Erro")
        erro_n_emails.geometry("300x150+500+100")

        erro_n_emails_label = customtkinter.CTkLabel(master = erro_n_emails, text = "Erro no numero de e-mails.\n Certifique-se que tem lá um número", font = customtkinter.CTkFont(size=16, weight = "bold"))
        erro_n_emails_label.pack(padx=10, pady=(20,10))

    except KeyError:
        #print("keyerror")
        #reposicao_automatica = True
        with open("reposicao_automatica.txt", "r", encoding = "utf-8") as reposicao_automatica_arq:
            reposicao_automatica = reposicao_automatica_arq.read()
        if reposicao_automatica == "True":
            #abrir excel
            tabela= pd.read_excel("dados_emails - completo.xlsx")
            emails = tabela[['emails','flag']] #puxar colunas
            #guardar excel
            file_name = 'dados_emails.xlsx'
            emails.to_excel(file_name)

            janela_reposicao_automatica = customtkinter.CTkToplevel(janela, fg_color="red")
            janela_reposicao_automatica.title("Projeto e-mails - Repor lista automatica")
            janela_reposicao_automatica.geometry("300x150+500+100")
            #caixa de texto
            reposicao_automatica_label = customtkinter.CTkLabel(master = janela_reposicao_automatica, text = "Emails enviados \nLista de e-mails reposta!", font = customtkinter.CTkFont(size=16, weight = "bold"))
            reposicao_automatica_label.pack(padx=10, pady=(20,10))

            botao_voltar = customtkinter.CTkButton(janela_reposicao_automatica, text = " Voltar ", corner_radius=0, command = janela_reposicao_automatica.destroy)
            botao_voltar.pack(padx=10, pady=10)
        else:
            tabela= pd.read_excel("marca_final.xlsx")
            emails = tabela[['emails']] #puxar colunas

            file_name = 'dados_emails.xlsx'
            emails.to_excel(file_name)

            with open("email_para_avisos.txt", "r", encoding = "utf-8") as email_para_avisos_arq:
                email_para_avisos = email_para_avisos_arq.read()
            email = outlook.CreateItem(0) #associar o remetente
            #cofigurar o email
            email.To = email_para_avisos
            email.Subject = f"Lista Terminada"
            email.HTMLBody = f"A lista de e-mails terminou e por isso o envio parou."
            email.Send()

            janela_sem_reposicao_automatica = customtkinter.CTkToplevel(janela,fg_color="red")
            janela_sem_reposicao_automatica.title("Projeto e-mails - Repor lista automatica")
            janela_sem_reposicao_automatica.geometry("400x150+500+100")
            #caixa de texto
            reposicao_automatica_label = customtkinter.CTkLabel(master = janela_sem_reposicao_automatica, text = "Lista terminou, importe uma nova", font = customtkinter.CTkFont(size=16, weight = "bold"))
            reposicao_automatica_label.pack(padx=10, pady=(20,10))

            botao_voltar = customtkinter.CTkButton(janela_sem_reposicao_automatica, text = " Voltar ", corner_radius=0, command = janela_sem_reposicao_automatica.destroy)
            botao_voltar.pack(padx=10, pady=10)

    except IndexError:
        print("indexError")
        with open("reposicao_automatica.txt", "r", encoding = "utf-8") as reposicao_automatica_arq:
            reposicao_automatica = reposicao_automatica_arq.read()
        if reposicao_automatica == "True":
            #abrir excel
            tabela= pd.read_excel("dados_emails - completo.xlsx")
            emails = tabela['emails'] #puxar colunas
            #guardar excel
            file_name = 'dados_emails.xlsx'
            emails.to_excel(file_name)

            with open("email_para_avisos.txt", "r", encoding = "utf-8") as email_para_avisos_arq:
                email_para_avisos = email_para_avisos_arq.read()

            outlook = win32.Dispatch('outlook.application') #ligar com o outlook
            email = outlook.CreateItem(0) #associar o remetente
            #cofigurar o email
            email.To = email_para_avisos
            email.Subject = f"Lista Terminada"
            email.HTMLBody = f"A lista de e-mails terminou e foi reposta, por isso o envio continua."
            email.Send()

            janela_reposicao_automatica = customtkinter.CTkToplevel(janela, fg_color="red")
            janela_reposicao_automatica.title("Projeto e-mails - Repor lista automatica")
            janela_reposicao_automatica.geometry("300x150+500+100")
            #caixa de texto
            reposicao_automatica_label = customtkinter.CTkLabel(master = janela_reposicao_automatica, text = "Emails enviados \nLista de e-mails reposta!", font = customtkinter.CTkFont(size=16, weight = "bold"))
            reposicao_automatica_label.pack(padx=10, pady=(20,10))

            botao_voltar = customtkinter.CTkButton(janela_reposicao_automatica, text = " Voltar ", corner_radius=0, command = janela_reposicao_automatica.destroy)
            botao_voltar.pack(padx=10, pady=10)
        else:
            with open("email_para_avisos.txt", "r", encoding = "utf-8") as email_para_avisos_arq:
                email_para_avisos = email_para_avisos_arq.read()
            outlook = win32.Dispatch('outlook.application') #ligar com o outlook
            email = outlook.CreateItem(0) #associar o remetente
            #cofigurar o email
            email.To = email_para_avisos
            email.Subject = f"Lista Terminada"
            email.HTMLBody = f"A lista de e-mails terminou e por isso o envio parou."
            email.Send()

            janela_tabela_vazia = customtkinter.CTkToplevel(janela,fg_color="red")
            janela_tabela_vazia.title("Projeto e-mails - Repor lista automatica")
            janela_tabela_vazia.geometry("400x150+500+100")
            #caixa de texto
            tabela_vazia_label = customtkinter.CTkLabel(master = janela_tabela_vazia, text = "Lista terminou, importe uma nova", font = customtkinter.CTkFont(size=16, weight = "bold"))
            tabela_vazia_label.pack(padx=10, pady=(20,10))

            botao_voltar = customtkinter.CTkButton(janela_tabela_vazia, text = " Voltar ", corner_radius=0, command = janela_tabela_vazia.destroy)
            botao_voltar.pack(padx=10, pady=10)

    #except Exception as error:

# B O T Ã O   E N V I A R   E M A I L   T E S T E
def clique_enviar_email_teste():
    try:
        outlook = win32.Dispatch('outlook.application') #ligar com o outlook

        #variáveis em txt dentro do email
        with open("assunto.txt", "r", encoding = "utf-8") as assunto_arq:
            assunto = assunto_arq.read()
        with open("corpo_email.txt", "r", encoding = "utf-8") as corpo_email_arq:
            corpo_email = corpo_email_arq.read()
        with open("email_teste.txt", "r", encoding = "utf-8") as teste_email_arq:
            teste_email = teste_email_arq.read()

        #criar um email
        email = outlook.CreateItem(0) #associar o remetente
        #cofigurar o email
        email.To = teste_email
        email.Subject = f"{assunto}"
        #utilizar formatação HTML a utilizar no e-mail - Escrever email normal
        email.HTMLBody = f"{corpo_email}"

        #abrir a localização dos anexos
        with open("anexo1.txt", "r", encoding = "utf-8") as anexo1_arq:
            anexo1 = anexo1_arq.read()
        with open("anexo2.txt", "r", encoding = "utf-8") as anexo2_arq:
            anexo2 = anexo2_arq.read()
        with open("anexo3.txt", "r", encoding = "utf-8") as anexo3_arq:
            anexo3 = anexo3_arq.read()
        with open("anexo4.txt", "r", encoding = "utf-8") as anexo4_arq:
            anexo4 = anexo4_arq.read()
        with open("anexo5.txt", "r", encoding = "utf-8") as anexo5_arq:
            anexo5 = anexo5_arq.read()

        #enviar anexos se eles existirem
        if anexo1 != " " or None:
            email.Attachments.Add(anexo1)

        if anexo2 != " " or None:
            email.Attachments.Add(anexo2)

        if anexo3 != " " or None:
            email.Attachments.Add(anexo3)

        if anexo4 != " " or None:
            email.Attachments.Add(anexo4)

        if anexo5 != " " or None:
            email.Attachments.Add(anexo5)
        email.Send()

        #janela a confirmar envio
        janela_enviar_email = customtkinter.CTkToplevel(janela)
        janela_enviar_email.title("Projeto e-mails - E-mail de Teste")
        janela_enviar_email.geometry("300x150+500+100")
        #caixa de texto
        muda_assunto_label = customtkinter.CTkLabel(master = janela_enviar_email, text = "E-mail de teste enviado", font = customtkinter.CTkFont(size=16, weight = "bold"))
        muda_assunto_label.pack(padx=10, pady=(20,10))

        botao_voltar = customtkinter.CTkButton(janela_enviar_email, text = " Voltar ", corner_radius=0, command = janela_enviar_email.destroy)
        botao_voltar.pack(padx=10, pady=10)

    except Exception as error:
        #janela a informar que houve um erro
        #print("O campo do e-mail de teste encontra-se vazio!")
        janela_enviar_teste_vazio = customtkinter.CTkToplevel(janela, fg_color="red")
        janela_enviar_teste_vazio.title("Projeto e-mails - Erro")
        janela_enviar_teste_vazio.geometry("300x200+500+100")
        #caixa de texto
        muda_assunto_label = customtkinter.CTkLabel(master = janela_enviar_teste_vazio, text = "O campo de email de teste\nencontra-se vazio, ou preenchido \nde forma incorreta,\n ou há um problema com os anexos", font = customtkinter.CTkFont(size=16, weight = "bold"))
        muda_assunto_label.pack(padx=10, pady=(20,10))
        muda_assunto_label2 = customtkinter.CTkLabel(master = janela_enviar_teste_vazio, text = teste_email)
        muda_assunto_label2.pack(padx=10, pady=0)

        botao_voltar = customtkinter.CTkButton(janela_enviar_teste_vazio, text = " Voltar ", corner_radius=0, command = janela_enviar_teste_vazio.destroy)
        botao_voltar.pack(padx=10, pady=10)

# B O T Ã O   M U D A R   M E N S A G E M
def clique_mudar_email():
    # janela
    janela_mudar_email = customtkinter.CTkToplevel(janela)
    janela_mudar_email.title("Projeto e-mails - Mudar E-mail")
    janela_mudar_email.geometry("650x490+500+50")

    frame_janela = customtkinter.CTkFrame(janela_mudar_email, width=600, height=450)
    frame_janela.place(x=20,y=20)

#o assunto não precisa de formatação etão pode ficar só como entry
    def botao_guardar_assunto():
        assunto_entry1 = str(assunto_entry.get())
        with open("assunto.txt","w", encoding = "utf-8") as guardar_assunto_arq:
            guardar_assunto = guardar_assunto_arq.write(assunto_entry1)

#isto está a pegar a informação que colocou na entry do corpo de texto
    def botao_guardar_corpo_texto():
        corpo_texto_entry1 = str(inserir_corpo_texto.get())
        with open("corpo_email.txt","w", encoding = "utf-8") as guardar_corpo_texto_arq:
            guardar_corpo_texto = guardar_corpo_texto_arq.write(corpo_texto_entry1)

#então como é que está a receber a informação?
    # BOTÃO OCNSTRUTOR DE CORPO DE TEXTO
    def botao_construtor_HTML():
        def botao_construtor_HTML1():
            #ao carregar abrir uma determinada pagina web
            webbrowser.open_new_tab("http://127.0.0.1:5000")
            app.run()
            pass

        #para abrir a nova pagina ela estava me a criar sempre um novo botão, então eu não coloquei as coordenadas da pagina
        #assim ele cria mas não aparece
        btn_corpo_texto1 = customtkinter.CTkButton(master=coluna2, width = 1, height= 1,text = "", command = threading.Thread(target=botao_construtor_HTML1).start())
        #btn_corpo_texto1.place(x=30,y=110)
        pass

    # ANEXAR ANEXOS
    def clique_adicionar_anexos():
        janela_adicionar_anexos = customtkinter.CTkToplevel(janela_mudar_email)
        janela_adicionar_anexos.title("Projeto e-mails - Adicionar anexos")
        janela_adicionar_anexos.geometry("680x550+500+50")

        def clique_anexo_full_path():
            adicionar_anexos_entry1a = adicionar_anexos_entry1.get()
            with open("anexo1.txt","w", encoding = "utf-8") as anexo1_arq:
                anexo1 = anexo1_arq.write(adicionar_anexos_entry1a)
            pass
        def clique_anexo_full_path2():
            adicionar_anexos_entry2a = adicionar_anexos_entry2.get()
            with open("anexo2.txt","w", encoding = "utf-8") as anexo2_arq:
                anexo2 = anexo2_arq.write(adicionar_anexos_entry2a)
            pass
        def clique_anexo_full_path3():
            adicionar_anexos_entry3a = adicionar_anexos_entry3.get()
            with open("anexo3.txt","w", encoding = "utf-8") as anexo3_arq:
                anexo3 = anexo3_arq.write(adicionar_anexos_entry3a)
            pass
        def clique_anexo_full_path4():
            adicionar_anexos_entry4a = adicionar_anexos_entry4.get()
            with open("anexo4.txt","w", encoding = "utf-8") as anexo4_arq:
                anexo4 = anexo4_arq.write(adicionar_anexos_entry4a)
            pass
        def clique_anexo_full_path5():
            adicionar_anexos_entry5a = adicionar_anexos_entry5.get()
            with open("anexo5.txt","w", encoding = "utf-8") as anexo5_arq:
                anexo5 = anexo5_arq.write(adicionar_anexos_entry5a)
            pass

        #criar espaço para ter as entrys ao lado dos botões
        adicionar_anexos_coluna1 = customtkinter.CTkFrame(janela_adicionar_anexos, width=440, height=430)
        adicionar_anexos_coluna1.place(x=20,y=20)

        # ler o caminho onde está o anexo
        with open("anexo1.txt", "r", encoding = "utf-8") as adicionar_anexos1_arq:
            adicionar_anexos1 = adicionar_anexos1_arq.read()
        adicionar_anexos_entry1 = customtkinter.CTkEntry(adicionar_anexos_coluna1, width=400, placeholder_text=adicionar_anexos1)
        adicionar_anexos_entry1.pack(padx=10, pady=10)
        with open("anexo2.txt", "r", encoding = "utf-8") as adicionar_anexos2_arq:
            adicionar_anexos2 = adicionar_anexos2_arq.read()
        adicionar_anexos_entry2 = customtkinter.CTkEntry(adicionar_anexos_coluna1, width=400, placeholder_text=adicionar_anexos2)
        adicionar_anexos_entry2.pack(padx=10, pady=10)
        with open("anexo3.txt", "r", encoding = "utf-8") as adicionar_anexos3_arq:
            adicionar_anexos3 = adicionar_anexos3_arq.read()
        adicionar_anexos_entry3 = customtkinter.CTkEntry(adicionar_anexos_coluna1, width=400, placeholder_text=adicionar_anexos3)
        adicionar_anexos_entry3.pack(padx=10, pady=10)
        with open("anexo4.txt", "r", encoding = "utf-8") as adicionar_anexos4_arq:
            adicionar_anexos4 = adicionar_anexos4_arq.read()
        adicionar_anexos_entry4 = customtkinter.CTkEntry(adicionar_anexos_coluna1, width=400, placeholder_text=adicionar_anexos4)
        adicionar_anexos_entry4.pack(padx=10, pady=10)
        with open("anexo5.txt", "r", encoding = "utf-8") as adicionar_anexos5_arq:
            adicionar_anexos5 = adicionar_anexos5_arq.read()
        adicionar_anexos_entry5 = customtkinter.CTkEntry(adicionar_anexos_coluna1, width=400, placeholder_text=adicionar_anexos5)
        adicionar_anexos_entry5.pack(padx=10, pady=10)

        adicionar_anexos_info_label1= customtkinter.CTkLabel(adicionar_anexos_coluna1, text="Para adicionar o ficheiro:", justify="left")
        adicionar_anexos_info_label1.pack(padx=10, pady=5)
        adicionar_anexos_info_label2= customtkinter.CTkLabel(adicionar_anexos_coluna1, text=" 1) Botão direito em cima do ficheiro a anexar;\n 2) Propriedades;\n 3) Copiar a localização para a barra de anexos, colocar uma barra invertida,\nnome do ficheiro, ponto, extensão/tipo do ficheiro \n (pdf, xlsx, docx, png...) ", justify="left")
        adicionar_anexos_info_label2.pack(padx=10, pady=(0,10))
        adicionar_anexos_info_label3= customtkinter.CTkLabel(adicionar_anexos_coluna1, text="Exemplo (só pode haver espaços no Nome do Ficheiro):", justify="left")
        adicionar_anexos_info_label3.pack(padx=10, pady=0)
        adicionar_anexos_info_label3= customtkinter.CTkLabel(adicionar_anexos_coluna1, text=r"C:\Users\gaspar\Desktop\Ficha de Inscrição.pdf", justify="left")
        adicionar_anexos_info_label3.pack(padx=10, pady=0)
        adicionar_anexos_info_label5= customtkinter.CTkLabel(adicionar_anexos_coluna1, text="Para não enviar um anexo basta colocar um espço e carregar no anexar. \nNOTA: Se tiver 2 espaços ou um caracter vai dar erro no envio. Tal como\nse colocar um caminho inválido ou com extensão incorreta (ter em atenção\nque um documento word pode ter como extensão .doc ou .docx) ", justify="left")
        adicionar_anexos_info_label5.pack(padx=10, pady=10)

        #criar espaço para ter os botões ao lado das entrys
        adicionar_anexos_coluna2 = customtkinter.CTkFrame(janela_adicionar_anexos, width=180, height=430)
        adicionar_anexos_coluna2.place(x=480,y=20)
        adicionar_anexos_label_coluna2= customtkinter.CTkLabel(adicionar_anexos_coluna2, text=" ")
        adicionar_anexos_label_coluna2.place(x=20,y=20)
        botao_adicionar_anexos_entry1 = customtkinter.CTkButton(adicionar_anexos_coluna2, text = " Anexo 1 ", corner_radius=8, command = clique_anexo_full_path)
        botao_adicionar_anexos_entry1.pack(padx=10, pady=10)
        botao_adicionar_anexos_entry2 = customtkinter.CTkButton(adicionar_anexos_coluna2, text = " Anexo 2 ", corner_radius=8, command = clique_anexo_full_path2)
        botao_adicionar_anexos_entry2.pack(padx=10, pady=10)
        botao_adicionar_anexos_entry3 = customtkinter.CTkButton(adicionar_anexos_coluna2, text = " Anexo 3 ", corner_radius=8, command = clique_anexo_full_path3)
        botao_adicionar_anexos_entry3.pack(padx=10, pady=10)
        botao_adicionar_anexos_entry4 = customtkinter.CTkButton(adicionar_anexos_coluna2, text = " Anexo 4 ", corner_radius=8, command = clique_anexo_full_path4)
        botao_adicionar_anexos_entry4.pack(padx=10, pady=10)
        botao_adicionar_anexos_entry5 = customtkinter.CTkButton(adicionar_anexos_coluna2, text = " Anexo 5 ", corner_radius=8, command = clique_anexo_full_path5)
        botao_adicionar_anexos_entry5.pack(padx=10, pady=10)

        botao_voltar = customtkinter.CTkButton(adicionar_anexos_coluna2, text = " Voltar ", corner_radius=8, command = janela_adicionar_anexos.destroy)
        botao_voltar.pack(padx=10, pady=30)
        pass

    coluna2 = customtkinter.CTkFrame(frame_janela, width=400, height=400)
    coluna2.place(x=20,y=50)
    assunto_entry = customtkinter.CTkEntry(coluna2, width=300, placeholder_text= " Novo assunto ")
    assunto_entry.pack(padx=10, pady=10)
    inserir_corpo_texto = customtkinter.CTkEntry(coluna2, width=300, placeholder_text="Novo corpo de texto")
    inserir_corpo_texto.pack(padx=10, pady=10)
    btn_corpo_texto1 = customtkinter.CTkButton(coluna2, width=250, text = " Construtor do email ", corner_radius=8, command = botao_construtor_HTML)
    btn_corpo_texto1.pack(padx=10, pady=10)
    botao_adicionar_anexos = customtkinter.CTkButton(coluna2, width=250, text = " Adicionar Anexos ", corner_radius=8, command = clique_adicionar_anexos)
    botao_adicionar_anexos.pack(padx=10, pady=10)

    coluna3 = customtkinter.CTkFrame(frame_janela, width=250, height=400)
    coluna3.place(x=360,y=50)
    btn_assunto = customtkinter.CTkButton(coluna3, width=200, text = " Adicionar Assunto ", corner_radius=8, command = botao_guardar_assunto)
    btn_assunto.pack(padx=10, pady=10)
    btn_corpo_texto = customtkinter.CTkButton(coluna3, width=200, text = " Adicionar corpo de texto ", corner_radius=8, command = botao_guardar_corpo_texto)
    btn_corpo_texto.pack(padx=10, pady=10)

    botao_voltar = customtkinter.CTkButton(coluna3, text = " Voltar ", corner_radius=8, command = janela_mudar_email.destroy)
    botao_voltar.pack(padx=10, pady=(40,10))

# B O T Ã O   M O S T R A R   E M A I L
def clique_mostrar_emails():
#criar nova tela
    janela_mostrar_email = customtkinter.CTkToplevel(janela)
    janela_mostrar_email.title("Projeto e-mails")
    janela_mostrar_email.geometry("400x650+500+10")
#caixa de texto
    muda_assunto_label = customtkinter.CTkLabel(master = janela_mostrar_email, text = "E-mails restantes !", font = customtkinter.CTkFont(size=16, weight = "bold"))
    muda_assunto_label.pack(padx=10, pady=(20,10))

#mostrar excel
    importar_mostrar_excel = pd.read_excel("dados_emails.xlsx")
    importar_mostrar_emails = importar_mostrar_excel[['emails']]

    tamanho_lista = len(importar_mostrar_excel['emails'])

    exibir_emails = customtkinter.CTkScrollableFrame(janela_mostrar_email, width=300, height=430)
    exibir_emails.pack(padx=10, pady=10)
    #mostrar só os 60 primeiros porque se pedir 61 vai aparecer umas reticencias no meio
    scrolabletext= customtkinter.CTkLabel(exibir_emails, text = importar_mostrar_emails[['emails']].head(60))
    scrolabletext.pack(padx=10, pady=10)

    tamanho_lista_label1= customtkinter.CTkLabel(janela_mostrar_email, text = "E-mails por enviar:")
    tamanho_lista_label1.pack(padx=0, pady=0)
    tamanho_lista_label2= customtkinter.CTkLabel(janela_mostrar_email, text = tamanho_lista)
    tamanho_lista_label2.pack(padx=0, pady=0)

    # Botão HELP
    def mostrar_emails_informacoes():
        janela_mostrar_emails_informacoes = customtkinter.CTkToplevel(janela)
        janela_mostrar_emails_informacoes.title("Projeto e-mails")
        janela_mostrar_emails_informacoes.geometry("400x650+900+10")

        emails_invalidos_informacoes_label = customtkinter.CTkLabel(janela_mostrar_emails_informacoes, text = "Se na lista aparecer \n\nemails\nxx  -----\n\n ou\n\nEmpty DataFrame \nColumns:[] \nIndex: []\n\n significa que a lista acabou")
        emails_invalidos_informacoes_label.pack(padx=10, pady=10)

        botao_voltar = customtkinter.CTkButton(janela_mostrar_emails_informacoes, text = " Voltar ", corner_radius=8, command = janela_mostrar_emails_informacoes.destroy)
        botao_voltar.pack(padx=10, pady=10)

        pass
    botao_mostrar_emails_informacoes = customtkinter.CTkButton(janela_mostrar_email, text = "Help",width=20, corner_radius=20, command = mostrar_emails_informacoes)
    botao_mostrar_emails_informacoes.place(x=10,y=10)

    botao_voltar = customtkinter.CTkButton(janela_mostrar_email, text = " Voltar ", corner_radius=8, command = janela_mostrar_email.destroy)
    botao_voltar.pack(padx=10, pady=10)

# B O T Ã O   O U T R A S   O P Ç Õ E S
def clique_outras_opcoes():
    #Criação da janela
    janela_outras_opcoes = customtkinter.CTkToplevel(janela)
    janela_outras_opcoes.title("Projeto e-mails - Outras opções")
    janela_outras_opcoes.geometry("400x650+500+10")

    outras_opcoes_label = customtkinter.CTkLabel(janela_outras_opcoes, text = "Outras opções:", font = customtkinter.CTkFont(size=16, weight = "bold"))
    outras_opcoes_label.pack(padx=10, pady=(20,10))

    outras_opcoes_frame= customtkinter.CTkFrame(janela_outras_opcoes, width=350, height=550)
    outras_opcoes_frame.pack(padx=10, pady=10)

    # NUMERO DE EMAILS
    def clique_alterar_n_emails():
        try:
            #vou guardar no txt
            with open("numero_envios.txt","w", encoding = "utf-8") as n_envios_arq:
                n_envios_arq.write(n_emails.get())
            #vou buscar
            with open("numero_envios.txt","r", encoding = "utf-8") as n_envios_arq:
                numero_envios = n_envios_arq.read()
            #vou verificar
            #caso correto vou guardar
            numero_envios1 = int(numero_envios)
            if numero_envios1 > 0 : # o numero de envios deve ser um numero maior do que zero
                #janela de confirmação da alteração da quantidare - alteração feita com sucesso
                janela_alterar_n_emails = customtkinter.CTkToplevel(janela_outras_opcoes)
                janela_alterar_n_emails.title("Projeto e-mails")
                janela_alterar_n_emails.geometry("300x150+900+100")

                alterar_n_emails_label = customtkinter.CTkLabel(janela_alterar_n_emails, text = "Alteração feita com sucesso", font = customtkinter.CTkFont(size=16, weight = "bold"))
                alterar_n_emails_label.pack(padx=10, pady=(20,10))

                botao_voltar = customtkinter.CTkButton(janela_alterar_n_emails, text = " Voltar ", corner_radius=8, command = janela_alterar_n_emails.destroy)
                botao_voltar.pack(padx=10, pady=10)
            pass
        except ValueError:
            #janela de erro quando o valor guardado não é um numero
            janela_lista_original_nao_encontrada = customtkinter.CTkToplevel(janela, fg_color="red")
            janela_lista_original_nao_encontrada.title("Projeto e-mails - Erro")
            janela_lista_original_nao_encontrada.geometry("300x150+900+100")

            lista_original_nao_encontrada_label = customtkinter.CTkLabel(janela_lista_original_nao_encontrada, text = "O que inseriu não é numero", font = customtkinter.CTkFont(size=16, weight = "bold"))
            lista_original_nao_encontrada_label.pack(padx=10, pady=(20,10))
            botao_voltar = customtkinter.CTkButton(janela_lista_original_nao_encontrada, text = " Voltar ", corner_radius=8, command = janela_lista_original_nao_encontrada.destroy)
            botao_voltar.pack(padx=10, pady=10)
            pass

    # ALTERAR EMAIL DE TESTES
    def clique_alterar_email():
        #ir buscar o que foi escrito na entry
        with open("email_teste.txt","w", encoding = "utf-8") as email_teste_arq:
            email_testar = email_teste_arq.write(alterar_email_teste_entry.get())
        #janela de confirmação
        janela_alterar_email_teste = customtkinter.CTkToplevel(janela_outras_opcoes)
        janela_alterar_email_teste.title("Projeto e-mails ")
        janela_alterar_email_teste.geometry("300x150+900+100")

        alterar_n_emails_label = customtkinter.CTkLabel(janela_alterar_email_teste, text = "E-mail teste alterado", font = customtkinter.CTkFont(size=16, weight = "bold"))
        alterar_n_emails_label.pack(padx=10, pady=(20,10))

        botao_voltar = customtkinter.CTkButton(janela_alterar_email_teste, text = " Voltar ", corner_radius=8, command = janela_alterar_email_teste.destroy)
        botao_voltar.pack(padx=10, pady=10)
        pass

    # IMPORTAÇÃO DE NOVA LISTA DE EMAILS
    def clique_nova_lista():
        try:
            #abrir excel
            tabela= pd.read_excel("dados_emails - completo.xlsx")
            emails = tabela[['emails']] #puxar colunas
            #guardar excel
            file_name = 'dados_emails.xlsx'
            emails.to_excel(file_name)

            janela_nova_lista = customtkinter.CTkToplevel(janela_outras_opcoes)
            janela_nova_lista.title("Projeto e-mails - E-mail teste alterado")
            janela_nova_lista.geometry("300x150+900+100")

            alterar_n_emails_label = customtkinter.CTkLabel(janela_nova_lista, text = "Nova lista importada", font = customtkinter.CTkFont(size=16, weight = "bold"))
            alterar_n_emails_label.pack(padx=10, pady=(20,10))

            botao_voltar = customtkinter.CTkButton(janela_nova_lista, text = " Voltar ", corner_radius=8, command = janela_nova_lista.destroy)
            botao_voltar.pack(padx=10, pady=10)
        except FileNotFoundError:
            #janela de erro caso não exista o documento na pasta com o nome "dados_emails - completo.xlsx"
            janela_lista_original_nao_encontrada = customtkinter.CTkToplevel(janela, fg_color="red")
            janela_lista_original_nao_encontrada.title("Projeto e-mails - Erro")
            janela_lista_original_nao_encontrada.geometry("300x150+900+100")

            lista_original_nao_encontrada_label = customtkinter.CTkLabel(janela_lista_original_nao_encontrada, text = "Nova lista não \nencontrada", font = customtkinter.CTkFont(size=16, weight = "bold"))
            lista_original_nao_encontrada_label.pack(padx=10, pady=(20,10))
            botao_voltar = customtkinter.CTkButton(janela_lista_original_nao_encontrada, text = " Voltar ", corner_radius=8, command = janela_lista_original_nao_encontrada.destroy)
            botao_voltar.pack(padx=10, pady=10)
            pass

    # SWITCH PARA LIGAR E DESLIGAR A REPOSIÇÃO AUTOMÁTICA
    def switch_reposicao_automatica():
        #quando clicado é guardado
        #print("valor switch reposição automática ->", switch_var.get())
        with open("reposicao_automatica.txt","w", encoding = "utf-8") as reposicao_automatica_arq:
            reposicao_automatica = reposicao_automatica_arq.write(switch_var.get())
        pass

    # VERIFICAR EMAILS REJEITADOS PELO OUTLOOK
    def clique_rejeitados_outlook():

        outlook = win32.Dispatch("Outlook.Application").GetNamespace("MAPI")

        #pasta onde procurar os emails - a caixa de entrada/inbox foi definida como pasta 6 (pela documentação)
        inbox = outlook.GetDefaultFolder(6)
        mensagens_inbox = inbox.Items
        lista_rejeitados=[]

        #vou procurar determinado texto nas mensagens da inbox
        for msg in mensagens_inbox:
            if 'This message was created automatically by mail delivery software' in str(msg.Body):
                #procurar a expressao que coincida com o email
                procurar_email = re.search(r"[A-Za-z0-9_%+-.]+"r"@[A-Za-z0-9.-]+"r"\.[A-Za-z]{2,5}",msg.Body)
                lista_rejeitados.append(procurar_email.group()) #adicionar à lista

        #passar para dataframe para eliminar duplicados
        email_rejeitado_df = pd.DataFrame({'rejeitados': lista_rejeitados})
        email_rejeitado_df.drop_duplicates

        file_email_rejeitado = 'emails_rejeitados_pelo_outlook.xlsx'
        email_rejeitado_df.to_excel(file_email_rejeitado)

        def clique_eliminar_rejeitados_outlook():
            tabela_email_rejeitado_eliminar_original= pd.read_excel("dados_emails - completo.xlsx")
            email_rejeitado_eliminar_original = tabela_email_rejeitado_eliminar_original['emails'] #puxar colunas

            tabela_email_rejeitado_eliminar1= pd.read_excel("emails_rejeitados_pelo_outlook.xlsx")
            email_rejeitado_eliminar1 = tabela_email_rejeitado_eliminar1['rejeitados']

            lista_email_rejeitado_eliminar_original = email_rejeitado_eliminar_original.tolist()
            dicionario_rejeitados = {'emails':lista_email_rejeitado_eliminar_original,'e-mails':lista_email_rejeitado_eliminar_original}
            email_rejeitado_eliminar_original_df = pd.DataFrame( dicionario_rejeitados,columns=['emails'], index= lista_email_rejeitado_eliminar_original)
            lista_nova=[]
            for rejeitado_eliminar3 in email_rejeitado_eliminar_original_df['emails']:
                for rejeitado in email_rejeitado_eliminar1:
                    if rejeitado == rejeitado_eliminar3:
                        lista_nova.append(rejeitado)
                    else: a=1
            #print("listanova:",lista_nova)
            email_rejeitado_eliminar_original_df.drop_duplicates
            for rejeitado in lista_nova:
                email_rejeitado_eliminar_original_df = email_rejeitado_eliminar_original_df.drop(rejeitado)
            #print("segundo print",email_rejeitado_eliminar_original_df)

            file_name_emails_sem_rejeitados = 'dados_emails - completo.xlsx'
            email_rejeitado_eliminar_original_df.to_excel(file_name_emails_sem_rejeitados)

            #janela de confirmação
            janela_email_rejeitado_confirmacao = customtkinter.CTkToplevel(janela)
            janela_email_rejeitado_confirmacao.title("Projeto e-mails - E-mail teste alterado")
            janela_email_rejeitado_confirmacao.geometry("300x150+400+100")

            alterar_n_emails_label = customtkinter.CTkLabel(janela_email_rejeitado_confirmacao, text = "Emails rejeitados eliminados \n da lista original", font = customtkinter.CTkFont(size=16, weight = "bold"))
            alterar_n_emails_label.pack(padx=10, pady=(20,10))

            botao_voltar = customtkinter.CTkButton(janela_email_rejeitado_confirmacao, text = " Voltar ", corner_radius=8, command = janela_email_rejeitado_confirmacao.destroy)
            botao_voltar.pack(padx=10, pady=10)

            pass

        #Janela para visualizar rejeitados
        janela_email_rejeitado = customtkinter.CTkToplevel(janela)
        janela_email_rejeitado.title("Projeto e-mails")
        janela_email_rejeitado.geometry("400x650+900+10")

        email_rejeitado_label = customtkinter.CTkLabel(master = janela_email_rejeitado, text = "E-mails rejeitados pelo\n Outlook", font = customtkinter.CTkFont(size=16, weight = "bold"))
        email_rejeitado_label.pack(padx=10, pady=(20,10))

        tamanho_lista_email_rejeitado = len(email_rejeitado_df)

        exibir_email_rejeitado = customtkinter.CTkScrollableFrame(janela_email_rejeitado, width=300, height=400)
        exibir_email_rejeitado.pack(padx=10, pady=10)

        tabela_email_rejeitado= pd.read_excel("emails_rejeitados_pelo_outlook.xlsx")
        apresentar_email_rejeitado = tabela_email_rejeitado[['rejeitados']] #puxar colunas
        email_rejeitado_scrolabletext1= customtkinter.CTkLabel(exibir_email_rejeitado,width=600, text = apresentar_email_rejeitado.head(60))
        email_rejeitado_scrolabletext1.pack(padx=10, pady=10)

        tamanho_lista_emails_invalidos_label1= customtkinter.CTkLabel(janela_email_rejeitado, text = f"Número de emails rejeitados pelo Outlook: {tamanho_lista_email_rejeitado}")
        tamanho_lista_emails_invalidos_label1.pack(padx=0, pady=0)

        botao_eliminar_email_rejeitado = customtkinter.CTkButton(janela_email_rejeitado, text = " Eliminar emails rejeitados da lista completa ", corner_radius=8, command = clique_eliminar_rejeitados_outlook)
        botao_eliminar_email_rejeitado.pack(padx=10, pady=10)

        botao_voltar = customtkinter.CTkButton(janela_email_rejeitado, text = " Voltar ", corner_radius=8, command = janela_email_rejeitado.destroy)
        botao_voltar.pack(padx=10, pady=10)
        pass

    # VERIFICAR SE OS EMAILS ESTÃO CORRETAMENTE PREENCHIDOS
    def clique_verificar_emails():
        #importar emails
        tabela_emails_a_verificar= pd.read_excel("dados_emails.xlsx")
        emails_a_verificar = tabela_emails_a_verificar[['emails']] #puxar colunas

        #importar excel dos dominios que foram acrescentados
        tabela_dominios_a_verificar= pd.read_excel("dominios.xlsx")
        dominios_a_verificar = tabela_dominios_a_verificar['dominios'] #puxar colunas
        dominios_a_verificar_lista = dominios_a_verificar.tolist()

        #deletar registos duplicados
        emails_a_verificar=emails_a_verificar.drop_duplicates()
        lista_bons_dominios=[]
        emails_invalidos = []
        for email_a_verificar in emails_a_verificar['emails']:
            email_a_verificar=email_a_verificar.lower()
            # verificar dominios mais comuns
            p1 = r'@gmail.com$'
            p2 = r'@hotmail.com$'
            p3 = r'@outlook.com$'
            p4 = r'@outlook.pt$'
            p5 = r'@yahoo.com$'
            p6 = r'@sapo.pt$'
            p7 = r'@topdata.pt$'

            p9 = r'\s' #verificar espaços
            p10= r'"' #verificar aspas
            p11= r',' #verificar virgulas
            p12= r'[A-Za-z0-9_.+-]+@[A-Za-z0-9_.+-]+@[A-Za-z0-9_.+-]' #verificar tem 2 @ intercalados
            p13=r'@{2,}'#verificar tem 2 @ seguidos

            # V E R I F I C A R   S E   T E M :
            if re.findall(p9,email_a_verificar):
                #print("TEM ESPAÇOS: |",email_a_verificar,"|")
                emails_invalidos.append(email_a_verificar)
            elif re.findall(p10,email_a_verificar):
                #print("TEM ASPAS: |",email_a_verificar,"|")
                emails_invalidos.append(email_a_verificar)
            elif re.findall(p11,email_a_verificar):
                #print("TEM vírgula: |",email_a_verificar,"|")
                emails_invalidos.append(email_a_verificar)
            elif re.findall(p12,email_a_verificar):
                #print("dois arrobas: |", email_a_verificar, "|")
                emails_invalidos.append(email_a_verificar)
            elif re.findall(p13,email_a_verificar):
                #print("dois arrobas: |", email_a_verificar, "|")
                emails_invalidos.append(email_a_verificar)

            elif re.findall(p1,email_a_verificar): a=1
            elif re.findall(p2,email_a_verificar): a=1
            elif re.findall(p3,email_a_verificar): a=1
            elif re.findall(p4,email_a_verificar): a=1
            elif re.findall(p5,email_a_verificar): a=1
            elif re.findall(p6,email_a_verificar): a=1
            elif re.findall(p7,email_a_verificar): a=1

            #se tiver um problema é adicionado aos invalidos
            else:
                for dominio in dominios_a_verificar_lista:
                    if re.findall(dominio,email_a_verificar):
                        lista_bons_dominios.append(email_a_verificar)
                        continue
                    else:
                        emails_invalidos.append(email_a_verificar)

        dicionarios_invalidos = {'emails':emails_invalidos,'indice':emails_invalidos }
        emails_invalidos_df = pd.DataFrame( dicionarios_invalidos,columns=['emails'], index= emails_invalidos)
        emails_invalidos_df = emails_invalidos_df.drop_duplicates()

        for dominios in lista_bons_dominios:
            emails_invalidos_df = emails_invalidos_df.drop(dominios)

        #guardar a informação num excel - substiui o excel se ele já existir
        file_name_emails_invalidos= 'emails_invalidos.xlsx'
        emails_invalidos_df.to_excel(file_name_emails_invalidos)

        #janela para mostrar os emails que podem ter erros
        janela_emails_invalidos = customtkinter.CTkToplevel(janela)
        janela_emails_invalidos.title("Projeto e-mails")
        janela_emails_invalidos.geometry("400x650+900+10")

        def mostrar_dominios():
            janela_mostrar_dominios = customtkinter.CTkToplevel(janela)
            janela_mostrar_dominios.title("Projeto e-mails")
            janela_mostrar_dominios.geometry("400x650+200+10")
        #caixa de texto
            mostrar_dominios_label = customtkinter.CTkLabel(master = janela_mostrar_dominios, text = " Dominios adicionados", font = customtkinter.CTkFont(size=16, weight = "bold"))
            mostrar_dominios_label.pack(padx=10, pady=(20,10))

        #mostrar excel
            mostrar_dominios_excel = pd.read_excel("dominios.xlsx")
            mostrar_dominios_emails = mostrar_dominios_excel[['dominios']]

            mostrar_dominios_tamanho_lista = len(mostrar_dominios_emails['dominios'])

            mostrar_dominios_frame = customtkinter.CTkScrollableFrame(janela_mostrar_dominios, width=300, height=360)
            mostrar_dominios_frame.pack(padx=10, pady=10)
            mostrar_dominios_scrolabletext= customtkinter.CTkLabel(mostrar_dominios_frame, text = mostrar_dominios_emails[['dominios']].head(60))
            mostrar_dominios_scrolabletext.pack(padx=10, pady=10)

            mostrar_dominios_tamanho_lista_label1= customtkinter.CTkLabel(janela_mostrar_dominios, text = f"Número de domínios adicionados: {mostrar_dominios_tamanho_lista}")
            mostrar_dominios_tamanho_lista_label1.pack(padx=0, pady=0)

            def clique_eliminar_mostrar_dominios():
                tabela_dominios_eliminar= pd.read_excel("dominios.xlsx")
                dominios_eliminar = tabela_dominios_eliminar[['dominios']] #puxar colunas

                indice_eliminar = int(eliminar_mostrar_dominios_entry.get())
                dominios_eliminar = dominios_eliminar.drop([indice_eliminar],axis=0)

                file_name_dominios_eliminar = 'dominios.xlsx'
                dominios_eliminar.to_excel(file_name_dominios_eliminar)

                #janela de confirmação
                janela_dominios_eliminar_confirmacao = customtkinter.CTkToplevel(janela)
                janela_dominios_eliminar_confirmacao.title("Projeto e-mails ")
                janela_dominios_eliminar_confirmacao.geometry("300x150+400+100")

                alterar_n_emails_label = customtkinter.CTkLabel(janela_dominios_eliminar_confirmacao, text = "Dominio eliminados", font = customtkinter.CTkFont(size=16, weight = "bold"))
                alterar_n_emails_label.pack(padx=10, pady=(20,10))

                botao_voltar = customtkinter.CTkButton(janela_dominios_eliminar_confirmacao, text = " Voltar ", corner_radius=8, command = janela_dominios_eliminar_confirmacao.destroy)
                botao_voltar.pack(padx=10, pady=10)

            #label informar que é para colocar o numero do indice que se encontra antes do email
            eliminar_mostrar_dominios_label = customtkinter.CTkLabel(janela_mostrar_dominios, text = "Indique o numero do indice do domínio que pretende eliminar:")
            eliminar_mostrar_dominios_label.pack(padx=0, pady=0)
            #entry indice do dominio a eliminar
            eliminar_mostrar_dominios_entry = customtkinter.CTkEntry(janela_mostrar_dominios, width=40, placeholder_text= "Numero")
            eliminar_mostrar_dominios_entry.pack(padx=0, pady=0)
            #botão de fazer evento
            eliminar_mostrar_dominios_botao = customtkinter.CTkButton(janela_mostrar_dominios, width=80, text = " Eliminar ", corner_radius=8, command = clique_eliminar_mostrar_dominios)
            eliminar_mostrar_dominios_botao.pack(padx=10, pady=10)

            botao_voltar = customtkinter.CTkButton(janela_mostrar_dominios, text = " Voltar ", corner_radius=8, command = janela_mostrar_dominios.destroy)
            botao_voltar.pack(padx=10, pady=10)
            pass

        emails_invalidos_label = customtkinter.CTkLabel(master = janela_emails_invalidos, text = "E-mails possivelmente \ninválidos", font = customtkinter.CTkFont(size=16, weight = "bold"))
        emails_invalidos_label.pack(padx=10, pady=(20,10))

        tamanho_lista_emails_invalidos = len(emails_invalidos_df)

        exibir_emails_invalidos = customtkinter.CTkScrollableFrame(janela_emails_invalidos, width=300, height=360)
        exibir_emails_invalidos.pack(padx=10, pady=10)

        tabela_apresentar_invalidos= pd.read_excel("emails_invalidos.xlsx")
        apresentar_invalidos = tabela_apresentar_invalidos[['emails']] #puxar colunas
        scrolabletext1= customtkinter.CTkLabel(exibir_emails_invalidos,width=600, text = apresentar_invalidos.head(60))
        scrolabletext1.pack(padx=10, pady=10)

        tamanho_lista_emails_invalidos_label1= customtkinter.CTkLabel(janela_emails_invalidos, text = f"Número de emails possivelmente inválidos: {tamanho_lista_emails_invalidos}")
        tamanho_lista_emails_invalidos_label1.pack(padx=0, pady=0)

        # Botão HELP
        def emails_invalidos_informacoes():
            janela_emails_invalidos_informacoes = customtkinter.CTkToplevel(janela)
            janela_emails_invalidos_informacoes.title("Projeto e-mails")
            janela_emails_invalidos_informacoes.geometry("400x650+200+10")

            emails_invalidos_informacoes_label1 = customtkinter.CTkLabel(janela_emails_invalidos_informacoes, text = "Se na lista aparecer \n\nEmpty DataFrame \nColumns:[] \nIndex: []\n\n significa que não foram identificados emails para reparar")
            emails_invalidos_informacoes_label1.pack(padx=10, pady=10)
            separador_de_informação = customtkinter.CTkLabel(janela_emails_invalidos_informacoes, text = " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
            separador_de_informação.pack(padx=10, pady=5)
            emails_invalidos_informacoes_label2 = customtkinter.CTkLabel(janela_emails_invalidos_informacoes, text = "Se aparecer: \n\n emails indice \n ----- ----- ----- \n \n também significa que o excel está vazio")
            emails_invalidos_informacoes_label2.pack(padx=10, pady=10)
            separador_de_informação2 = customtkinter.CTkLabel(janela_emails_invalidos_informacoes, text = " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
            separador_de_informação2.pack(padx=10, pady=5)
            emails_invalidos_informacoes_label3 = customtkinter.CTkLabel(janela_emails_invalidos_informacoes, text = "A lista de domínios deve ter 3 ou mais domínios \n para não dar problemas")
            emails_invalidos_informacoes_label3.pack(padx=10, pady=10)

            botao_voltar = customtkinter.CTkButton(janela_emails_invalidos_informacoes, text = " Voltar ", corner_radius=8, command = janela_emails_invalidos_informacoes.destroy)
            botao_voltar.pack(padx=10, pady=10)
            pass

        #def clique_botao_emails_invalidos():
        #        tabela_apresentar_invalidos_eliminar= pd.read_excel("emails_invalidos.xlsx")
        #        apresentar_invalidos_eliminar = tabela_apresentar_invalidos_eliminar[['emails']] #puxar colunas
        #
        #        email_indice_eliminar = int(botao_emails_invalidos_entry.get())
        #        print(email_indice_eliminar)

        botao_emails_invalidos_informacoes = customtkinter.CTkButton(janela_emails_invalidos, text = "Help",width=20, corner_radius=8, command = emails_invalidos_informacoes)
        botao_emails_invalidos_informacoes.place(x=10,y=10)

        #label informar que é para colocar o numero do indice que se encontra antes do email
        #botao_emails_invalidos_label = customtkinter.CTkLabel(janela_emails_invalidos, text = "Indique o numero do indice do email que pretende eliminar:")
        #botao_emails_invalidos_label.pack(padx=0, pady=0)
        #entry indice do dominio a eliminar
        #botao_emails_invalidos_entry = customtkinter.CTkEntry(janela_emails_invalidos, width=40, placeholder_text= "Numero")
        #botao_emails_invalidos_entry.place(x=100, y=520)
        #botão de fazer evento
        #botao_emails_invalidos_botao = customtkinter.CTkButton(janela_emails_invalidos, width=80, text = " Eliminar ", corner_radius=8, command = clique_botao_emails_invalidos)
        #botao_emails_invalidos_botao.place(x=160, y=520)

        botao_mostrar_dominios = customtkinter.CTkButton(janela_emails_invalidos, text = " Mostrar domínios adicionados ", corner_radius=8, command = mostrar_dominios)
        botao_mostrar_dominios.pack(padx=10, pady=10)

        botao_voltar = customtkinter.CTkButton(janela_emails_invalidos, text = " Voltar ", corner_radius=8, command = janela_emails_invalidos.destroy)
        botao_voltar.pack(padx=10, pady=10)

        pass

    # ADICIONAR DOMINIOS À LISTA DE VERIFICAÇÃO
    def clique_adicionar_dominio():
        tabela_adicionar_dominio= pd.read_excel("dominios.xlsx")
        adicionar_dominio = tabela_adicionar_dominio['dominios'] #puxar colunas
        adicionar_dominio_list = adicionar_dominio.tolist() #criar lista

        dominio = adicionar_dominio_entry.get()

        regex_dominio = re.compile(r'@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')
        if re.fullmatch(regex_dominio,dominio):
            adicionar_dominio_list.append(dominio)# adicionado à lista
            print(adicionar_dominio_list)
            dicionario = {'dominios':adicionar_dominio_list}
            adicionar_dominio_serie=pd.DataFrame(dicionario)

            novo_dominio_guardar_file = "dominios.xlsx"
            adicionar_dominio_serie.to_excel(novo_dominio_guardar_file)
            adicionar_dominio_entry.delete(0,END)

            janela_adicionar_dominio = customtkinter.CTkToplevel(janela)
            janela_adicionar_dominio.title("Projeto e-mails ")
            janela_adicionar_dominio.geometry("300x150+900+100")

            adicionar_dominio_label = customtkinter.CTkLabel(master = janela_adicionar_dominio, text = "Dominio adicionado \ncom sucesso", font = customtkinter.CTkFont(size=16, weight = "bold"))
            adicionar_dominio_label.pack(padx=10, pady=(20,10))
            botao_voltar = customtkinter.CTkButton(janela_adicionar_dominio, text = " Voltar ", corner_radius=8, command = janela_adicionar_dominio.destroy)
            botao_voltar.pack(padx=10, pady=10)
        else:
            janela_erro_adicionar_dominio = customtkinter.CTkToplevel(janela, fg_color="red")
            janela_erro_adicionar_dominio.title("Projeto e-mails - Erro")
            janela_erro_adicionar_dominio.geometry("300x150+900+100")

            erro_adicionar_dominio_label = customtkinter.CTkLabel(master = janela_erro_adicionar_dominio, text = "Ocorreu um erro, \nverifique se começou por @ e \nse o dominio está bem escrito", font = customtkinter.CTkFont(size=16, weight = "bold"))
            erro_adicionar_dominio_label.pack(padx=10, pady=(20,10))
            botao_voltar = customtkinter.CTkButton(janela_erro_adicionar_dominio, text = " Voltar ", corner_radius=8, command = janela_erro_adicionar_dominio.destroy)
            botao_voltar.pack(padx=10, pady=10)
        pass

    # ALTERAR TEMPO ENTRE ENVIO DE EMAILS AUTOMÁTICOS
    def clique_emails_automaticos_tempo():
        try:
            #vou guardar no txt
            with open("emails_automaticos_tempo.txt","w", encoding = "utf-8") as emails_automaticos_tempo_arq:
                emails_automaticos_tempo_arq.write(emails_automaticos_tempo_entry.get())
            #vou buscar
            with open("emails_automaticos_tempo.txt","r", encoding = "utf-8") as emails_automaticos_tempo_arq:
                emails_automaticos_tempo = emails_automaticos_tempo_arq.read()
            #vou verificar
            #caso correto vou guardar
            emails_automaticos_tempo1 = int(emails_automaticos_tempo)
            if emails_automaticos_tempo1 > 0 :
                janela_emails_automaticos_tempo = customtkinter.CTkToplevel(janela_outras_opcoes)
                janela_emails_automaticos_tempo.title("Projeto e-mails")
                janela_emails_automaticos_tempo.geometry("300x150+900+100")

                alterar_n_emails_label = customtkinter.CTkLabel(janela_emails_automaticos_tempo, text = "Tempo Alterado", font = customtkinter.CTkFont(size=16, weight = "bold"))
                alterar_n_emails_label.pack(padx=10, pady=(20,10))

                botao_voltar = customtkinter.CTkButton(janela_emails_automaticos_tempo, text = " Voltar ", corner_radius=8, command = janela_emails_automaticos_tempo.destroy)
                botao_voltar.pack(padx=10, pady=10)
            pass
        except ValueError:
            #janela de erro devido ao caracter inserido ser inválido
            janela_emails_automaticos_tempo_erro_valor = customtkinter.CTkToplevel(janela, fg_color="red")
            janela_emails_automaticos_tempo_erro_valor.title("Projeto e-mails - Erro")
            janela_emails_automaticos_tempo_erro_valor.geometry("300x150+900+100")

            with open("emails_automaticos_tempo.txt","w", encoding = "utf-8") as emails_automaticos_tempo_arq:
                emails_automaticos_tempo_arq.write("60")
            lista_original_nao_encontrada_label1 = customtkinter.CTkLabel(janela_emails_automaticos_tempo_erro_valor, text = "O que inseriu não é numero", font = customtkinter.CTkFont(size=16, weight = "bold"))
            lista_original_nao_encontrada_label1.pack(padx=10, pady=(20,0))
            lista_original_nao_encontrada_label2 = customtkinter.CTkLabel(janela_emails_automaticos_tempo_erro_valor, text = "Vai ser reposto o tempo original de 1 hora")
            lista_original_nao_encontrada_label2.pack(padx=10, pady=0)
            botao_voltar = customtkinter.CTkButton(janela_emails_automaticos_tempo_erro_valor, text = " Voltar ", corner_radius=8, command = janela_emails_automaticos_tempo_erro_valor.destroy)
            botao_voltar.pack(padx=10, pady=10)
            pass

    # SWITCH PARA LIGAR E DESLIGAR OS ENVIOS AUTOMÁTICOS
    def switch_emails_automaticos_tempo():
        #print("valor switch emails automaticos tempo->", switch_var1.get())
        with open("emails_automaticos_tempo_ativo.txt","w", encoding = "utf-8") as emails_automaticos_tempo_ativo_arq:
            emails_automaticos_tempo_ativo = emails_automaticos_tempo_ativo_arq.write(switch_var1.get())
        pass

    def clique_email_final_lista():
        #ir buscar o que foi escrito na entry
        with open("email_para_avisos.txt","w", encoding = "utf-8") as email_para_avisos_arq:
            email_para_avisos = email_para_avisos_arq.write(email_para_avisos_entry.get())
        #janela de confirmação
        janela_email_para_avisos = customtkinter.CTkToplevel(janela_outras_opcoes)
        janela_email_para_avisos.title("Projeto e-mails ")
        janela_email_para_avisos.geometry("300x150+900+100")

        email_para_avisos_label = customtkinter.CTkLabel(janela_email_para_avisos, text = "E-mail para avisos alterado", font = customtkinter.CTkFont(size=16, weight = "bold"))
        email_para_avisos_label.pack(padx=10, pady=(20,10))

        botao_voltar = customtkinter.CTkButton(janela_email_para_avisos, text = " Voltar ", corner_radius=8, command = janela_email_para_avisos.destroy)
        botao_voltar.pack(padx=10, pady=10)
        pass

    # C O M P O N E N T E S   D A   J A N E L A   -   O U T R A S   O P Ç Õ E S
    # NUMERO DE EMAILS
    n_emails_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Quantidade de e-mails a enviar:")
    n_emails_label.place(x=20,y=10)
        #ir buscar a informação que já está guardada no bloco de notas para se saber o que tem lá guardado
    with open("numero_envios.txt", "r", encoding = "utf-8") as numero_envios_arq:
            n_requerido_envios = int(numero_envios_arq.read())
    n_emails = customtkinter.CTkEntry(outras_opcoes_frame, width=40, placeholder_text= n_requerido_envios)
    n_emails.place(x=210, y=10)
    botao_n_emails = customtkinter.CTkButton(outras_opcoes_frame, width=80, text = " Alterar ", corner_radius=8, command = clique_alterar_n_emails)
    botao_n_emails.place(x=260, y=10)

    # ALTERAR EMAIL DE TESTES
    alterar_email_teste_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Alterar e-mail de testes:")
    alterar_email_teste_label.place(x=20,y=50)
    with open("email_teste.txt", "r", encoding = "utf-8") as teste_email_arq:
            teste_email = teste_email_arq.read()
    alterar_email_teste_entry = customtkinter.CTkEntry(outras_opcoes_frame, width=200, placeholder_text= teste_email)
    alterar_email_teste_entry.place(x=20, y=80)
    alterar_email_teste_botao = customtkinter.CTkButton(outras_opcoes_frame, width=80, text = " Alterar ", corner_radius=8, command = clique_alterar_email)
    alterar_email_teste_botao.place(x=260, y=80)

    # IMPORTAÇÃO DE NOVA LISTA DE EMAILS
    nova_lista_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Importar lista de e-mails nova:")
    nova_lista_label.place(x=20,y=120)
    botao_nova_lista = customtkinter.CTkButton(outras_opcoes_frame, width=80, text = " Importar ", corner_radius=8, command = clique_nova_lista)
    botao_nova_lista.place(x=260, y=120)

    # SWITCH PARA LIGAR E DESLIGAR A REPOSIÇÃO AUTOMÁTICA
    #primeiro tenho de ler o que esá guardado
    with open("reposicao_automatica.txt","r", encoding = "utf-8") as reposicao_automatica_arq:
            reposicao_automatica = reposicao_automatica_arq.read()
    switch_var = customtkinter.StringVar(value=reposicao_automatica)
    reposicao_automatica_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Reposição automatica OFF / ON:")
    reposicao_automatica_label.place(x=20,y=160)
    reposicao_automatica_switch = customtkinter.CTkSwitch(outras_opcoes_frame, text=None, switch_width=50, command = switch_reposicao_automatica, variable=switch_var, onvalue="True", offvalue="False")
    reposicao_automatica_switch.place(x=280, y=160)

    # JANELA COM OS EMAILS REJEITADOS PELO OUTLOOK
    rejeitados_outlook_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "E-mails rejeitados pelo Outlook:")
    rejeitados_outlook_label.place(x=20,y=200)
    rejeitados_outlook_botao = customtkinter.CTkButton(outras_opcoes_frame, width=120, text = " Ver lista ", corner_radius=8, command = clique_rejeitados_outlook)
    rejeitados_outlook_botao.place(x=220, y=200)

    # VERIFICAR SE OS EMAILS ESTÃO CORRETAMENTE PREENCHIDOS
    verificar_emails_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Verificar erros em e-mails: ")
    verificar_emails_label.place(x=20,y=240)
    verificar_emails_botao = customtkinter.CTkButton(outras_opcoes_frame, width=120, text = " Verificar E-mails ", corner_radius=8, command = clique_verificar_emails)
    verificar_emails_botao.place(x=220, y=240)

    # ADICIONAR DOMINIO
    adicionar_dominio_entry = customtkinter.CTkEntry(outras_opcoes_frame, width=200, placeholder_text= "@dominio.pt")
    adicionar_dominio_entry.place(x=20, y=280)
    adicionar_dominio_botao = customtkinter.CTkButton(outras_opcoes_frame, width=80, text = " Adicionar ", corner_radius=8, command = clique_adicionar_dominio)
    adicionar_dominio_botao.place(x=260, y=280)

    # ALTERAR TEMPO ENTRE ENVIO DE EMAILS AUTOMÁTICOS
    emails_automaticos_tempo_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Tempo entre envios, em minutos")
    emails_automaticos_tempo_label.place(x=20,y=320)
    with open("emails_automaticos_tempo.txt", "r", encoding = "utf-8") as emails_automaticos_tempo_arq:
            emails_automaticos_tempo = int(emails_automaticos_tempo_arq.read())
    emails_automaticos_tempo_entry = customtkinter.CTkEntry(outras_opcoes_frame, width=40, placeholder_text= emails_automaticos_tempo)
    emails_automaticos_tempo_entry.place(x=210, y=320)
    botao_emails_automaticos_tempo = customtkinter.CTkButton(outras_opcoes_frame, width=80, text = " Alterar ", corner_radius=8, command = clique_emails_automaticos_tempo)
    botao_emails_automaticos_tempo.place(x=260, y=320)

    # SWITCH PARA LIGAR E DESLIGAR OS ENVIOS AUTOMÁTICOS
    with open("emails_automaticos_tempo_ativo.txt","r", encoding = "utf-8") as emails_automaticos_tempo_ativo_arq:
            emails_automaticos_tempo_ativo = emails_automaticos_tempo_ativo_arq.read()
    switch_var1 = customtkinter.StringVar(value=emails_automaticos_tempo_ativo)
    emails_automaticos_tempo_ativo_label = customtkinter.CTkLabel(outras_opcoes_frame, text = "Envio automatico OFF / ON:")
    emails_automaticos_tempo_ativo_label.place(x=20,y=360)
    emails_automaticos_tempo_ativo_switch = customtkinter.CTkSwitch(outras_opcoes_frame, text=None, switch_width=50, command = switch_emails_automaticos_tempo,
                                                                    variable=switch_var1, onvalue="True", offvalue="False")
    emails_automaticos_tempo_ativo_switch.place(x=280, y=360)

    email_para_avisos_label_ = customtkinter.CTkLabel(outras_opcoes_frame, text = "Alterar e-mail para avisos:")
    email_para_avisos_label_.place(x=20,y=400)
    with open("email_para_avisos.txt", "r", encoding = "utf-8") as email_para_avisos_arq:
            email_para_avisos = email_para_avisos_arq.read()
    email_para_avisos_entry = customtkinter.CTkEntry(outras_opcoes_frame, width=200, placeholder_text= email_para_avisos)
    email_para_avisos_entry.place(x=20, y=430)
    email_para_avisos_botao = customtkinter.CTkButton(outras_opcoes_frame, width=80, text = " Alterar ", corner_radius=8, command = clique_email_final_lista)
    email_para_avisos_botao.place(x=260, y=430)

    botao_voltar = customtkinter.CTkButton(outras_opcoes_frame, text = " Voltar ", corner_radius=8, command = janela_outras_opcoes.destroy)
    botao_voltar.place(x=110, y=480)

    pass

# C O M P O N E N T E S   D A   J A N E L A   I N I C I A L
titulo = customtkinter.CTkLabel(master = janela, text = " |  Enviar e-mails  | ", font = customtkinter.CTkFont(size=30, weight = "bold"))
titulo.pack(padx=10, pady=(40,20))

botao_emails = customtkinter.CTkButton(janela, text = " Enviar e-mails ", corner_radius=8, command = clique_enviar_emails)
botao_emails.pack(padx=10, pady=10)

botao_email_teste = customtkinter.CTkButton(janela, text = " Enviar e-mail teste ", corner_radius=8, command = clique_enviar_email_teste)
botao_email_teste.pack(padx=10, pady=10)

botao_mensagem = customtkinter.CTkButton(janela, text = " Mudar a mensagem ", corner_radius=8, command = clique_mudar_email)
botao_mensagem.pack(padx=10, pady=10)

botao_mostrar_emails = customtkinter.CTkButton(janela, text = " Mostrar e-mails ", corner_radius=8, command = clique_mostrar_emails)
botao_mostrar_emails.pack(padx=10, pady=10)

botao_outros_opcoes = customtkinter.CTkButton(janela, text = " Outras opções ", corner_radius=8, command = clique_outras_opcoes)
botao_outros_opcoes.pack(padx=10, pady=10)

botao_sair = customtkinter.CTkButton(janela, text = " Sair ", corner_radius=8, command = janela.destroy)
botao_sair.pack(padx=10, pady=10)

# L O O P   P A R A   O   P R O G R A M A   E S T A R   S E M P R E   A   C O R R E R
janela.mainloop()


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from bs4 import BeautifulSoup
import time
import pandas as pd
from ssl import Options

options = webdriver.ChromeOptions()
# options.headless = True
options.add_argument("--headless=new")
options.add_argument("window-size=1920x1080")

# browser = webdriver.Chrome(options=options)
browser = webdriver.Chrome()
browser.maximize_window()
rl = 'https://jumin.mois.go.kr/'

time.sleep(1)
browser.get(rl)

iframe = browser.find_element(By.TAG_NAME, "iframe")
browser.switch_to.default_content()
browser.switch_to.frame(iframe)

iframe_source = browser.page_source
# print(iframe_source) #returns iframe source
# print(browser.current_url) #returns iframe URL

select_elements = []

soup = BeautifulSoup(iframe_source)

select_elements = browser.find_elements(By.ID, "searchYearStart")

for i in select_elements:
    select = Select(i)
    select.select_by_value('2022')

for select_element in select_elements:
    select = Select(select_element)
    options = select.options

    for option in options:
        if option.get_attribute("value") == "2022":
            option.click()
            break

selected_option = select.first_selected_option
selected_value = selected_option.get_attribute('value')
selected_text = selected_option.text

print(selected_text)


from bs4 import BeautifulSoup as soup
from urllib.request import urlopen as request

# loading results
client = request('https://phoenixnap.com/kb/linux-commands-cheat-sheet')
page = client.read()
client.close()
results = soup(page, 'html.parser')

# simplifying and processing results
h = results.findAll('p')
work = h[10:144]
task = []
for each in work:
    task.append(each.text.strip())
unprocessedcommands = results.findAll('pre')
commands = []

for each in unprocessedcommands:
    commands.append(each.code.text.strip())

for _ in task:
    if 'Note' in _ or (':' not in _):
        del task[task.index(_)]
del task[task.index('Chown command in Linux changes file and directory ownership.')]

# displaying results
for i in range (126):
    print(str(i+1) + ' ' + task[i])
    print(" ")
    print(commands[i])
    print(" ")


from PIL import Image
import torch
from torchvision.transforms.functional import to_tensor
from natsort import natsorted
import os

def batch_iterator(lst, batch_size):
    for i in range(0, len(lst), batch_size):
        yield lst[i : i + batch_size]

img_dir = "results/image/tcfg64_label817_run0"
device = "cuda"
batch_size = 16
img_list = []

for filename in natsorted(os.listdir(img_dir)):
    if filename.endswith(".png") and not filename.endswith("_list.png"):
        file_path = os.path.join(img_dir, filename)
        img_list.append(file_path)

for i_batch, img_path_batch in enumerate(batch_iterator(img_list, batch_size)):
    inputs = []
    for img_path in img_path_batch:
        # print(f"input img path: {img_path}")
        img = Image.open(img_path)
        img = to_tensor(img)
        inputs.append(img)

    inputs = torch.stack(inputs, dim=0)
    print(f"batch{i_batch} load image: {inputs.shape}")


import argparse
import requests
from bs4 import BeautifulSoup
from collections import Counter

def extract_keywords(url, top_n):
    try:
        response = requests.get(url)
        response.raise_for_status()
        content = response.text

        soup = BeautifulSoup(content, 'html.parser')
        text_content = ' '.join([p.get_text() for p in soup.find_all('p')])

        words = text_content.lower().split()
        word_counts = Counter(words)

        print(f"Top {top_n} Keywords:")
        for word, count in word_counts.most_common(top_n):
            print(f"{word}: {count}")

    except requests.RequestException as e:
        print(f"Error fetching URL: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def main():
    parser = argparse.ArgumentParser(description='Easy SEO Keyword Extractor')
    parser.add_argument('--url', required=True, help='URL of the webpage to analyze')
    parser.add_argument('--top', type=int, default=5, help='Number of top keywords to display')

    args = parser.parse_args()
    extract_keywords(args.url, args.top)

if __name__ == "__main__":
    main()


import math
from typing import Iterable, List, Tuple

class Solution:
    def sampleStats(self, count: List[int]) -> List[float]:
        running_sum = 0
        running_count = 0
        minimum = 1 << 31
        maximum = -1 << 31
        mode = -1
        highest_seen = -1 << 31

        def counts(count: List[int]) -> Iterable[Tuple[int, int]]:
            for i, sample_count in enumerate(count):
                if sample_count > 0:
                    yield i, sample_count

        for i, sample_count in counts(count):
            minimum = min(minimum, i)
            maximum = max(maximum, i)
            running_sum += i * sample_count
            running_count += sample_count
            if highest_seen < sample_count:
                highest_seen = sample_count
                mode = i

        mean = running_sum / running_count

        median = 0
        median_counter = math.ceil(running_count / 2)
        median_requires_midpoint = running_count % 2 == 0

        generator = counts(count)
        while median_counter > 0:
            i, sample_count = next(generator)
            median_counter -= sample_count
        median = i
        if median_requires_midpoint and median_counter == 0:
            j, _ = next(generator)
            median = (i + j) / 2

        return float(minimum), float(maximum), float(mean), float(median), float(mode)


import bs4

import time

import requests

import keyboard
link = "https://www.google.com/search?client=opera-gx&q=доллар+к+рублю&sourceid=opera&ie=UTF-8&oe=UTF-8"

headers = {
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.441"}

page = requests.get(link, headers)

soup = bs4.BeautifulSoup(page.content, "html.parser")

def check_the_dollar_to_ruble():

                da_number = soup.findAll("div", {"class": "BNeawe iBp4i AP7Wnd"})

                ruble = da_number[1].text

                print("Сейчас 1 доллар стоит", ruble, sep=' ')

while True:
    if keyboard.is_pressed("shift"):
        break
    else:
        check_the_dollar_to_ruble()

        time.sleep(5)