Merge branch 'tkinter' into courseTable

This commit is contained in:
Ting-Jun Wang 2021-07-03 02:00:10 +08:00
commit 987081e6d3
Signed by: snsd0805
GPG Key ID: 8DB0D22BC1217D33
8 changed files with 245 additions and 14 deletions

View File

@ -1,7 +1,8 @@
from config import CONFIG
from api.moodle import Moodle
from api.ncnuMain import NcnuMain
from api.ncnu import NCNU
from api.moodle import MoodleAPI
from api.ncnuMain import NcnuMainAPI
from api.ncnu import NcnuAPI
from api.eventRigestry import EventRegistry
def space():
print("\n" + "="*20 + "\n")
@ -9,7 +10,7 @@ def space():
# =================== TEST Moodle API ==========================
# ===== Test 登入 =====
moodle = Moodle(CONFIG['moodle']['username'], CONFIG['moodle']['password'])
moodle = MoodleAPI(CONFIG['moodle']['username'], CONFIG['moodle']['password'])
if moodle.status:
# ===== Test 取得該學期課程資料 =====
@ -40,7 +41,7 @@ else:
# =================== Test 暨大官網 API ==========================
# ===== Test 取得暨大官網最新消息 =====
main = NcnuMain()
main = NcnuMainAPI()
for anno in main.getAnno():
print(anno)
space()
@ -50,7 +51,7 @@ space()
# =================== Test 暨大教務系統 API ==========================
# ===== Test 登入 =====
ncnu = NCNU(CONFIG['NCNU']['username'], CONFIG['NCNU']['password'])
ncnu = NcnuAPI(CONFIG['NCNU']['username'], CONFIG['NCNU']['password'])
if ncnu.status:
# ===== Test 下載課表 =====
@ -99,3 +100,27 @@ if ncnu.status:
space()
else:
print("NCNU 教務系統登入失敗")
# =================== Test 暨大活動報名系統 API ==========================
# ===== Test 登入 =====
eventReg = EventRegistry(CONFIG['NCNU']['username'], CONFIG['NCNU']['password'])
if eventReg.status:
print("登入成功")
space()
# ===== Test 取得所有活動第一頁的列表 =====
for event in eventReg.getEventsList():
print(event)
space()
# ===== Test 報名前準備 request body =====
requestBody = eventReg.signUpPrepare('3010')
for key, value in requestBody.items():
print("{}: {}".format(key, value))
space()
else:
print("登入失敗")

View File

@ -1,5 +1,5 @@
from tkinter import *
from api.moodle import Moodle
from api.moodle import MoodleAPI
from config import CONFIG
from tkhtmlview import HTMLLabel
@ -14,7 +14,7 @@ def getIdAndName(course):
def createMoodleWin():
moodle = Moodle(CONFIG['moodle']['username'], CONFIG['moodle']['password'])
moodle = MoodleAPI(CONFIG['moodle']['username'], CONFIG['moodle']['password'])
if moodle.status:
# ===== 取得課程ID與名稱 =====

100
Ncnu.py Normal file
View File

@ -0,0 +1,100 @@
from tkinter import *
from api.ncnu import NcnuAPI
from config import CONFIG
from tkinter import messagebox
from tkhtmlview import HTMLLabel
def createNcnuWin():
ncnu = NcnuAPI(CONFIG['NCNU']['username'], CONFIG['NCNU']['password'])
if ncnu.status:
def dlCurriculum(sem):
if ncnu.getCourseTable(sem):
messagebox.showinfo(message="{} 課表已經儲存到 ./{}課表.pdf".format(sem,sem))
else:
messagebox.showwarning(message="無法存取 {} 課表".format(sem))
win=Tk()
leftframe=Frame(win)
leftframe.pack(fill=BOTH,side=LEFT)
rightframe=Frame(win)
rightframe.pack(side=RIGHT)
textlb=Label(leftframe,text="我的學習紀錄",font="Helvetica 20")
options=["各學期成績總覽","指定學期的成績列表","缺曠課記錄","獎懲紀錄","加選課程狀態"]
optionsListbox=Listbox(leftframe)
optionsListbox.insert(END,*options)
chooseSemesterLb=Label(leftframe,text="指定學期",font="Helvetica 10")
chooseSemesterEntry=Entry(leftframe)
chooseSemesterEntry.insert(0,"1092")
downloadBtn=Button(leftframe,text="下載課表",command=lambda:dlCurriculum(chooseSemesterEntry.get()))
textlb.pack(fill=BOTH,expand=True)
optionsListbox.pack(fill=BOTH)
chooseSemesterLb.pack(fill=BOTH)
chooseSemesterEntry.pack(fill=BOTH)
downloadBtn.pack()
htmlLb=HTMLLabel(rightframe,html="")
htmlScrollbar=Scrollbar(rightframe)
htmlLb.configure(yscrollcommand=htmlScrollbar.set)
htmlScrollbar.pack(fill=Y,side=RIGHT)
htmlLb.pack()
def itemSelected(event):
obj = event.widget
Index = obj.curselection()
Html=''''''
if str( obj.get(Index) ) == options[0]:
scores = ncnu.getScoreSummary()
for c in scores['semesters']:
Html+='''<tr> <td>學期:{}</td> <td>修課數:{}</td> <td>通過數:{}</td> <td>學分數:{}</td> <td>平均分數:{}</td> <td>排名:{}</td></tr><p>'''.format(c.get("semester"),
c.get("select_num"),c.get("pass_Num"),c.get("pass_credit"),c.get("average"),c.get("rank") )
c=scores['sum']
Html+='''<tr> <td>學期{}</td> <td>修課數:{}</td> <td>通過數:{}</td> <td>學分數:{}</td> <td>{}</td> <td>{}</td></tr>'''.format(c.get("semester"),
c.get("select_num"),c.get("pass_Num"),c.get("pass_credit"),c.get("average"),c.get("rank") )
htmlLb.set_html(Html)
elif str( obj.get(Index) ) == options[1]:
scores = ncnu.getScore(chooseSemesterEntry.get())
for i in scores:
Html+="<tr><td>代號: {}</td> <td>班號: {}</td> <td>課程名稱: {}</td> <td>學分數: {}</td><td>老師: {}</td> <td>時間: {}</td> <td>地點: {}</td> <td>學分: {}</td> <td>分數: {}</td> <td>是否為必修?: {}</td></tr><p>".format(i.get("number"),
i.get("class"),i.get("name"),i.get("credit"),i.get("teacher"),i.get("time"),i.get("place"),i.get("credit"),i.get("score"),i.get("mandatary") )
htmlLb.set_html(Html)
elif str( obj.get(Index) ) == options[2]:
absenceLogs = ncnu.getAbsenceLogs()
if absenceLogs:
for log in absenceLogs:
Html+='''<tr> <td>{}</td> <td>{}</td> <td>{}</td> <td>{}</td> <td>{}</td></tr>'''.format(log.get('id'),
log.get('semester'),log.get('classname'),log.get('date'),log.get('time'))
htmlLb.set_html(Html)
else:
Html+='''<h3>沒有任何缺曠課記錄</h3>'''
htmlLb.set_html(Html)
elif str( obj.get(Index) ) == options[3]:
awardLogs = ncnu.getAwardLogs()
if awardLogs:
for log in awardLogs:
Html+='''<tr> <td>{}</td> <td>{}</td> <td>{}</td> <td>{}</td> <td>{}</td></tr>'''.format(log.get('id'),
log.get('semester'),log.get('award'),log.get('count'),log.get('content'))
htmlLb.set_html(Html)
else:
Html+='''<h3>沒有任何缺曠課記錄</h3>'''
htmlLb.set_html(Html)
elif str( obj.get(Index) ) == options[4]:
logs = ncnu.getAddCourseLogs()
if logs:
for log in logs:
Html+='''<tr> <td> {} </td> <td>學期: {} </td> <br> <td>課名: {} </td> <td>班別: {} </td> <td>加選狀態:{}</td></tr><p>'''.format(log.get('id'),
log.get('semester'),log.get('classname'),log.get('class'),log.get('check'))
htmlLb.set_html(Html)
optionsListbox.bind("<<ListboxSelect>>", itemSelected)
win.mainloop()
else:
print("NCNU 教務系統登入失敗")
createNcnuWin()

View File

@ -1,12 +1,12 @@
from tkinter import *
from tkhtmlview import HTMLLabel
from api.ncnuMain import NcnuMain
from api.ncnuMain import NcnuMainAPI
def createNcnuMainWin():
win=Tk()
win.title("暨大官網最新資訊!")
win.geometry("600x600")
main = NcnuMain()
main = NcnuMainAPI()
Link='''<span style="background-color:#ffcccc"><ul>'''
textLb=Label(win,text="暨大校園最新資訊",font="Helvetica 20",bg="#ffcccc")

106
api/eventRigestry.py Normal file
View File

@ -0,0 +1,106 @@
import requests
from api.tools import *
class EventRegistry():
def __init__(self, username, password):
'''
initial 就登入
根據 self.status 判斷成功與否
'''
self.username = username # 學號
self.session = requests.Session()
self.status = self.login(username, password)
def login(self, username, password):
'''
登入活動報名系統
return bool
'''
# get login token
response = self.session.get('https://ccweb.ncnu.edu.tw/SLLL/login.asp')
loginToken = find(response, 'input', param={'name': 'token'}).get('value')
# request login page
response = self.session.post(
"https://ccweb.ncnu.edu.tw/SLLL/login.asp",
data={
'token': loginToken,
'username': username,
'password': password,
'type': ''
}
)
# 成功的話 return http 302, redirect
if len(response.history)!=0:
return True
else:
return False
def getEventsList(self):
'''
取得活動列表中的第一頁
包含所有狀態的活動
'''
url = "https://ccweb.ncnu.edu.tw/SLLL/z6D3B52D553CA5831540D8CC7659967E58A62list.asp"
response = self.session.get(url)
with open('test.html') as fp:
response = fp.read()
root = BeautifulSoup(response, 'html.parser')
events = root.find('table').findAll('tr')
return [{
'id': getUrlParam(data[0].find('a').get('href').replace('&amp;', '&'), 'RowID'),
# 活動詳細:
# https://ccweb.ncnu.edu.tw/SLLL/z6D3B52D553CA5831540D8CC7659967E58A62view.asp?showdetail=&RowID={}
'semester': data[1].text.replace('\n', ''),
'status': data[2].text.replace('\n', ''), # 活動報名狀態
'name': data[3].text.replace('\n', ''),
'time': data[4].text.replace('\n', ''), # 活動開始時間
'method': data[5].text.replace('\n', ''), # 報名方式
'hour': data[6].text.replace('\n', ''), # 時數
'speaker': data[7].text.replace('\n', ''), # 講師
'teacherEvent': data[8].text.replace('\n', ''), # 申請為教師知能活動
} for data in (event.findAll('td') for event in events[1:])]
def signUpPrepare(self, eventID):
'''
報名活動前的資料確認
return 報名系統預設給的資料供使用者確認
'''
url = "https://ccweb.ncnu.edu.tw/SLLL/z7DDA4E0A5831540Dadd.asp?showmaster=z958B653E5831540D4E4B6D3B52D5660E7D30&fk_RowID={}"
response = self.session.get(url.format(eventID))
inputs = find(response, 'form').findAll('input')
values = [inputData.get('value') for inputData in inputs]
names = [inputData.get('name') for inputData in inputs]
# 僅下列資料可更改
# - x_iphone 校內分機
# - x_phone 聯絡電話
# - x_zemail EMAIL
# - x_remark 備註
ans = {}
for index in range(len(values)):
ans[names[index]] = values[index]
return ans
# 前端接收後,僅可更改上述四項 value
# 更改後送到 signUp(requestBody) function 中送出請求
def signUp(self, requestBody):
'''
目前禁止使用
'''
url = "https://ccweb.ncnu.edu.tw/SLLL/z7DDA4E0A5831540Dadd.asp"
response = self.session.post(url, data=requestBody)
if response.status_code == 200:
return True
else:
return False

View File

@ -4,7 +4,7 @@ from bs4 import BeautifulSoup
from api.tools import *
import json
class Moodle():
class MoodleAPI():
def __init__(self, username, password):
'''
Create a Moodle object to handle Session
@ -122,7 +122,7 @@ class Moodle():
return [{
'name': " ".join( link.text.split(' ')[:-1] ),
'type': link.text.split(' ')[-1],
'link': link.find('a').get('href')
'link': link.find('a').get('href') if link.find('a') != None else ""
} for link in links]
else:
return None

View File

@ -1,7 +1,7 @@
import requests
from api.tools import *
class NCNU():
class NcnuAPI():
def __init__(self, username, password):
'''
initial 就登入

View File

@ -2,7 +2,7 @@ from api.tools import *
import requests
from bs4 import BeautifulSoup
class NcnuMain():
class NcnuMainAPI():
def getAnno(self):
response = requests.get('https://www.ncnu.edu.tw/ncnuweb/ann/tabs.aspx?homeType=ncnu&unit=ncnu')
block = find(response, 'div', param={'id': 'annNews'})