diff options
author | 藍挺瑋 <lantw44@gmail.com> | 2012-12-21 09:52:09 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2012-12-21 09:52:09 +0800 |
commit | 024f6e82e68b9e862387ec541dd4ab4328d9df9c (patch) | |
tree | fa4475e16eae807d7340d77d0cb483b6d8baaf5e | |
parent | 65b3e824ddc24ec7dc7bad883426ec88b1bcf39d (diff) | |
download | inccalendar-024f6e82e68b9e862387ec541dd4ab4328d9df9c.tar.gz inccalendar-024f6e82e68b9e862387ec541dd4ab4328d9df9c.tar.zst inccalendar-024f6e82e68b9e862387ec541dd4ab4328d9df9c.zip |
NTU CEIBA 解析支援,但網頁部份尚未實作(仍在測試中,可能修改 API)
繳交日期之後會改成字串,因為其實只有期限比較重要而已......
-rw-r--r-- | access/imnc.py | 28 | ||||
-rw-r--r-- | jinhtml/import.html | 46 | ||||
-rw-r--r-- | js/imnc.js | 40 | ||||
-rw-r--r-- | ntuceiba/__init__.py | 17 | ||||
-rw-r--r-- | ntuceiba/parse.py | 119 | ||||
-rw-r--r-- | ntuceiba/toxml.py | 70 |
6 files changed, 317 insertions, 3 deletions
diff --git a/access/imnc.py b/access/imnc.py new file mode 100644 index 0000000..2451bd7 --- /dev/null +++ b/access/imnc.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +import webapp2 +from StringIO import StringIO + +from ntuceiba import NtuCeibaEvent +from ntuceiba.parse import ntuceiba_parser +from ntuceiba.toxml import ntuceiba_toxml + +from google.appengine.api import users +from google.appengine.ext import db + +class NtuCeibaImport(webapp2.RedirectHandler): + def get(self): + return + def post(self): + viewonly = self.request.get('viewonly') + htmlfile = self.request.get('file') + if viewonly != "": + htmlfile = StringIO(htmlfile) + htmlfile.readline() + cblist = ntuceiba_parser(htmlfile) + self.response.headers['Content-Type'] = 'text/xml; charset=UTF-8' + self.response.out.write(ntuceiba_toxml(cblist)) + + +app = webapp2.WSGIApplication([('/access/imnc', NtuCeibaImport)]) diff --git a/jinhtml/import.html b/jinhtml/import.html index 7af9a77..25e928b 100644 --- a/jinhtml/import.html +++ b/jinhtml/import.html @@ -5,9 +5,23 @@ margin-top: 20px; margin-left: 20px; } + div.indented{ + padding-left: 35px; + } p.question{ font-size: xx-large; } + input.loginfield{ + width: 300px; + } + ul.nolistsymbol{ + list-style-type: none; + margin-left: 20px; + margin-right: 0px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + } </style> {% endblock %} @@ -18,6 +32,7 @@ {% endblock %} {% block headjs %} + <script type="text/javascript" src="js/data.js"></script> <script type="text/javascript" src="js/imnc.js"></script> <script type="text/javascript"> function selsrc_initbut(){ @@ -42,11 +57,36 @@ <div id="imntuceibainfo" class="wholeform" style="display: none;"> <p class="question">請問您想透過哪一種方式取得 CEIBA 網站上的資料?</p> <input type="radio" id="nclogin" name="ncinfo" value="directlogin">透過帳號密碼直接登入 CEIBA 網站<br> - <input type="radio" id="ncupload" name="ncinfo" value="uploadpage">上傳 CEIBA 作業區的網頁檔案<br><br> - <input type="checkbox" id="ncviewagain" checked>匯入前檢視並修改內容(會導致較大的網路流量)<br> + <div class="indented"> + 網址:<input type="text" class="loginfield" id="ncloginurl" value="https://ceiba.ntu.edu.tw"><br> + 認證:<input type="text" class="loginfield" id="ncloginauth" value="https://web2.cc.ntu.edu.tw/p/s/login2/p1.php"><br> + 帳號:<input type="text" class="loginfield" id="ncloginacct"><br> + 密碼:<input type="password" class="loginfield" id="ncloginpass"><br> + </div> + <br> + <input type="radio" id="ncupload" name="ncinfo" value="uploadpage">上傳 CEIBA 作業區的網頁檔案<br> + <div class="indented"> + <form name="fileuploadform" action="access/echo" method="post" enctype="multipart/form-data"> + 檔案:<input name="echo" type="file" id="ncfile"> + </form> + </div> + <br> + 在「內容」欄位加入以下資訊: + <ul class="nolistsymbol"> + <li><input type="checkbox" id="ncaddtitle">名稱</li> + <li><input type="checkbox" id="ncaddmember">成員</li> + <li><input type="checkbox" id="ncaddmethod">繳交方法</li> + <li><input type="checkbox" id="ncaddpercent">成績比重</li> + <li><input type="checkbox" id="ncadddue">繳交期限</li> + <li><input type="checkbox" id="ncaddlate">逾期繳交</li> + <li><input type="checkbox" id="ncaddsub">繳交日期</li> + <li><input type="checkbox" id="ncaddlate">作業評語</li> + </ul> + <br> + <input type="checkbox" id="ncviewagain" checked>匯入前檢視並修改內容(可能導致較大的網路流量)<br> <input type="checkbox" id="ncmerge" checked>與先前匯入的資料合併以避免重複匯入<br><br> <input type="button" value="重新選擇來源" onclick="imnc_deinit()"> - <input type="button" value="開始匯入"> + <input type="button" value="開始匯入" onclick="imnc_argok()"> </div> <div id="imntuceibacheck" class="wholeform" style="display: none;"> </div> @@ -1,3 +1,5 @@ +var imnc_filecontent; + function imnc_init(){ status_bar_clear(); document.getElementById("imstepforminit").style.display = "none"; @@ -8,3 +10,41 @@ function imnc_deinit(){ document.getElementById("imstepforminit").style.display = "block"; document.getElementById("imntuceibainfo").style.display = "none"; } + +function imnc_argok(){ + status_bar_clear(); + if(document.getElementById("nclogin").checked){ + imnc_login(); + }else if(document.getElementById("ncupload").checked){ + imnc_upload(); + }else{ + status_bar_warning("請至少選取一種資料取得方式!"); + } +} + +function imnc_upload(){ + var fileldobj; + var filereader; + fileldobj = document.getElementById("ncfile"); + if(window.FileReader){ /* 支援 HTML5 File API 的話 */ + if(fileldobj.files.length <= 0){ + status_bar_warning("請選擇檔案!"); + return; + } + filereader = new FileReader(); + filereader.onloadend = function(evt){ + imnc_filecontent = evt.target.result; + imnc_upload_send(); + } + filereader.readAsText(fileldobj.files[0], 'Big5'); + }else{ + status_bar_warning("抱歉,尚未支援您的瀏覽器"); + return; + } +} + +function imnc_upload_send(){ + var rq; + rq = create_xmlhttp_object(); + +} diff --git a/ntuceiba/__init__.py b/ntuceiba/__init__.py new file mode 100644 index 0000000..d7b9925 --- /dev/null +++ b/ntuceiba/__init__.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +class NtuCeibaEvent: + def __init__(self): + self.title = "" + self.member = "" + self.method = "" + self.percent = "" + self.duedate = None + self.late = False + self.subdate = None + self.comment = "" + self.red = False + def setred(self, boolval): + if boolval == True: + self.red = True diff --git a/ntuceiba/parse.py b/ntuceiba/parse.py new file mode 100644 index 0000000..2686ea9 --- /dev/null +++ b/ntuceiba/parse.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +from datetime import datetime, timedelta +from lxml import etree +from ntuceiba import NtuCeibaEvent + +class nccolinfo: + def __init__(self): + self.red = False + self.url = None + self.data = "" + +def ntuceiba_readcol(etrele): + rval = nccolinfo() + if etrele.text: + rval.data = etrele.text + elif etrele[0].tag == 'a': + subele = etrele[0] + rval.url = subele.get('href') + if subele.text: + rval.data = subele.text + else: + rval.data = subele[0].text + rval.red = True + elif etrele[0].tag == 'font': + subele = etrele[0] + if subele.text: + rval.data = subele.text + rval.red = True + elif subele[0].tag == 'a': + rval.url = subele[0].get('href') + rval.data = subele[0].text + rval.red = True + return rval + +def ntuceiba_parsedate(instr): + if instr == '--': + return None + + try: + dyear = int(instr[0:4]) + dmonth = int(instr[5:7]) + ddate = int(instr[8:10]) + dhour = int(instr[11:13]) + except ValueError: + return None + + if dhour == 24: + rval = datetime(dyear, dmonth, ddate, 0) + rval = rval + timedelta(1, 0, 0) + else: + rval = datetime(dyear, dmonth, ddate, dhour) + + return rval + + +def ntuceiba_parser(fileobj): # 如果第一行是亂七八糟的東西,請先自行讀掉 + rval = [] + htmlparser = etree.HTMLParser(encoding='UTF-8') + htmltree = etree.parse(fileobj, htmlparser) + htmlroot = htmltree.getroot() + for hwarea in htmlroot.iter(): # 找出作業的位置 + if hwarea.tag == 'div' and hwarea.get('id') == 'sect_cont': + break + else: + return None + + allrow = [] + for item in hwarea.iter(): + if item.tag == 'tr': + allrow.append(item) + + if len(allrow) > 0: + allrow.pop(0) # 要去除第一列,因為那是表格標題列 + else: + return rval # 沒有資料就可以直接回傳了 + + for row in allrow: + ncdata = NtuCeibaEvent() + + sinfo = ntuceiba_readcol(row[0]) + ncdata.title = sinfo.data + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[1]) + ncdata.member = sinfo.data + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[2]) + ncdata.method = sinfo.data + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[3]) + ncdata.percent = sinfo.data + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[4]) + ncdata.duedate = ntuceiba_parsedate(sinfo.data) + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[5]) + if sinfo.data == 'Yes' or sinfo.data == u'可以': + ncdata.late = True + else: + ncdata.late = False + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[6]) + ncdata.subdate = ntuceiba_parsedate(sinfo.data) + ncdata.setred(sinfo.red) + + sinfo = ntuceiba_readcol(row[7]) + ncdata.comment = sinfo.data + ncdata.setred(sinfo.red) + + rval.append(ncdata) + + return rval diff --git a/ntuceiba/toxml.py b/ntuceiba/toxml.py new file mode 100644 index 0000000..4417f15 --- /dev/null +++ b/ntuceiba/toxml.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +from ntuceiba import NtuCeibaEvent +from datetime import datetime +from lxml import etree + +def XMLBuildNtuCaibaEvent(eleobj, cbobj): + newdata = etree.SubElement(eleobj, 'title') + newdata.text = cbobj.title + newdata = etree.SubElement(eleobj, 'member') + newdata.text = cbobj.member + newdata = etree.SubElement(eleobj, 'method') + newdata.text = cbobj.method + newdata = etree.SubElement(eleobj, 'percent') + newdata.text = cbobj.percent + newdata = etree.SubElement(eleobj, 'late') + newdata.text = str(cbobj.late) + newdate = etree.SubElement(eleobj, 'comment') + newdata.text = cbobj.comment + newdata = etree.SubElement(eleobj, 'red') + newdata.text = str(cbobj.red) + + if(cbobj.duedate == None): + newdata = etree.SubElement(eleobj, 'dueyear') + newdata.text = "" + newdata = etree.SubElement(eleobj, 'duemonth') + newdata.text = "" + newdata = etree.SubElement(eleobj, 'duedate') + newdata.text = "" + newdata = etree.SubElement(eleobj, 'duehour') + newdata.text = "" + else: + newdata = etree.SubElement(eleobj, 'dueyear') + newdata.text = str(cbobj.duedate.year) + newdata = etree.SubElement(eleobj, 'duemonth') + newdata.text = str(cbobj.duedate.month) + newdata = etree.SubElement(eleobj, 'duedate') + newdata.text = str(cbobj.duedate.day) + newdata = etree.SubElement(eleobj, 'duehour') + newdata.text = str(cbobj.duedate.hour) + + if(cbobj.subdate == None): + newdata = etree.SubElement(eleobj, 'subyear') + newdata.text = "" + newdata = etree.SubElement(eleobj, 'submonth') + newdata.text = "" + newdata = etree.SubElement(eleobj, 'subdate') + newdata.text = "" + newdata = etree.SubElement(eleobj, 'subhour') + newdata.text = "" + else: + newdata = etree.SubElement(eleobj, 'subyear') + newdata.text = str(cbobj.duedate.year) + newdata = etree.SubElement(eleobj, 'submonth') + newdata.text = str(cbobj.duedate.month) + newdata = etree.SubElement(eleobj, 'subdate') + newdata.text = str(cbobj.duedate.day) + newdata = etree.SubElement(eleobj, 'subhour') + newdata.text = str(cbobj.duedate.hour) + + +def ntuceiba_toxml(listobj): + xmlroot = etree.Element('ntuceiba') + for entry in listobj: + newevt = etree.SubElement(xmlroot, 'ncevent') + XMLBuildNtuCaibaEvent(newevt, entry) + + return etree.tostring(xmlroot, xml_declaration=True, encoding='UTF-8') + |