import sys # 시스템 관련 기능을 제공하는 모듈
from PyQt5 import QtCore, QtGui, QtWidgets # PyQt5 라이브러리에서 QtCore, QtGui, QtWidgets 모듈을 가져옴
import requests # HTTP 요청을 보내고 응답을 받기 위한 라이브러리
import time # 시간 관련 기능을 제공하는 모듈
import webbrowser # 웹 브라우저를 제어하는 모듈
import datetime # 날짜와 시간을 다루기 위한 모듈
from threading import Thread, Event # 쓰레드 기능과 이벤트 처리를 위한 모듈
import os # 운영 체제와 상호작용하는 기능을 제공하는 모듈
# 프로그램의 설정값
Title = "ㅇㅇㅇ 대기방" # 프로그램 제목창에 표시될 이름
channel_id = "458f6ec20b034f49e0fc6d03921646d2" # 스트리머 채널의 ID
background = "background.png" # 배경 이미지 파일 이름 (720x540 크기, 4:3 비율)
# 배경 이미지 파일은 이 코드파일(knockknock.py)와 동일한 경로에 있어야 함.
# PyInstaller를 통해 EXE 파일로 만들 때 다음과 같은 형식으로 추가할 수 있음:
# pyinstaller --onefile --windowed --add-data "background.png;." knockknock.py
# 방송 대기 프로그램의 핵심 기능을 수행하는 Worker 클래스
class Worker(Thread):
def __init__(self, channel_id, refresh, text_edit):
super().__init__() # Thread 클래스의 초기화
self.channel_id = channel_id # 채널 ID 설정
self.refresh = refresh # 새로 고침 주기 설정
self.text_edit = text_edit # 결과를 표시할 QTextEdit 객체
self._stop_event = Event() # 스레드 종료를 위한 이벤트 객체
def run(self):
# 스레드가 실행되는 동안 계속 반복
while not self._stop_event.is_set():
try:
headers = {'User-Agent': 'Mozilla/5.0'} # 봇으로 인식되지 않게 하기 위한 헤더
request = requests.get(f"https://[Log in to view URL]", headers=headers) # API 요청
channel_info = request.json().get("content") # JSON 형식으로 응답을 파싱
open_live = channel_info.get("openLive") # 방송 여부 확인
channel_name = channel_info.get("channelName") # 채널 이름 정보
if open_live: # 방송 중인 경우
self.text_edit.append(f"{channel_name} 방송이 켜졌습니다! 10초 후에 접속합니다...")
for i in range(10, 0, -1): # 10초 카운트 다운
if self._stop_event.is_set(): # 스레드가 종료 요청된 경우
return
self.text_edit.append(f"{channel_name} 방송이 켜졌습니다! {i}초 남았습니다...")
time.sleep(1) # 1초 대기
webbrowser.open(f"https://[Log in to view URL]", new=0) # 방송 링크 열기
return
# 방송이 아닐 경우
date = datetime.datetime.today().strftime('%H:%M:%S') # 현재 시간 가져오기
self.text_edit.append(f'[{date}] {channel_name} 방송 대기중, {self.refresh}초 후 다시 확인합니다...')
time.sleep(self.refresh) # 새로 고침 주기만큼 대기
except requests.exceptions.RequestException as e: # 요청 예외 처리
self.text_edit.append(f"오류 발생: {e}")
def stop(self):
self._stop_event.set() # 스레드 종료 요청
# GUI 관련 코드
class Ui_Form(object):
def __init__(self):
self.worker = None # Worker 객체 초기화
def setupUi(self, Form):
Form.setObjectName('Form') # 폼 객체 이름 설정
Form.resize(780, 640) # 폼 크기 설정
# START 버튼 UI 설정
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(30, 20, 75, 23)) # 버튼 위치 및 크기 설정
self.pushButton.setObjectName("pushButton") # 버튼 이름 설정
self.pushButton.clicked.connect(self.start_checking) # 버튼 클릭 시 start_checking 메서드 연결
# STOP 버튼 UI 설정
self.pushButton_2 = QtWidgets.QPushButton(Form)
self.pushButton_2.setGeometry(QtCore.QRect(675, 20, 75, 23)) # 버튼 위치 및 크기 설정
self.pushButton_2.setObjectName("pushButton_2") # 버튼 이름 설정
self.pushButton_2.clicked.connect(self.stop_program) # 버튼 클릭 시 stop_program 메서드 연결
# 결과가 출력될 UI 설정
self.background_label = QtWidgets.QLabel(Form)
self.background_label.setGeometry(QtCore.QRect(30, 70, 720, 540)) # 레이블 위치 및 크기 설정
# 배경 이미지를 QLabel에 설정
image_path = os.path.join(os.path.dirname(__file__), background) # 현재 디렉토리의 이미지 경로
self.background_pixmap = QtGui.QPixmap(image_path) # 이미지 로드
self.background_label.setPixmap(self.background_pixmap) # QLabel에 배경 이미지 설정
self.background_label.setScaledContents(True) # QLabel 크기에 맞게 이미지 비율 조절
# 결과 출력창에 대한 설정
self.textEdit = QtWidgets.QTextEdit(Form) # QTextEdit 객체 생성
self.textEdit.setGeometry(QtCore.QRect(30, 70, 720, 540)) # 텍스트 편집기 위치 및 크기 설정
# 스타일 시트 수정: 글자 크기, 색상, 굵기, 배경 투명화
self.textEdit.setStyleSheet("color: black; font-size: 12px; font-weight: bold; "
"background: transparent; padding: 5px; "
"border: none;") # 테두리 없음
self.textEdit.setReadOnly(True) # 텍스트 편집기를 읽기 전용으로 설정
self.retranslateUi(Form) # UI 텍스트 번역 설정
QtCore.QMetaObject.connectSlotsByName(Form) # 슬롯과 신호 연결
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate # 텍스트 변환 함수
Form.setWindowTitle(_translate("Form", Title)) # 창 제목 설정
self.pushButton.setText(_translate("Form", "Start")) # START 버튼 텍스트 설정
self.pushButton_2.setText(_translate("Form", "Stop")) # STOP 버튼 텍스트 설정
# 방송 확인 새로 고침 주기 설정
def start_checking(self):
if self.worker is None: # Worker가 None인 경우 (즉, 실행 중이지 않은 경우)
refresh = 5 # 새로 고침 주기 (5초)
self.worker = Worker(channel_id, refresh, self.textEdit) # Worker 객체 생성
self.worker.start() # Worker 스레드 시작
# 프로그램 정지 버튼 기능
def stop_program(self):
if self.worker is not None: # Worker가 실행 중인 경우
self.worker.stop() # Worker 종료 요청
self.worker.join() # Worker 스레드 종료 대기
self.worker = None # Worker 객체 초기화
self.textEdit.append("프로그램이 정지되었습니다.") # 정지 메시지 출력
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv) # QApplication 객체 생성
Form = QtWidgets.QWidget() # QWidget 객체 생성
ui = Ui_Form() # Ui_Form 객체 생성
ui.setupUi(Form) # UI 설정
Form.show() # 폼을 화면에 표시
sys.exit(app.exec_()) # 애플리케이션 실행
To embed this project on your website, copy the following code and paste it into your website's HTML: