코딩 프로젝트

GPTS를 활용한 AI캐릭터 만들기 - Project AL-1S(2)

hajin1209 2024. 5. 31. 00:20

계획

GPTS의 답변을 UI로 주고받는 채팅 프로그램 개발

이건 만든 UI인데... 글꼴 변경이 죽어도 안됨....

 

SELENIUM을 활용해서 입력창에 입력한 글을 GPT로 옮기고 GPT의 답변을 대화창으로 가져온다.

 

API를 물리적으로 가져와 GPT결제만 해두면 API값을 안 내도 된다.

 

CODE

더보기
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit, QLineEdit, QLabel, QPushButton
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
from PyQt5.QtGui import QPixmap, QGuiApplication, QFont, QColor, QIcon
from PyQt5.QtCore import Qt, QSize
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import logging
import undetected_chromedriver as uc
import time

class HelperFn:
    def __init__(self, driver):
            self.driver = driver

    def wait_for_element(self, xpath, timeout=22):
        try:
              WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located((By.XPATH, xpath)))
              logging.info("# Element '%s' is present" % xpath)
        except TimeoutException:
              logging.error("# Element '%S' is not present" % xpath)

    def is_element_present(self, xpath):
        try:
              self.driver.find_element(By.XPATH, xpath)
              logging.info("# Element '%s' is present" % xpath)
        except TimeoutException:
              logging.error("# Element '%S' is not present" % xpath)
              return False
        return True

    def wait_for_element_visible(self, xpath, timeout=22):
        try:
             WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located((By.XPATH, xpath)))
        except TimeoutException:
             logging.error("# Element '%s'is not visible" % xpath)

    def is_element_visible(self, xpath):
        try:
             logging.info("# Element '%s' is visible." % xpath)
             return self.driver.find_element(By.XPATH, xpath).is_displayed()
        except NoSuchElementException:
             logging.error("# Element '%s' is not visible." % xpath)
             return False

    def find_element(self, xpath):
        try:
             element = self.driver.find_element(By.XPATH, xpath)
             logging.info("# Element '%s' is found. " % xpath)
        except NoSuchElementException:
             logging.error("# Element '%s' is not found." % xpath)
             return False
        return element


class VisualNovelChat(QWidget):
    def __init__(self, screen_height, gpt):
        super().__init__()
        self.initUI(screen_height)
        self.gpt = gpt


    def initUI(self, screen_height):

        image_aspect_ratio = 16 / 9
        window_height = int(screen_height * 0.4)
        window_width = int(window_height * image_aspect_ratio)

        #창크기와 타이틀
        self.setGeometry(100, 100, window_width, window_height)
        self.setWindowTitle('ChatBot App')

        side_margin = int(window_width * 0.12)

        #배경화면 이미지
        self.background_label = QLabel(self)
        self.background_label.setPixmap(QPixmap('aris_image.png'))
        self.background_label.setScaledContents(True)
        self.background_label.setGeometry(0, 0, window_width, window_height)

        self.background_label = QLabel(self)
        self.background_label.setPixmap(QPixmap('1.png'))
        self.background_label.setScaledContents(True)
        self.background_label.setGeometry(0, int(window_height*0.1), window_width, window_height)


        # 채팅 영역 설정
        chat_area_height = int(window_height * 0.2)
        self.chat_area = QTextEdit(self)
        self.chat_area.setStyleSheet("background-color: rgba(255, 255, 255, 0); border-radius : 10px")
        #shadow effect
        shadow_effect = QGraphicsDropShadowEffect()
        shadow_effect.setBlurRadius(15)
        shadow_effect.setColor(QColor('black'))
        shadow_effect.setOffset(2)
        self.chat_area.setGraphicsEffect(shadow_effect)
        self.chat_area.setGeometry(side_margin, 570, window_height - 2*side_margin, chat_area_height + 50)

        #fonts
        font = QFont('경기천년제목OTF Medium', 10)
        self.chat_area.setFont(font)

        # 입력칸 설정
        input_field_height = 60
        self.input_field = QLineEdit(self)
        self.input_field.setStyleSheet("background-color: rgba(255, 255, 255, 200); border-radius: 15px; padding-left:10px; padding-right:10px")
        self.input_field.setGeometry(side_margin, window_height - input_field_height - 10, window_width - 2*side_margin, input_field_height)
        self.input_field.setFont(font)
        self.input_field.returnPressed.connect(self.handleInput)

        #send button
        self.send_button = QPushButton(self)
        self.send_button.setGeometry(window_width - side_margin - 70, window_height - input_field_height - 5, 50, 50)
        self.send_button.setStyleSheet("padding: 0px; border: none; background-image: url('2.png');")

        #character name label
        self.name_label = QLabel('텐도 아리스', self)
        self.name_label.setFont(QFont('경기천년제목OTF Bold', 20))
        self.name_label.setAlignment(Qt.AlignRight)
        self.name_label.setStyleSheet("background-color: white; border-radius: 2px;")
        self.name_label.setGeometry(side_margin-20, 220, 700, 50)
        self.name_label.setAlignment(Qt.AlignLeft)
        self.name_label.setAlignment(Qt.AlignBottom)
        self.name_label.setStyleSheet("background-color: rgba(255, 255, 255, 0); border-radius: 10px; color : white")

        self.name_label2 = QLabel('게임개발부', self)
        self.name_label2.setFont(QFont('경기천년제목OTF Bold', 14))
        self.name_label2.setAlignment(Qt.AlignRight)
        self.name_label2.setStyleSheet("background-color: white; border-radius: 2px")
        self.name_label2.setGeometry(side_margin+130, 250, 700, 50)
        self.name_label2.setAlignment(Qt.AlignLeft)
        self.name_label2.setStyleSheet("background-color: none; border-radius: 10px; color : rgb(128, 207, 248);")

 
        self.output_lavel = QLabel('', self)
        self.output_lavel.setFont(QFont('경기천년제목OTF Medium', 16))
        self.output_lavel.setAlignment(Qt.AlignRight)

        self.output_lavel.setStyleSheet("background-color: white; border-radius: 2px;")
        self.output_lavel.setGeometry(side_margin, 100, 1150, 200)
        self.output_lavel.setAlignment(Qt.AlignLeft)
        self.output_lavel.setAlignment(Qt.AlignBottom)
        self.output_lavel.setStyleSheet("background-color rgba(255, 255, 255, 0); border-radius: 10px; color : white")


        self.show()

    def handleInput(self):
        text = self.input_field.text()
        self.input_field.clear()
        QApplication.processEvents()
        print("엔터 입력")
        print("입력 타입"+str(type(text))+", 입력값 : "+str(text))
        response = self.gpt.make_gpt_request(text)
        print("handleinput으로 탈출 성공")
        print("타입은"+str(type(response)))
        QApplication.processEvents()
        time.sleep(1)
        self.output_lavel.setText(response.text)
   
        super().__init__()
        self.initUI(screen_height)


logging.basicConfig(format='%(asctime)s - %(levelname)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')


class selenium:
    def __init__(self, driver):
        self.driver = driver
        self.start_chat_gpt(driver)

    def start_chat_gpt(self,driver):
        driver.maximize_window()


    def make_gpt_request(self, text):
        print("make gpt request에 텍스트 받음.")
        time.sleep(1)
        text_area_xpath = "//*[@id='prompt-textarea']"
        helper_fn.wait_for_element(text_area_xpath)
        if helper_fn.is_element_present(text_area_xpath):
            text_area = helper_fn.find_element(text_area_xpath)
            text_area.send_keys(text)


            send_btn_xpath = "//*[@data-testid='send-button']"
            helper_fn.wait_for_element(send_btn_xpath)
            send_btn = helper_fn.find_element(send_btn_xpath)
            time.sleep(1)
            send_btn.click()
        time.sleep(2)
        response_xpath = "//*[@class='markdown prose w-full break-words dark:prose-invert dark']"
        regenerate_xpath = "//*[@class='absolute md:bottom-3 md:right-3 dark:hover:bg-gray-900 dark:disabled:hover:bg-transparent right-2 dark:disabled:bg-white disabled:bg-black disabled:opacity-10 disabled:text-gray-400 enabled:bg-black text-white p-0.5 border border-black rounded-lg dark:border-white dark:bg-white bottom-1.5 transition-colors']"
        helper_fn.wait_for_element(regenerate_xpath, 120)
        if helper_fn.is_element_present(response_xpath):
             print("대답완료")
             response = helper_fn.find_element(response_xpath)[-1]
             print(response.text)
             return response.text
   
    def stop_chat_gpt(self):
      driver.close()        

if __name__ == '__main__':
    options = uc.ChromeOptions()
    driver = uc.Chrome(options=options)
    helper_fn = HelperFn(driver)
    gpt = selenium(driver)

    app = QApplication(sys.argv)
    screen = QGuiApplication.primaryScreen().size().height()
    ex = VisualNovelChat(screen, gpt)
    sys.exit(app.exec_())

근데 문제 발생...

ChatGPT업데이트로 SELENIUM이 답변을 가져오지를 못함...

 

그래서 뻘짓이 됐다 끝