Add files via upload

master
JesterHey 2 years ago committed by GitHub
parent d357047662
commit 29dc7b5562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,45 @@
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
def encrypt_message(message, key):
"""
加密函数
:param message: 要加密的明文消息
:param key: 加密密钥
:return: 密文
"""
# 创建 AES 对象
cipher = AES.new(key, AES.MODE_CBC)
# 对明文进行填充,然后加密
ct_bytes = cipher.encrypt(pad(message.encode(), AES.block_size))
# 将 IV 和密文返回
return cipher.iv, ct_bytes
def decrypt_message(iv, ct, key):
"""
解密函数
:param iv: 初始化向量
:param ct: 密文
:param key: 加密密钥
:return: 解密后的明文
"""
# 创建一个新的 AES 对象
cipher = AES.new(key, AES.MODE_CBC, iv)
# 解密并去除填充
pt = unpad(cipher.decrypt(ct), AES.block_size).decode()
return pt
# 测试
key = get_random_bytes(16) # 生成随机密钥
message = "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"
iv, ct = encrypt_message(message, key)
print("Encrypted:", ct)
pt = decrypt_message(iv, ct, key)
print("Decrypted:", pt)

@ -32,4 +32,6 @@ def upload(name):
bucket.put_object_from_file(name, name)
def delete(name):
bucket.delete_object(name)
bucket.delete_object(name)
delete('18503.json')

@ -1,19 +1,5 @@
from openai import OpenAI
import openai
import os
openai.api_base = "https://api.openai-proxy.com"
openai.api_key = "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"
# os.environ['http_proxy'] = 'http://127.0.0.1:10809'
# os.environ['https_proxy'] = 'http://127.0.0.1:10809'
client = OpenAI(
api_key='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',
base_url='https://api.openai-proxy.com'
)
resp = client.chat.completions.create(
model='gpt-3.5-turbo',
messages=[
{'role': 'user', 'content': '你好!'}
]
)
print(resp.choices[0].message.content)
import json
with open('demo.json','r',encoding='utf-8') as f:
data = json.load(f)
for i,j in enumerate(data.items()):
print(i,j[-1])

@ -1,98 +1,134 @@
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 加载背景图片
self.background = QPixmap('hnu.jpg')
# 创建一个垂直布局
mainLayout = QVBoxLayout()
# 创建三个文本框并设置占位符
self.nameEdit = QLineEdit()
self.pwdEdit = QLineEdit()
self.urlEdit = QLineEdit()
self.nameEdit.setPlaceholderText('Name')
self.pwdEdit.setPlaceholderText('Password')
self.urlEdit.setPlaceholderText('URL')
# 创建一个按钮并连接信号
btn = QPushButton('提交')
btn.clicked.connect(self.onSubmit)
# 对于每个输入框,创建一个水平布局以保持居中
for label_text, edit_widget in [("用户名", self.nameEdit),
("密码", self.pwdEdit),
("实训网址", self.urlEdit)]:
hbox = QHBoxLayout()
hbox.addStretch()
vbox_inner = QVBoxLayout()
vbox_inner.addWidget(QLabel(label_text))
vbox_inner.addWidget(edit_widget)
hbox.addLayout(vbox_inner)
hbox.addStretch()
mainLayout.addLayout(hbox)
# 添加按钮到布局
mainLayout.addWidget(btn, 0, Qt.AlignCenter)
# 设置窗口的布局
self.setLayout(mainLayout)
self.setWindowTitle('')
self.setGeometry(300, 300, 400, 300)
self.centerWindow()
# 应用样式
self.applyStyles()
def paintEvent(self, event):
painter = QPainter(self)
# 计算背景图片绘制的起始坐标,使其位于窗口中心
bgWidth = self.background.width()
bgHeight = self.background.height()
startX = (self.width() - bgWidth) // 2
startY = (self.height() - bgHeight) // 2
painter.drawPixmap(startX, startY, self.background)
def centerWindow(self):
qr = self.frameGeometry()
cp = QApplication.desktop().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def applyStyles(self):
self.setStyleSheet("""
QLineEdit {
border: 1px solid gray;
border-radius: 10px;
padding: 5px;
background: transparent;
}
QLineEdit:focus {
border: 1px solid LightSeaGreen;
}
""")
def onSubmit(self):
name = self.nameEdit.text()
pwd = self.pwdEdit.text()
url = self.urlEdit.text()
print(f"Name: {name}, Password: {pwd}, URL: {url}")
# 关闭窗口
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
ex.show()
sys.exit(app.exec_())
'''
本模块用于创建登录界面并保存用户信息
'''
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt,QTimer
from PyQt5.QtGui import QPixmap, QPainter
import os
import platform
import json
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 加载背景图片
self.background = QPixmap()
# 创建一个垂直布局
mainLayout = QVBoxLayout()
# 创建三个文本框并设置占位符
self.nameEdit = QLineEdit()
self.pwdEdit = QLineEdit()
self.urlEdit = QLineEdit()
# 创建一个按钮并连接信号
btn = QPushButton('提交')
btn.clicked.connect(self.onSubmit)
# 创建一个用于显示错误信息的标签
self.errorLabel = QLabel('', self)
self.errorLabel.hide() # 初始时隐藏该标签
self.setWindowTitle('头歌助手登录')
# 对于每个输入框,创建一个水平布局以保持居中
for label_text, edit_widget in [("用户名", self.nameEdit),
("密 码", self.pwdEdit),
("实训网址", self.urlEdit)]:
hbox = QHBoxLayout()
hbox.addStretch()
vbox_inner = QVBoxLayout()
vbox_inner.addWidget(QLabel(label_text))
vbox_inner.addWidget(edit_widget)
hbox.addLayout(vbox_inner)
hbox.addStretch()
mainLayout.addLayout(hbox)
# 添加按钮和错误信息标签到布局
mainLayout.addWidget(btn, 0, Qt.AlignCenter)
mainLayout.addWidget(self.errorLabel, 0, Qt.AlignCenter)
# 设置窗口的布局
self.setLayout(mainLayout)
self.setGeometry(300, 300, 650, 550)
self.centerWindow()
# 应用样式
self.applyStyles()
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.background)
def centerWindow(self):
qr = self.frameGeometry()
cp = QApplication.desktop().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def applyStyles(self):
self.setStyleSheet("""
QLineEdit {
border: 1px solid gray;
border-radius: 10px;
padding: 5px;
background: rgba(255, 255, 255, 100);
color: black;
width: 300px;
height: 30px;
}
QLineEdit:focus {
border: 3px solid black;
}
QLabel {
color: black;
font-size: 20pt;
font-family: "Microsoft YaHei";
}
QPushButton {
border: 1px solid gray;
border-radius: 10px;
background: rgba(255, 255, 255, 100);
color: black;
width: 100px;
height: 27px;
}
/* 样式用于错误信息标签 */
QLabel#errorLabel {
color: red;
font-size: 16pt;
}
""")
def onSubmit(self):
name = self.nameEdit.text()
pwd = self.pwdEdit.text()
url = self.urlEdit.text()
if name == '' or pwd == '' or url == '':
self.showError("非法输入!")
else:
with open('userinfo.json', 'w') as f:
json.dump({'name': name, 'pwd': pwd, 'url': url}, f)
self.close()
def showError(self, message):
self.errorLabel.setText(message)
self.errorLabel.show()
QTimer.singleShot(2000, self.hideError)
def hideError(self):
self.errorLabel.hide()
def main():
app = QApplication(sys.argv)
ex = MyApp()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

@ -10,6 +10,7 @@
'''
#导入所需模块
import platform
import os
import json
import time
@ -25,147 +26,167 @@ from cloud import is_exist,download
#配置参数
opt = Options()
opt.add_experimental_option('detach', True)
opt.add_argument('--headless')
#opt.add_argument('--headless')
chrome_driver = 'D:\ChromeDownload\chromedriver-win64\chromedriver-win64'
#以下部分在发行版本需要优化UI
# url = input('请输入作业中任意一关的网址:')
# user_name = input('请输入用户名:')
# password = input('请输入密码:')
# 发行版时改为调用userinfo.json文件中的用户名和密码
url = 'https://www.educoder.net/tasks/27V4D95N/1191515/vmxpzae734bj?coursesId=27V4D95N'
user_name = 'hnu202311020126'
password = 'hzy123456'
# 另外目前好像只有实训作业有这些参数其他的作业例如编程作业就没有所以先判断一下是否为实训作业可以通过用户输入的url判断
# 主要是看educoder.net/后面是否有tasks如果有则是实训作业否则不是实训作业
platf = platform.platform()
def is_practice(url:str) -> bool:
obj=re.compile(r'www.educoder.net/tasks')
if obj.search(url):
return True
else:
return False
if is_practice(url):
#构造selenium对象
safari = Chrome(options=opt)
safari.get(url)
#模拟登录
safari.implicitly_wait(10)
safari.find_element(By.ID, 'login').send_keys(user_name)
safari.find_element(By.ID, 'password').send_keys(password)
safari.find_element(By.ID, 'password').send_keys(Keys.ENTER)
time.sleep(2)
#获取cookieUser-Agent
Cookie = safari.get_cookies()
User_Agent = safari.execute_script('return navigator.userAgent')
cookie = f'autologin_trustie={Cookie[1]["value"]}; _educoder_session={Cookie[0]["value"]}'
#先获取到shixun_id便于先判断云端文件是否存在
cur_url = url
identity = cur_url.split('/')[-1].split('?')[0]
id_url = f'https://data.educoder.net/api/tasks/{identity}.json?'
headers = {
'Cookie':cookie,
'User-Agent':User_Agent,
'Referer':cur_url
}
response = requests.get(url=id_url, headers=headers)
shixun_id = dict(response.json())['challenge']['shixun_id']
#判断云端文件是否存在
try:
exist = is_exist(f'{shixun_id}.json')
if exist: #存在,则跳转到云端下载并终止本程序
print('云端文件已存在,正在下载')
download(f'{shixun_id}.json')
# 检测本地文件是否下载完成
while True:
try:
if os.path.exists(f'{shixun_id}.json'):
print('下载完成')
safari.quit()
exit()
break
except Exception as e:
print(e)
except Exception as e:
print(e)
finally: #不存在,则继续执行本程序
#获取关卡数
#点击展开关卡页面
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[1]/a[1]').click()
# 另外目前好像只有实训作业有这些参数其他的作业例如编程作业就没有所以先判断一下是否为实训作业可以通过用户输入的url判断
# 主要是看educoder.net/后面是否有tasks如果有则是实训作业否则不是实训作业
#为方便main.py调用将判断函数写入函数中以下部分封装为函数
def get_parameters(url:str,user_name:str,password:str):
url = url
user_name = user_name
password = password
if is_practice(url):
#构造selenium对象
safari = Chrome(options=opt)
safari.get(url)
#模拟登录
safari.implicitly_wait(10)
safari.find_element(By.ID, 'login').send_keys(user_name)
safari.find_element(By.ID, 'password').send_keys(password)
safari.find_element(By.ID, 'password').send_keys(Keys.ENTER)
time.sleep(2)
#关卡数量由 class = "flex-container challenge-title space-between" 的元素数量决定
htmltxt = safari.page_source
html = etree.HTML(htmltxt)
task_num = html.xpath('count(//*[@class="flex-container challenge-title space-between"])')
task_num = int(task_num)
#关闭关卡页面
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[3]/div[1]').click()
#对于每一关,获取参数
#每一关的参数由以下元素组成:
'''
/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[3]/div[1]/a
/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[4]/div[1]/a
'''
obj1 = re.compile(r'<h3 id="任务描述">任务描述</h3><p>(?P<describe>.*?)</p>',re.S)
obj2 = re.compile(r'<h3 id="编程要求">编程要求</h3><p>(?P<require>.*?)</p>',re.S)
#初始化一个字典,用于存放所有关卡的参数
total = {}
i=1
#判断是否登录成功
try:
while i <= task_num:
safari.implicitly_wait(10)
safari.find_element(By.XPATH, '//*[@id="task-left-panel"]/div[1]/a[1]').click()
safari.implicitly_wait(10)
safari.find_element(By.XPATH,f'/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[{i}]/div[1]/a').click()
time.sleep(3)
#获取课程id -> 根据url中?前面的,最后一个/后面的那部分参数构造请求同时似乎还需要用到cookieUser-Agent和Referer参数这些统一用selenium在登陆后获取并组装成headers
#获取cookieUser-Agent和Referer
cur_url=Referer = safari.current_url
identity = cur_url.split('/')[-1].split('?')[0]
id_url = f'https://data.educoder.net/api/tasks/{identity}.json?'
#获取课程id
headers = {
'Cookie':cookie,
'User-Agent':User_Agent,
'Referer':Referer
}
try:
response = requests.get(url=id_url,headers=headers)
challenge_id = dict(response.json())['challenge']['id']
shixun_id = dict(response.json())['challenge']['shixun_id']
except BaseException:
print('获取课程id失败')
#获取任务描述(如果存在的话)
page_source = safari.page_source
describe = obj1.findall(page_source)
#获取编程要求(如果存在的话)
require = obj2.findall(page_source)
#获取编辑器中的代码,由于代码都是class = "view-line"的div,先找到所有class = "view-line"的div获取其中的所有文本再把不同行的代码用\n连接起来
code = safari.find_elements(By.CLASS_NAME,'view-line')
code = '\n'.join([i.text for i in code]).lstrip('\n')
#把参数存入字典再转换为json格式
task = {
'describe':describe[0] if len(describe) != 0 else '',
'require':require[0] if len(require) != 0 else '',
'code':code,
'verified': False, #这个参数是用来标记答案是否被用户认证为正确答案的初始值为False
'last_modified': time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) #这个参数是用来标记答案最后一次被修改的时间,初始值为当前时间
}
#把每一关的参数存入总的字典中
total[challenge_id] = task
#去往下一关
i += 1
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[1]/a[1]')
except BaseException:
print(f'{challenge_id}参数获取参数失败')
#判断爬取到的代码是否存在空值,如果存在空值,则重新爬取
for value in total.values():
if value['code'] == '':
print('检测到代码参数为空值,重新爬取')
safari.close()
os.system('python get_params.py')
exit()
#把参数写入本地json文件中文件名字与shixun_name相同键为course_id值为一个列表列表中每个元素为一个字典字典中包含每一关的参数
with open(f'{shixun_id}.json','w',encoding='utf-8') as f:
json.dump(total,f,ensure_ascii=False,indent=4)
#关闭浏览器
safari.quit()
else:
print('这不是一个实训作业')
exit()
print('登录失败 请检查输入信息是否正确')
# 关闭浏览器
safari.quit()
#重新调用login_ui.py
if 'Windows' in platf:
os.system('python login_ui.py')
else:
os.system('python3 login_ui.py')
#获取cookieUser-Agent
Cookie = safari.get_cookies()
User_Agent = safari.execute_script('return navigator.userAgent')
cookie = f'autologin_trustie={Cookie[1]["value"]}; _educoder_session={Cookie[0]["value"]}'
#先获取到shixun_id便于先判断云端文件是否存在
cur_url = url
identity = cur_url.split('/')[-1].split('?')[0]
id_url = f'https://data.educoder.net/api/tasks/{identity}.json?'
headers = {
'Cookie':cookie,
'User-Agent':User_Agent,
'Referer':cur_url
}
response = requests.get(url=id_url, headers=headers)
shixun_id = dict(response.json())['challenge']['shixun_id']
#判断云端文件是否存在
try:
exist = is_exist(f'{shixun_id}.json')
if exist: #存在,则跳转到云端下载并终止本程序
print('云端文件已存在,正在下载')
download(f'{shixun_id}.json')
# 检测本地文件是否下载完成
while True:
try:
if os.path.exists(f'{shixun_id}.json'):
print('下载完成')
safari.quit()
exit()
break
except Exception as e:
print(e)
except Exception as e:
print(e)
finally: #不存在,则继续执行本程序
print('云端文件不存在,正在爬取')
#获取关卡数
#点击展开关卡页面
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[1]/a[1]').click()
time.sleep(2)
#关卡数量由 class = "flex-container challenge-title space-between" 的元素数量决定
htmltxt = safari.page_source
html = etree.HTML(htmltxt)
task_num = html.xpath('count(//*[@class="flex-container challenge-title space-between"])')
task_num = int(task_num)
#关闭关卡页面
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[3]/div[1]').click()
#对于每一关,获取参数
#每一关的参数由以下元素组成:
'''
/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[3]/div[1]/a
/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[4]/div[1]/a
'''
obj1 = re.compile(r'<h3 id="任务描述">任务描述</h3><p>(?P<describe>.*?)</p>',re.S)
obj2 = re.compile(r'<h3 id="编程要求">编程要求</h3><p>(?P<require>.*?)</p>',re.S)
#初始化一个字典,用于存放所有关卡的参数
total = {}
i=1
try:
while i <= task_num:
safari.implicitly_wait(10)
safari.find_element(By.XPATH, '//*[@id="task-left-panel"]/div[1]/a[1]').click()
safari.implicitly_wait(10)
safari.find_element(By.XPATH,f'/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[{i}]/div[1]/a').click()
time.sleep(3)
#获取课程id -> 根据url中?前面的,最后一个/后面的那部分参数构造请求同时似乎还需要用到cookieUser-Agent和Referer参数这些统一用selenium在登陆后获取并组装成headers
#获取cookieUser-Agent和Referer
cur_url=Referer = safari.current_url
identity = cur_url.split('/')[-1].split('?')[0]
id_url = f'https://data.educoder.net/api/tasks/{identity}.json?'
#获取课程id
headers = {
'Cookie':cookie,
'User-Agent':User_Agent,
'Referer':Referer
}
try:
response = requests.get(url=id_url,headers=headers)
challenge_id = dict(response.json())['challenge']['id']
shixun_id = dict(response.json())['challenge']['shixun_id']
except BaseException:
print('获取课程id失败')
#获取任务描述(如果存在的话)
page_source = safari.page_source
describe = obj1.findall(page_source)
#获取编程要求(如果存在的话)
require = obj2.findall(page_source)
#获取编辑器中的代码,由于代码都是class = "view-line"的div,先找到所有class = "view-line"的div获取其中的所有文本再把不同行的代码用\n连接起来
code = safari.find_elements(By.CLASS_NAME,'view-line')
code = '\n'.join([i.text for i in code]).lstrip('\n')
#把参数存入字典再转换为json格式
task = {
'describe':describe[0] if len(describe) != 0 else '',
'require':require[0] if len(require) != 0 else '',
'code':code,
'verified': False, #这个参数是用来标记答案是否被用户认证为正确答案的初始值为False
'last_modified': time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) #这个参数是用来标记答案最后一次被修改的时间,初始值为当前时间
}
#把每一关的参数存入总的字典中
total[challenge_id] = task
#去往下一关
i += 1
except BaseException:
print(f'{challenge_id}参数获取参数失败')
#判断爬取到的代码是否存在空值,如果存在空值,则重新爬取
for value in total.values():
if value['code'] == '':
print('检测到代码参数为空值,重新爬取')
safari.close()
# 再次执行本程序
if 'Windows' in platf:
os.system('python get_params.py')
else:
os.system('python3 get_params.py')
#把参数写入本地json文件中文件名字与shixun_name相同键为course_id值为一个列表列表中每个元素为一个字典字典中包含每一关的参数
with open(f'{shixun_id}.json','w',encoding='utf-8') as f:
json.dump(total,f,ensure_ascii=False,indent=4)
print('参数爬取完成')
#关闭浏览器
safari.quit()
else:
print('这不是一个实训作业')
exit()

@ -1,116 +1,143 @@
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter
import os
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 加载背景图片
self.background = QPixmap('b3o.png')
# 创建一个垂直布局
mainLayout = QVBoxLayout()
# 创建三个文本框并设置占位符
self.nameEdit = QLineEdit()
self.pwdEdit = QLineEdit()
self.urlEdit = QLineEdit()
# self.nameEdit.setPlaceholderText('Name')
# self.pwdEdit.setPlaceholderText('Password')
# self.urlEdit.setPlaceholderText('URL')
# 创建一个按钮并连接信号
btn = QPushButton('提交')
btn.clicked.connect(self.onSubmit)
self.setWindowTitle('头歌助手登录')
# 对于每个输入框,创建一个水平布局以保持居中
for label_text, edit_widget in [("用户名", self.nameEdit),
("密 码", self.pwdEdit),
("实训网址", self.urlEdit)]:
hbox = QHBoxLayout() #创建一个水平布局
hbox.addStretch() #添加一个伸缩因子,使得文本框和按钮位于窗口中心
vbox_inner = QVBoxLayout() #创建一个垂直布局
vbox_inner.addWidget(QLabel(label_text)) #添加一个标签
vbox_inner.addWidget(edit_widget) #添加一个文本框
hbox.addLayout(vbox_inner) #将垂直布局添加到水平布局中
hbox.addStretch() #添加一个伸缩因子,使得文本框和按钮位于窗口中心
mainLayout.addLayout(hbox) #将水平布局添加到垂直布局中
# 添加按钮到布局
mainLayout.addWidget(btn, 0, Qt.AlignCenter)
# 设置窗口的布局
self.setLayout(mainLayout)
self.setWindowTitle('')
self.setGeometry(300, 300, 650,550) # 设置窗口大小,其中300,300为窗口左上角坐标1000,600为窗口大小
self.centerWindow()
# 应用样式
self.applyStyles()
self.show()
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.background)
def centerWindow(self):
qr = self.frameGeometry()
cp = QApplication.desktop().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def applyStyles(self):
# css 用于设置窗口样式
self.setStyleSheet("""
QLineEdit {
border: 1px solid gray;
border-radius: 10px;
padding: 5px;
background: rgba(255, 255, 255, 100);
}
QLineEdit:focus {
border: 1px solid black;
}
QLabel {
color: black;
font-size: 23pt;
margin-top: 50px; /* 顶部外边距 */
margin-left: 20px; /* 左侧外边距 */
}
QLineEdit {
border: 1px solid gray;
border-radius: 10px;
padding: 5px;
background: rgba(255, 255, 255, 100);
color: black; /* 设置输入文本颜色为黑色 */
width: 300px; /* 设置输入框宽度 */
height: 30px; /* 设置输入框高度 */
}
QPushButton {
border: 1px solid gray;
border-radius: 10px;
padding: 5px;
background: rgba(255, 255, 255, 100);
color: black; /* 设置按钮文本颜色为黑色 */
width: 100px; /* 设置按钮宽度 */
height: 27px; /* 设置按钮高度 */
}
""")
def onSubmit(self):
name = self.nameEdit.text()
pwd = self.pwdEdit.text()
url = self.urlEdit.text()
print(f"Name: {name}, Password: {pwd}, URL: {url}")
# 关闭窗口
self.close()
os.system('python3 show_welcome.py')
app = QApplication(sys.argv)
ex = MyApp()
ex.show()
sys.exit(app.exec_())
'''
本模块用于创建登录界面并保存用户信息
'''
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt,QTimer
from PyQt5.QtGui import QPixmap, QPainter
import os
import platform
import json
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 加载背景图片
self.background = QPixmap('picture\\b2.png')
# 创建一个垂直布局
mainLayout = QVBoxLayout()
# 创建三个文本框并设置占位符
self.nameEdit = QLineEdit()
self.pwdEdit = QLineEdit()
self.urlEdit = QLineEdit()
# 创建一个按钮并连接信号
btn = QPushButton('提交')
btn.clicked.connect(self.onSubmit)
# 创建一个用于显示错误信息的标签
self.errorLabel = QLabel('', self)
self.errorLabel.hide() # 初始时隐藏该标签
self.setWindowTitle('头歌助手登录')
# 对于每个输入框,创建一个水平布局以保持居中
for label_text, edit_widget in [("用户名", self.nameEdit),
("密 码", self.pwdEdit),
("实训网址", self.urlEdit)]:
hbox = QHBoxLayout()
hbox.addStretch()
vbox_inner = QVBoxLayout()
vbox_inner.addWidget(QLabel(label_text))
vbox_inner.addWidget(edit_widget)
hbox.addLayout(vbox_inner)
hbox.addStretch()
mainLayout.addLayout(hbox)
# 添加按钮和错误信息标签到布局
mainLayout.addWidget(btn, 0, Qt.AlignCenter)
mainLayout.addWidget(self.errorLabel, 0, Qt.AlignCenter)
# 设置窗口的布局
self.setLayout(mainLayout)
self.setGeometry(350, 350, 1200, 700)
self.centerWindow()
# 应用样式
self.applyStyles()
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.background)
def centerWindow(self):
qr = self.frameGeometry()
cp = QApplication.desktop().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def applyStyles(self):
self.setStyleSheet("""
QLineEdit {
border: 1px solid gray;
border-radius: 10px;
padding: 5px;
background: rgba(255, 255, 255, 100);
color: black;
width: 300px;
height: 50px;
font-size: 14pt; /* 设置字号为14磅 */
font-family: 'Microsoft YaHei'; /* 设置字体为微软雅黑 */
}
QLineEdit:focus {
border: 3px solid black;
}
QLabel {
color: black;
font-size: 20pt;
font-family: "Microsoft YaHei";
margin-top: 50px; /* 顶部外边距 */
margin-left: 200px; /* 左侧外边距 */
}
QPushButton {
border: 1px solid gray;
border-radius: 10px;
background: rgba(255, 255, 255, 100);
color: black;
width: 100px;
height: 27px;
}
/* 样式用于错误信息标签 */
QLabel#errorLabel {
color: red;
font-size: 16pt;
}
""")
def onSubmit(self):
name = self.nameEdit.text()
pwd = self.pwdEdit.text()
url = self.urlEdit.text()
if name == '' or pwd == '' or url == '' or ~url.startswith('https') or ~url.startswith('www'):
self.showError("非法输入!")
else:
with open('userinfo.json', 'w') as f:
json.dump({'name': name, 'pwd': pwd, 'url': url}, f)
self.close()
def showError(self, message):
self.errorLabel.setText(message)
self.errorLabel.show()
QTimer.singleShot(1200, self.hideError)
def hideError(self):
self.errorLabel.hide()
# 关闭窗口
# 判断当前操作系统(基础太渣,只能这样判断了,哈哈)
platf = platform.platform()
if platf.startswith('Windows'):
os.system('python show_welcome.py')
else:
os.system('python3 show_welcome.py')
app = QApplication(sys.argv) # 创建应用程序对象
ex = MyApp() # 创建窗口对象
ex.show() # 显示窗口
sys.exit(app.exec_()) # 保证程序完整退出

@ -1,15 +1,84 @@
'''
主程序整合各个模块
1ui文件调用相应ui模块
2get_params.py获取参数
3get_answer.py获取答案
4cloud.py将json文件存入云端
'''
# 生成图形化界面,引导用户登陆并输入实训网址
# 调用get_params.py获取参数这一步同时隐含了云端获取答案的过程
# 如果云端答案不存在则调用get_answer.py获取答案并展示给用户
# 用户verif选项确认后调用cloud.py将json文件存入云端
import login_ui
'''
主程序整合各个模块
1ui文件调用相应ui模块
2get_params.py获取参数
3get_answer.py获取答案
4cloud.py将json文件存入云端
'''
# 生成图形化界面,引导用户登陆并输入实训网址
# 调用get_params.py获取参数这一步同时隐含了云端获取答案的过程
# 如果云端答案不存在则调用get_answer.py获取答案并展示给用户
# 用户verif选项确认后调用cloud.py将json文件存入云端
# 导入所需模块
import platform
from get_params import get_parameters
from get_answer import get_answer_from_api,promot,client
import json
import os
# 判断当前操作系统
platf = platform.platform()
# 调用login_ui获得用户输入的用户名、密码和实训网址
if platf.startswith('Windows'):
os.system('python login_ui.py')
else:
os.system('python3 login_ui.py')
# 检查userinfo.json文件是否存在存在则程序继续
assert os.path.exists('userinfo.json'), 'userinfo.json文件不存在,请检查'
# 先读取userinfo.json文件获得用户名、密码和实训网址
with open('userinfo.json', 'r') as f:
userinfo = json.load(f)
user_name = userinfo['name']
password = userinfo['pwd']
url = userinfo['url']
# 调用get_params.py获得参数完成后本地应该有一个json文件里面有参数
get_parameters(url,user_name,password)
def get_json(file):
return [i for i in os.listdir(file) if i.endswith('.json')]
#将file指定为当前目录
file = os.getcwd()
json_names = get_json(file)
# 遍历查找以数字开头的json文件即为获得到的json文件可能是云端下载的也可能是爬取的
global j_name
for j in json_names:
if j[0].isdigit():
# 将该文件名赋值给json_name
j_name = j
break
# 判断json_name文件中是否有answer若有提取answer并格式化或展现
with open(j_name,'r',encoding='utf-8') as f:
json_data = json.load(f)
def is_exist_answer(data:dict) -> bool:
for i,j in data.items():
if 'answer' in j.keys():
return True
return False
if is_exist_answer(json_data):
pass
else:
# 调用API获取答案
new_data = get_answer_from_api(jsonfile=json_data,client=client,promot=promot)
# 重写本地json文件
with open(j_name,'w',encoding='utf-8') as f:
json.dump(new_data,f,ensure_ascii=False,indent=4)
# 上面的判断执行完后本地的json文件中已经有answer了下面实现信息展示
# release版本要优化UIbeta版本先用print代替
# 读取json文件获得answer
with open(j_name,'r',encoding='utf-8') as f:
data = json.load(f)
# 由于python3.6之后字典是有序的,所以可以直接遍历字典,显示关卡序号和答案
# 要将key在data中对应的索引值+1因为索引值是从0开始的
for i,j in enumerate(data.items()):
print(f'{i+1}关的答案是:{j[-1]["answer"]}')
# 询问用户是否认证答案正确(下午新开一个模块实现)

@ -1,39 +1,46 @@
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QTimer, Qt
class ImageWindow(QWidget):
def __init__(self, image_path):
super().__init__()
self.initUI(image_path)
def initUI(self, image_path):
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
label = QLabel(self)
pixmap = QPixmap(image_path)
# 缩放图片到期望的大小
scaled_pixmap = pixmap.scaled(700, 400, Qt.KeepAspectRatio) # 设置图片大小为400x300并保持纵横比
label.setPixmap(scaled_pixmap)
self.resize(scaled_pixmap.width(), scaled_pixmap.height())
# 居中显示窗口
qr = self.frameGeometry()
cp = QApplication.desktop().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
QTimer.singleShot(3000, self.close)
def show():
app = QApplication(sys.argv)
ex = ImageWindow('b2.png')
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
show()
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QDesktopWidget
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QTimer, Qt
class ImageWindow(QWidget):
def __init__(self, image_path):
super().__init__()
self.initUI(image_path)
def initUI(self, image_path):
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
label = QLabel(self)
pixmap = QPixmap(image_path)
# 获取屏幕尺寸
screen = QDesktopWidget().screenGeometry()
# 缩放图片大小
# 过时警告 scaled_pixmap = pixmap.scaledint(screen.width() * 0.5, screen.height() * 0.5, Qt.KeepAspectRatio)
scaled_pixmap = pixmap.scaled(int(screen.width() * 0.5), int(screen.height() * 0.5), Qt.KeepAspectRatio)
label.setPixmap(scaled_pixmap)
self.resize(scaled_pixmap.width(), scaled_pixmap.height())
# 居中显示窗口
self.centerWindow()
QTimer.singleShot(4500, self.close)
def centerWindow(self):
# 居中窗口
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center() # 获取屏幕中心点
qr.moveCenter(cp)
self.move(qr.topLeft())
def show_image():
app = QApplication(sys.argv)
ex = ImageWindow('picture\\b2txt.png') # 图片路径
ex.show()
sys.exit(app.exec_())
show_image()

@ -1 +1 @@
# 我真甜蜜地服了互联网上一群傻逼到处TMD跟喷史一样到处拉史一样的垃圾信息就TM配置个代理一帮牛马讲得TMD的天花乱坠什么TM云函数Cloudfare代理Njanx反向代理真NMSL的一群人。好不容易TND有几个人直接给TM代理地址又不说明要加/v1官方文档也TM是一堆若至写的吗API用法更新了就TM给几个示例代码是怕GitHub存储费用太高吗社区和和论坛也是一帮彼阳的晚意TM跟东晋士大夫一样搁哪清谈半天NM一个给代码示例的人都没有屈指可数的几个代码又是API1.2版本之前的用不了一点捏。我TM找整整2天就差冲OpenAI官网的时候无意间看到CSDN上的[这篇帖子](https://blog.csdn.net/qq_36265860/article/details/130111351)。WC什么叫清晰什么叫对比什么叫做程序员的自我修养TM我那么简单的一个问题就只有这个老哥给出解答。我NM真的当时真的想嫁给这个哥了。我宣布CSDN就是世界第一技术论坛那些说看CSDN是屎里淘食的人下赛季池史。以后多看书再上网查这种技术问题我也是SB。暂时就想到那么多哈哈。
# 我真甜蜜地服了互联网上一群傻逼到处TMD跟喷史一样到处拉史一样的垃圾信息就TM配置个代理一帮牛马讲得TMD的天花乱坠什么TM云函数Cloudfare代理Njanx反向代理真NMSL的一群人。好不容易TND有几个人直接给TM代理地址又不说明要加/v1官方文档也TM是一堆SB写的吗API用法更新了就TM给几个示例代码是怕GitHub存储费用太高吗社区和和论坛也是一帮勾石东西TM跟东晋士大夫一样搁哪清谈半天NM一个给代码示例的人都没有屈指可数的几个代码又是API1.2版本之前的用不了一点捏。我TM找整整2天就差冲OpenAI官网的时候无意间看到CSDN上的[这篇帖子](https://blog.csdn.net/qq_36265860/article/details/130111351)。WC什么叫清晰什么叫对比什么叫做程序员的自我修养TM我那么简单的一个问题就只有这个老哥给出解答。我NM真的当时真的想嫁给这个哥了。我宣布CSDN就是世界第一技术论坛那些说看CSDN是屎里淘食的人下赛季池史。以后多看书再上网查这种技术问题我也是SB。暂时就想到那么多哈哈。

Loading…
Cancel
Save