├── index.html ├── old ├── a ├── csv0.py ├── index.html ├── kdb.json ├── kdb_20210404.csv ├── kdb_20210404.xlsx ├── script.js └── style.css └── readme.md /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

This page is transferred to Make-IT-TSUKUBA/alternative-tsukuba-kdb (https://make-it-tsukuba.github.io/alternative-tsukuba-kdb/).

8 | 9 | -------------------------------------------------------------------------------- /old/a: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/csv0.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import json 3 | 4 | output = [] 5 | headline = "" 6 | with open("kdb_202104042.csv", encoding="utf-8") as fp : 7 | reader = csv.reader(fp) 8 | 9 | for line in reader : 10 | line.pop(1) 11 | 12 | for i in range(5) : 13 | line.pop(11) 14 | 15 | isEmpty = False 16 | isHead = False 17 | 18 | if line[0] == "科目番号" : 19 | continue 20 | 21 | if line[0] == "" : 22 | isEmpty = True 23 | 24 | if not isEmpty and line[1] == "" : 25 | isHead = True 26 | 27 | if isHead : 28 | headline = line[0] 29 | print(line[0]) 30 | 31 | if isEmpty or isHead : 32 | continue 33 | 34 | if line[13] == "" : 35 | line.pop(13) 36 | if line[12] == "" : 37 | line.pop(12) 38 | 39 | line.append(headline) 40 | output.append(line) 41 | 42 | with open("kdb.json", "w", encoding="utf-8") as fp : 43 | json.dump(output, fp, indent="\t", ensure_ascii=False) 44 | -------------------------------------------------------------------------------- /old/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 筑波大学 KdBっぽいなにか 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |

16 | キーワード 17 | 検索 18 | 19 | 20 | 21 | 22 | 23 |

24 |

25 | 要件 26 | 60 | 検索条件をクリア 61 |

62 |

63 | 学期 64 | 65 | 66 | 67 | / 68 | 69 | 70 | 71 | 72 |

73 |

74 | 時限 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | / 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |

92 |

93 | 実施形態 94 | 95 | 96 | 97 | 98 |

99 |
100 |
101 |
102 | 103 |
104 |
105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
科目番号/科目名単位/年次学期/時期教室担当実施形態概要備考
121 |
122 | 126 |
127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /old/kdb_20210404.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inaniwaudon/alternative-tsukuba-kdb/2a25bd40c467c2c6324819d7899edce30b343a27/old/kdb_20210404.xlsx -------------------------------------------------------------------------------- /old/script.js: -------------------------------------------------------------------------------- 1 | window.onload = function () { 2 | const table = document.querySelector("main table tbody"); 3 | const keyword_input = document.querySelector("input[type=\"text\"]"); 4 | const form = document.getElementsByTagName("form")[0]; 5 | const req_A_input = document.getElementById("req_A"); 6 | const clearButton = document.getElementById("clear"); 7 | const downloadLink = document.getElementById("download"); 8 | 9 | // checkbox 10 | const checkName = document.getElementById("check-name"); 11 | const checkNo = document.getElementById("check-no"); 12 | const checkPerson = document.getElementById("check-person"); 13 | const checkRoom = document.getElementById("check-room"); 14 | const checkAbstract = document.getElementById("check-abstract"); 15 | 16 | // if the device is iOS, displayed lines are limited 500. 17 | const isIOS = ["iPhone", "iPad", "iPod"].some(name => navigator.userAgent.indexOf(name) > -1); 18 | const lineLimit = 500; 19 | 20 | let data = null; 21 | let timeout = void 0; 22 | 23 | keyword_input.addEventListener("keydown", (evt) => { 24 | const KEYCODE_ENTER = 13; 25 | if (evt.keyCode === KEYCODE_ENTER) { 26 | evt.preventDefault(); 27 | search(evt); 28 | } 29 | }); 30 | 31 | clearButton.addEventListener('click', (evt) => { 32 | evt.stopPropagation(); 33 | keyword_input.value = ""; 34 | req_A_input.selectedIndex = 0; 35 | form.season.value = "null"; 36 | form.module.value = "null"; 37 | form.day.value = "null"; 38 | form.period.value = "null"; 39 | form.online.value = "null"; 40 | 41 | checkName.checked = true; 42 | checkNo.checked = true; 43 | checkPerson.checked = false; 44 | checkRoom.checked = false; 45 | checkAbstract.checked = false; 46 | }); 47 | 48 | // display a line of the table 49 | const createLine = (line) => { 50 | let tr = document.createElement("tr"); 51 | table.appendChild(tr); 52 | 53 | let url = `https://kdb.tsukuba.ac.jp/syllabi/2021/${line[0]}/jpn`; 54 | let methods = ["対面", "オンデマンド", "同時双方向"].filter(it => line[10].indexOf(it) > -1); 55 | 56 | tr.innerHTML += `${line[0]}
${line[1]}
シラバス`; 57 | tr.innerHTML += `${line[3]}単位
${line[4]}年次`; 58 | tr.innerHTML += `${line[5]}
${line[6]}`; 59 | tr.innerHTML += `${line[7].replace(/,/g, "
")}`; 60 | tr.innerHTML += `${line[8].replace(/,/g, "
")}`; 61 | 62 | if (methods.length < 1) 63 | tr.innerHTML += "不詳" 64 | else 65 | tr.innerHTML += `${methods.join('
')}
`; 66 | 67 | tr.innerHTML += `${line[9]}`; 68 | tr.innerHTML += `${line[10]}`; 69 | } 70 | 71 | 72 | // update the table 73 | const updateTable = (options, index, displayedIndex) => { 74 | let regex = new RegExp(options.keyword); 75 | 76 | index = typeof index === 'undefined' ? 0 : index; 77 | displayedIndex = typeof displayedIndex === "undefined" ? 0 : displayedIndex; 78 | 79 | if (isIOS && displayedIndex >= lineLimit) 80 | return; 81 | 82 | for (; ;) { 83 | const line = data[index]; 84 | 85 | if (typeof line === 'undefined') { 86 | return; 87 | } 88 | 89 | // keyword 90 | let matchesNo = checkNo.checked ? line[0].indexOf(options.keyword) != 0 : true; 91 | let matchesName = checkName.checked ? line[1].match(regex) == null : true; 92 | let matchesRoom = checkRoom.checked ? line[7].match(regex) == null : true; 93 | let matchesPerson = checkPerson.checked ? line[8].match(regex) == null : true; 94 | let matchesAbstract = checkAbstract.checked ? line[9].match(regex) == null : true; 95 | 96 | let matchesKeyword = options.keyword != "" && 97 | (matchesNo && matchesName && matchesRoom && matchesPerson && matchesAbstract); 98 | 99 | // other options 100 | let missMatchesSeason = options.season != "null" && line[5].indexOf(options.season) < 0; 101 | let missMatchesModule = options.module_ != "null" && line[5].indexOf(options.module_) < 0; 102 | let missMatchesDay = options.day != "null" && line[6].indexOf(options.day) < 0; 103 | let missMatchesPeriod = options.period != "null" && line[6].indexOf(options.period) < 0; 104 | let missMatchesOnline = options.online != "null" && line[10].indexOf(options.online) < 0; 105 | let missMatchesReq_A = options.req_A != "null" && options.req_A != line[12]; 106 | 107 | if ( 108 | matchesKeyword || 109 | missMatchesSeason || 110 | missMatchesModule || 111 | missMatchesDay || 112 | missMatchesPeriod || 113 | missMatchesOnline || 114 | missMatchesReq_A) { 115 | index++; 116 | continue; 117 | } 118 | 119 | createLine(line); 120 | timeout = setTimeout(() => updateTable(options, index + 1, ++displayedIndex), 0); 121 | break; 122 | } 123 | } 124 | 125 | // convert table data to CSV file with utf-8 BOM 126 | const makeCSV = (a, table_, filename) => { 127 | var escaped = /,|\r?\n|\r|"/; 128 | var e = /"/g; 129 | 130 | var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); 131 | var csv = [], row = [], field, r, c; 132 | for (r=0; r { 156 | makeCSV( 157 | downloadLink, document.querySelector("main table"), `kdb_${getDateString()}.csv`); 158 | } 159 | 160 | // get YYYYMMDDhhmmdd 161 | const getDateString = () => { 162 | let date = new Date(); 163 | let Y = date.getFullYear(); 164 | let M = ("00" + (date.getMonth()+1)).slice(-2); 165 | let D = ("00" + date.getDate()).slice(-2); 166 | let h = ('0' + date.getHours()).slice(-2); 167 | let m = ('0' + date.getMinutes()).slice(-2); 168 | let d = ('0' + date.getSeconds()).slice(-2); 169 | 170 | return Y + M + D + h + m + d; 171 | } 172 | 173 | // search 174 | const search = (e) => { 175 | // clear tbody contents 176 | table.innerHTML = ''; 177 | 178 | if (e !== null) { 179 | e.stopPropagation(); 180 | } 181 | let options = {}; 182 | 183 | options.keyword = keyword_input.value; 184 | options.req_A = req_A_input.options[req_A_input.selectedIndex].value; 185 | options.season = form.season.value; 186 | options.module_ = form.module.value; 187 | options.day = form.day.value; 188 | options.period = form.period.value; 189 | options.online = form.online.value; 190 | 191 | clearTimeout(timeout); 192 | 193 | updateTable(options); 194 | } 195 | 196 | let submit = document.getElementById("submit"); 197 | submit.onclick = search; 198 | downloadLink.onclick = downloadCSV; 199 | 200 | fetch("kdb.json") 201 | .then(response => response.json()) 202 | .then(json => { data = json; search(null); }); 203 | }; 204 | -------------------------------------------------------------------------------- /old/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: "Noto Sans JP", sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | header { 8 | width: 100%; 9 | position:fixed; 10 | top: 0; 11 | background: linear-gradient(90deg, rgba(242,230,255,0.95), rgba(255,255,255,0.95) 250px); 12 | } 13 | 14 | header form { 15 | position: sticky; 16 | top: 0; 17 | } 18 | 19 | header p { 20 | margin:0; 21 | } 22 | header p + p { 23 | margin-top: 0.4rem; 24 | } 25 | 26 | header div.content { 27 | width: 1100px; 28 | margin: auto; 29 | padding: 0.6rem 1rem; 30 | } 31 | 32 | header .h4 { 33 | width: 5rem; 34 | text-align: justify; 35 | margin-right: 1.4rem; 36 | display: inline-block; 37 | } 38 | 39 | header input[type="text"], header select { 40 | width: 22rem; 41 | height: 1.8rem; 42 | line-height: 1.8rem; 43 | margin-right: 0.2rem; 44 | padding:0 0.4rem; 45 | border: none; 46 | border-radius: 4px; 47 | box-sizing: content-box; 48 | box-shadow: 0 1px 2px rgba(0,0,0,0.4); 49 | vertical-align: top; 50 | -webkit-appearance: none; 51 | } 52 | 53 | a#submit, a#clear { 54 | color: #fff; 55 | height: 1rem; 56 | line-height:1rem; 57 | text-decoration: none; 58 | padding:0.45rem 0.4rem; 59 | border-radius: 4px; 60 | background: #60c; 61 | display: inline-block; 62 | } 63 | 64 | 65 | #page { 66 | width: 1100px; 67 | margin: 11.5rem auto 0 auto; 68 | padding: 0 1rem; 69 | } 70 | 71 | table { 72 | width: 100%; 73 | font-size: 0.9rem; 74 | border-spacing: 0; 75 | table-layout: fixed; 76 | overflow-x: scroll; 77 | border-collapse: collapse; 78 | } 79 | 80 | tr th { 81 | color: #fff; 82 | text-align: left; 83 | font-weight: normal; 84 | padding: 0.2rem 0; 85 | background: #60c; 86 | } 87 | tr th:first-child { 88 | padding-left: 0.4rem; 89 | } 90 | 91 | td { 92 | line-height: 1.4em; 93 | padding: 0.2rem 0; 94 | border-bottom: solid 1px #ccc; 95 | vertical-align: top; 96 | } 97 | 98 | td a.syllabus { 99 | color: #fff; 100 | text-align: center; 101 | text-decoration: none; 102 | font-size: 0.8rem; 103 | margin: 0.2rem 0; 104 | padding: 0.1rem 0.3rem; 105 | color: #63c; 106 | border-radius: 1rem; 107 | background: linear-gradient(30deg, #f2e6ff, #fff); 108 | box-shadow: 0 1px 2px rgba(0,0,0,0.2); 109 | display: inline-block; 110 | } 111 | 112 | td a.syllabus:hover { 113 | color: #fff; 114 | background: #63c; 115 | } 116 | 117 | td { 118 | padding-right: 0.4rem; 119 | } 120 | 121 | tr *:nth-child(1) { width: 14rem; } 122 | tr *:nth-child(2) { width: 5rem; } 123 | tr *:nth-child(3) { width: 5rem; } 124 | tr *:nth-child(4) { width: 6rem; } 125 | tr *:nth-child(5) { width: 6rem; } 126 | tr *:nth-child(6) { width: 6rem; } 127 | tr td:nth-child(7) { 128 | width:18rem; 129 | line-height: 1.3em; 130 | font-size: 0.6rem; 131 | } 132 | tr td:nth-child(8) { 133 | line-height: 1.3em; 134 | font-size: 0.6rem; 135 | } 136 | 137 | footer { 138 | text-align: center; 139 | margin: 1rem 0 2rem 0; 140 | } 141 | 142 | form { 143 | position: sticky; 144 | top: 0; 145 | } 146 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # alternative-tsukuba-kdb 2 | An informal website of the alternative of KdB, a curriculum planning support system used in University of Tsukuba. 3 | 4 | **This repository is being managed by Make-IT-TSUKUBA of a software developping organization.** 5 | 6 | **Therefore, this is so old that you should access [Make-IT-TSUKUBA/alternative-tsukuba-kdb](https://github.com/Make-IT-TSUKUBA/alternative-tsukuba-kdb)**. 7 | 8 | This web site can be used at https://make-it-tsukuba.github.io/alternative-tsukuba-kdb ~~https://inaniwaudon.github.io/alternative-tsukuba-kdb/~~ 9 | --------------------------------------------------------------------------------