aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author藍挺瑋 <lantw44@gmail.com>2012-12-21 09:52:09 +0800
committerLAN-TW <lantw44@gmail.com>2012-12-21 09:52:09 +0800
commit024f6e82e68b9e862387ec541dd4ab4328d9df9c (patch)
treefa4475e16eae807d7340d77d0cb483b6d8baaf5e
parent65b3e824ddc24ec7dc7bad883426ec88b1bcf39d (diff)
downloadinccalendar-024f6e82e68b9e862387ec541dd4ab4328d9df9c.tar.gz
inccalendar-024f6e82e68b9e862387ec541dd4ab4328d9df9c.tar.zst
inccalendar-024f6e82e68b9e862387ec541dd4ab4328d9df9c.zip
NTU CEIBA 解析支援,但網頁部份尚未實作(仍在測試中,可能修改 API)
繳交日期之後會改成字串,因為其實只有期限比較重要而已......
-rw-r--r--access/imnc.py28
-rw-r--r--jinhtml/import.html46
-rw-r--r--js/imnc.js40
-rw-r--r--ntuceiba/__init__.py17
-rw-r--r--ntuceiba/parse.py119
-rw-r--r--ntuceiba/toxml.py70
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>
diff --git a/js/imnc.js b/js/imnc.js
index db86053..9cfecf8 100644
--- a/js/imnc.js
+++ b/js/imnc.js
@@ -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')
+