Skip to content

Commit

Permalink
Added teacher vplan type
Browse files Browse the repository at this point in the history
- different riot tags for students and teacher column
- UploadWatcher refreshes frontend on deleting a used vplan
- VplanParser analyses vplan type
  • Loading branch information
DrJume committed Jun 18, 2018
1 parent 7d18684 commit a938d30
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 16 deletions.
2 changes: 1 addition & 1 deletion handlers/TaskScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function StartTaskRunner() {
await Updater.runUpdate(update)
})

// Vplan day shift on week days
// Vplan day shift on week days // TODO: check for code quality
cron.schedule('0 3 * * Mon-Fri', async () => {
log.info('VPLAN_DAY_SHIFT')

Expand Down
1 change: 0 additions & 1 deletion handlers/VplanReceiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ async function RunVplanReceiver() {
})
log.debug('JSON_NEW_FILEPATH', jsonFilePath)

log.debug('RELOAD_SOCKET_FIRED')
FrontendNotifier.reloadAll()

try_(
Expand Down
1 change: 1 addition & 0 deletions services/FrontendNotifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const FrontendNotifier = {
},

reloadAll() {
log.debug('RELOAD_ALL_SOCKET_FIRED')
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send('RELOAD_ALL')
Expand Down
21 changes: 18 additions & 3 deletions services/UploadWatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const nextVplanPath = path.join(uploadDir, 'next')
const XmlParser = require('services/XmlParser')
const VplanParser = require('services/VplanParser')

const FrontendNotifier = require('services/FrontendNotifier')

module.exports = async function UploadWatcher(callback) {
if (
!fs.existsSync(uploadDir) ||
Expand All @@ -31,7 +33,21 @@ module.exports = async function UploadWatcher(callback) {
cwd: '.',
awaitWriteFinish: true,
})
.on('add', async (filePath) => { // TODO: add delete listener when vplan removed
.on('unlink', async (filePath) => {
log.debug('FILE_REMOVED', filePath)

// get the last folder name in the uploadPath
const uploadLocation = path.parse(filePath).dir.split(path.sep).pop()

if (path.extname(filePath) === '.json') {
if (['current', 'next'].includes(uploadLocation)) {
// used vplan was deleted, refresh displays
log.warn('VPLAN_FILE_REMOVED', filePath)
FrontendNotifier.reloadAll()
}
}
})
.on('add', async (filePath) => {
log.debug('FILE_DETECTED', filePath)

// get the last folder name in the uploadPath
Expand Down Expand Up @@ -70,7 +86,7 @@ module.exports = async function UploadWatcher(callback) {

// Queueday determination

// on manual upload
// manual upload
if (['current', 'next'].includes(uploadLocation)) {
log.info('MANUAL_UPLOAD')
log.info('DETECTING_QUEUEDAY_BY_UPLOAD_DIR')
Expand All @@ -80,7 +96,6 @@ module.exports = async function UploadWatcher(callback) {
}

// normal upload

const queueDay = VplanParser.determineQueueDay(transformedVplanData)
if (!queueDay) {
log.warn('UNKNOWN_QUEUEDAY_UPLOAD_DELETED', filePath)
Expand Down
58 changes: 56 additions & 2 deletions services/VplanParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const KeyDictionary = {
lehrer: 'teacher',
raum: 'room',
info: 'info',
vfach: 'new_subject',
vlehrer: 'new_teacher',
vraum: 'new_room',
}

const Templates = {
Expand Down Expand Up @@ -49,20 +52,71 @@ const Templates = {
],
footer: 'vp.fuss.fusszeile.fussinfo._',
},

[VplanType.TEACHERS]: {
head: {
title: 'vp.kopf.titel._',
schoolname: 'vp.kopf.schulname._',
created: 'vp.kopf.datum._',
changed: {
classes: 'vp.kopf.kopfinfo.abwesendk._',
teachers: 'vp.kopf.kopfinfo.abwesendl._',
},
missing: {
classes: 'vp.kopf.kopfinfo.aenderungk._',
teachers: 'vp.kopf.kopfinfo.aenderungl._',
},
},
body: [
'vp.haupt.aktion.*',
entries => entries.map(entry => Object.assign(
{},
...Object.keys(entry)
.map(key => ({
[KeyDictionary[key]]: entry[key]._ ? entry[key]._ : '',
})),
{
changed: Object.keys(entry)
.map(key => (entry[key].$ ? KeyDictionary[key] : ''))
.filter(val => val), // let all solid values through
},
)),
],
supervision: [
'vp.aufsichten.aufsichtzeile.*',
entries => entries.map(entry => entry.aufsichtinfo._),
],
footer: 'vp.fuss.fusszeile.fussinfo._',
},
}

const VplanParser = {
detectType(rawVplanJSObject) {
return VplanType.STUDENTS
const rawInstructionStylesheet = rawVplanJSObject._instruction['xml-stylesheet']
.split('href="')[1]
.split('"')[0]

log.debug('RAW_VPLAN_TYPE', rawInstructionStylesheet)

const isStudents = rawInstructionStylesheet === 'vplank.xsl'
const isTeachers = rawInstructionStylesheet === 'vplanl.xsl'

if (isStudents) return VplanType.STUDENTS
if (isTeachers) return VplanType.TEACHERS
return undefined
},

async transform(rawVplanJSObject) {
const vplanType = this.detectType(rawVplanJSObject)
if (!vplanType) return { transformedVplanData: undefined, vplanType: undefined }

const [, transformedVplanData] = try_(
let [, transformedVplanData] = try_(
() => fanci.transform(rawVplanJSObject, Templates[vplanType]),
'VPLAN_PARSE_ERR',
)
// prepend type attribute
transformedVplanData = Object.assign({ type: vplanType }, transformedVplanData)

return { transformedVplanData, vplanType }
},

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<vplan-column>
<vplan-students-column>
<div ref="head" style="margin-top: 5px; margin-bottom: 10px" hidden>
<h2 class="title is-2">{ vplan.head.title }</h2>
</div>
Expand Down Expand Up @@ -113,4 +113,4 @@


</script>
</vplan-column>
</vplan-students-column>
120 changes: 120 additions & 0 deletions src/riot-tags/vplan-teachers-column.tag
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<vplan-teachers-column>
<div ref="head" style="margin-top: 5px; margin-bottom: 10px" hidden>
<h2 class="title is-2">{ vplan.head.title }</h2>
</div>

<table ref="table" class="table is-fullwidth is-narrow is-striped" hidden>
<thead>
<th>Lehrer</th>
<th>Stunde</th>
<th>Klasse/Kurs</th>
<th>Fach neu</th>
<th>Raum neu</th>
<th>für Fach</th>
<th>für Lehrer</th>
<th>Info</th>
</thead>
<tbody></tbody>
</table>

<div ref="progress" style="margin: auto 10px 15px 10px" hidden>
<progress class="progress is-small" value="0" max="100"></progress>
</div>

<div ref="notification" class="notification subtitle is-2 has-text-grey" style="margin: auto 10% auto 10%" hidden>
Der Vertretungsplan folgt demnächst
</div>

<script>
this.vplan = {
head: {
title: ""
}
}

let indexThreshold = 0

this.on('mount', () => {
const head = this.refs.head
const table = this.refs.table
const progress = this.refs.progress
const notification = this.refs.notification

axios(`/api/${this.opts.queue}?type=teachers`)
.then(res => {
this.vplan = res.data

console.log(this.vplan.body)

head.hidden = false
table.hidden = false
progress.hidden = false

this.update()
})
.catch(err => {
console.log(err)

if (err.response) {
console.log(err.response)
notification.hidden = false
}
})
})

this.on('updated', () => {
const head = this.refs.head
const table = this.refs.table
const progress = this.refs.progress
const notification = this.refs.notification

const getOuterHeight = (el) =>
el.offsetHeight + parseFloat(getComputedStyle(el)['margin-top'].match(/\d+/g)[0]) + parseFloat(getComputedStyle(el)['margin-bottom'].match(/\d+/g)[0])

const isTableOverflowing = () => ((getOuterHeight(head) + getOuterHeight(table) + getOuterHeight(progress)) > window.innerHeight)

for (let [index, entry] of this.vplan.body.entries()) {
if (index < indexThreshold) continue
if (isTableOverflowing()) continue

const entryRow = document.createElement('tr')
entryRow.innerHTML = `
<td>${entry.new_teacher}</td>
<td>${entry.lesson}</td>
<td>${entry.class}</td>
<td>${entry.new_subject}</td>
<td>${entry.new_room}</td>
<td>${entry.subject}</td>
<td>${entry.teacher}</td>
<td>${entry.info}</td>
`
table.tBodies[0].appendChild(entryRow)

}
if (isTableOverflowing()) table.tBodies[0].deleteRow(table.tBodies[0].rows.length - 1)

console.log(indexThreshold, table.tBodies[0].rows.length, this.vplan.body.length - 1)

indexThreshold += table.tBodies[0].rows.length
if (indexThreshold >= this.vplan.body.length - 1) indexThreshold = 0

setTimeout(() => {
table.tBodies[0].innerHTML = ''
this.update()
}, 9000)

window.vplan = this.vplan
window.table = table
window.head = head
window.progress = progress
window.getOuterHeight = getOuterHeight
})







</script>
</vplan-teachers-column>
2 changes: 1 addition & 1 deletion views/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</div>
</section>

<script src="/assets/riot-3.10.0/riot.js"></script>
<script src="/assets/riot-3.10.2/riot.js"></script>
<script src="/assets/riot-route-3.1.3/route+tag.js"></script>
<script src="/riot/tags.js"></script>
<script>
Expand Down
12 changes: 7 additions & 5 deletions views/display/students.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Vplan-ViSo</title>
<title>Schüler-Anzeige</title>
<link rel="stylesheet" href="/assets/bulma-0.7.1/bulma.css">
<style type="riot"></style>
<script defer src="/assets/fontawesome-5.0.13/fontawesome-all.min.js"></script>
</head>

<body>
<div class="columns is-gapless has-text-centered is-marginless" style="height: 100vh">
<vplan-column queue="current" class="column" style="display: flex; flex-direction: column; border-right: 1px solid"></vplan-column>
<vplan-column queue="next" class="column" style="display: flex; flex-direction: column; border-left: 1px solid"></vplan-column>
<vplan-students-column queue="current" class="column" style="display: flex; flex-direction: column; border-right: 1px solid"></vplan-students-column>
<vplan-students-column queue="next" class="column" style="display: flex; flex-direction: column; border-left: 1px solid"></vplan-students-column>
</div>

<script src="/assets/riot-3.10.0/riot.js"></script>
<span style="position: fixed; bottom: 0px; right: 0px; font-size: 10px;">Version 0.5.0</span>

<script src="/assets/riot-3.10.2/riot.js"></script>
<script src="/assets/axios-0.18.0/axios.js"></script>
<script src="/riot/tags.js"></script>
<script>
riot.mount('vplan-column')
riot.mount('vplan-students-column')
</script>

<script src="/assets/notification-listener.js"></script>
Expand Down
30 changes: 29 additions & 1 deletion views/display/teachers.html
Original file line number Diff line number Diff line change
@@ -1 +1,29 @@
TEACHERS
<!DOCTYPE html>
<html lang="de" style="overflow: hidden; cursor: none">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Lehrer-Anzeige</title>
<link rel="stylesheet" href="/assets/bulma-0.7.1/bulma.css">
<style type="riot"></style>
<script defer src="/assets/fontawesome-5.0.13/fontawesome-all.min.js"></script>
</head>

<body>
<div class="columns is-gapless has-text-centered is-marginless" style="height: 100vh">
<vplan-teachers-column queue="current" class="column" style="display: flex; flex-direction: column; border-right: 1px solid"></vplan-teachers-column>
<vplan-teachers-column queue="next" class="column" style="display: flex; flex-direction: column; border-left: 1px solid"></vplan-teachers-column>
</div>

<script src="/assets/riot-3.10.2/riot.js"></script>
<script src="/assets/axios-0.18.0/axios.js"></script>
<script src="/riot/tags.js"></script>
<script>
riot.mount('vplan-teachers-column')
</script>

<script src="/assets/notification-listener.js"></script>
</body>

</html>

0 comments on commit a938d30

Please sign in to comment.