diff --git a/cutprogress.py b/cutprogress.py index c1741b1f042ea8abd2439ab16334d0fbdea3612f..0b382351241fdca61df19c6d57f5a4ab4b6c034a 100644 --- a/cutprogress.py +++ b/cutprogress.py @@ -1,5 +1,5 @@ from server import * -from datetime import time +import datetime @register_navbar('Schnittfortschritt User', icon='spinner', iconlib='fa', userendpoint=True, endpoint='cutprogress_user') @register_navbar('Schnittfortschritt', icon='spinner', iconlib='fa') @@ -7,33 +7,94 @@ from datetime import time @app.route('/internal/user/<int:user>/cutprogress', endpoint='cutprogress_user') @mod_required def cutprogress(user=None): + # use request argument, default to latest semester allsemester = query('SELECT DISTINCT semester from courses ORDER BY semester DESC') semester = request.values.get('semester', allsemester[0]['semester']) - coursesraw = query('SELECT courses.id, courses.handle, courses.short FROM courses WHERE semester = ?', semester) - courses = [] - maxlecturecount = 0 - for course in coursesraw: - course['lectures'] = query(''' - SELECT lectures.title, lectures.time, lectures.id FROM lectures - WHERE lectures.course_id= ? AND NOT lectures.deleted AND NOT lectures.norecording - ORDER BY lectures.time''', course['id']) - for lecture in course['lectures']: - lecture['videos'] = query(''' - SELECT videos.path, formats.description as formatdesc, videos.visible FROM videos - JOIN formats ON (videos.video_format = formats.id) - WHERE videos.lecture_id = ? AND NOT videos.deleted''', lecture['id']) - course['responsible'] = query('''SELECT users.* - FROM responsible - JOIN users ON (responsible.user_id = users.id AND responsible.course_id = ?) - ORDER BY users.realname ASC''', course['id']) - if len(course['responsible']) == 0: - course['responsible'] = [{"realname": "Niemand", "id": -1}] - if not user or user in [ r['id'] for r in course['responsible'] ]: - courses.append(course) - maxlecturecount = max(len(course['lectures']), maxlecturecount) + + # filter to single user? + if user is not None: + user = query('SELECT * FROM users WHERE id = ?', user)[0] + + # column headers: courses + courses = query(''' + SELECT courses.id, courses.handle, courses.short, courses.responsible + FROM courses + WHERE semester = ? + ORDER by id DESC + ''', semester) + + # list of people responsible for course + for course in courses: + people = query(''' + SELECT users.* + FROM users + JOIN responsible ON responsible.user_id = users.id + WHERE responsible.course_id = ? + ORDER BY users.realname ASC + ''', course['id']) + + if not people: + people = [{ 'realname': 'Niemand' }] + + course['responsible'] = people + + # fetch lectures + lectures = query(''' + SELECT + lectures.id, + lectures.course_id, + lectures.time, DATE(lectures.time) as date, + lectures.title, + COUNT(videos.id) as videos_total, + COUNT(videos.visible) as videos_visible + FROM lectures + JOIN courses ON courses.id = lectures.course_id + LEFT JOIN videos ON lectures.id = videos.lecture_id + WHERE courses.semester = ? + AND date <= DATE('now') + AND NOT lectures.norecording + GROUP BY lectures.id + ORDER BY date DESC, lectures.time ASC, lectures.id ASC + ''', semester) + + # sort dates, figure out when weeks change + dates = sorted({ + datetime.datetime.strptime(row['date'], '%Y-%m-%d') + for row in lectures + }, reverse=True) + + # check week numbers + is_new_weeks = [ + False if (i == 0) else thisdate.isocalendar()[1] != dates[i-1].isocalendar()[1] + for i, thisdate in enumerate(dates) + ] + + # sort into cells + tablebody = [ + { + 'date': date, # row header + 'is_new_week': is_new_week, + 'cells': [ # this is the body of the row + [ # this list is a cell + lecture + for lecture in lectures + if lecture['course_id'] == course['id'] and datetime.datetime.strptime(lecture['date'], '%Y-%m-%d') == date + and (user is None or user in [r['id'] for r in course['responsible']]) + ] + for course in courses + ] + } + for date,is_new_week in zip(dates, is_new_weeks) + ] + return render_template('cutprogress.html', - allsemester=allsemester, - semester=semester, - courses=courses, - maxlecturecount=maxlecturecount, - user=query('SELECT * FROM users WHERE id = ?', user)[0] if user else None) + # dropdown selection + allsemester=allsemester, # options + semester=semester, # choice + user=user, + + # content + courses=courses, + dates=dates, + tablebody=tablebody, + ) diff --git a/static/style.css b/static/style.css index becd506401df17e70822ae06b1ac844e598392b0..e2060c23287d11d3987ee1ba1ee9070964b80702 100644 --- a/static/style.css +++ b/static/style.css @@ -144,3 +144,7 @@ th.rotate > div { max-width: 500px; } + +#cutprogress.table tr.weekbreak td { + border-top: 2px solid black !important; +} diff --git a/templates/cutprogress.html b/templates/cutprogress.html index ca1ccf9c7ea906dae246e7ba1e8715ae5e05c424..6e145d2334f4a9978770a7bd1dbb62366eb172f9 100644 --- a/templates/cutprogress.html +++ b/templates/cutprogress.html @@ -12,8 +12,11 @@ </span> </div> <div class="panel-body table-responsive"> - <table class="table table-condensed table-bordered"> + <table id="cutprogress" class="table table-condensed table-bordered"> <tr> + <th class="text-left"> + Datum + </th> {% for course in courses %} <th class="text-center rotate"> <div> @@ -22,33 +25,27 @@ </th> {% endfor %} </tr> - {% for i in range(maxlecturecount) %} - <tr class="text-center"> - {% for course in courses %} + + {% for row in tablebody %} + <tr class="text-center {% if row.is_new_week %}weekbreak{% endif %}"> + <td class="text-left">{{ row.date.strftime("%d.%m.%Y (%a)") }}</td> + {% for cell in row.cells %} <td> - {% set l = course.lectures[i]|d({}) %} - {% if "time" in l %} - <a href="{{ url_for("course", handle=course.handle) }}#lecture-{{ l.id }}" title="{{ l.time }} Titel: {{ l.title|replace('\n','') }} Videos: {{ l.videos|count }} Internes Kommentar: {{ l.internal }}"> - {% if l.time < datetime.now() %} - {% if l.videos|count == 0 %} + {% for lecture in cell %} + <a href="{{ url_for('course', handle=lecture.course_id) }}#lecture-{{ lecture.id }}" title="Uhrzeit: {{ lecture.time.strftime('%H:%M') }} Titel: {{ lecture.title|replace('\n','') }} Videos: {{ lecture.videos_total }} Interner Kommentar: {{ lecture.internal }}"> + {% if lecture.videos_total == 0 %} <span style="color: red" aria-hidden="true" class="fa fa-times"></span> - {% else %} - {% if l.videos|selectattr('visible')|list|count == 0 %} - <span style="color: orange" aria-hidden="true" class="glyphicon glyphicon-ok"></span> - {% else %} - <span style="color: green" aria-hidden="true" class="glyphicon glyphicon-ok"></span> - {% endif %} - {% endif %} + {% elif lecture.videos_visible == 0 %} + <span style="color: orange" aria-hidden="true" class="glyphicon glyphicon-ok"></span> {% else %} - <span style="color: grey" aria-hidden="true" class="fa fa-times"></span> + <span style="color: green" aria-hidden="true" class="glyphicon glyphicon-ok"></span> {% endif %} - </a> - {% else %} - {% endif %} + </a> + {% endfor %} </td> {% endfor %} </tr> - {% endfor %} + {% endfor %} </table> </div> </div>