Skip to content

Commit

Permalink
Merge PR pyvec#259 - Add course info cards & calendars for runs
Browse files Browse the repository at this point in the history
  • Loading branch information
encukou committed Nov 14, 2017
2 parents 4fe0c57 + 5147d58 commit 8a977aa
Show file tree
Hide file tree
Showing 13 changed files with 414 additions and 95 deletions.
8 changes: 5 additions & 3 deletions naucse/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,10 @@ def merge_dict(base, patch):

class Session(Model):
"""An ordered collection of materials"""
def __init__(self, root, path, base_course, info):
def __init__(self, root, path, base_course, info, index):
super().__init__(root, path)
base_name = info.get('base')
self.index = index
if base_name is None:
self.info = info
else:
Expand Down Expand Up @@ -334,8 +335,9 @@ def get_coverpage_content(self, run, coverpage, app):

def _get_sessions(course, plan):
result = OrderedDict()
for sess_info in plan:
session = Session(course.root, course.path, course.base_course, sess_info)
for index, sess_info in enumerate(plan):
session = Session(course.root, course.path, course.base_course,
sess_info, index=index)
result[session.slug] = session

sessions = list(result.values())
Expand Down
59 changes: 59 additions & 0 deletions naucse/routes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import datetime
import calendar

from flask import Flask, render_template, url_for, send_from_directory
from flask import abort, redirect
Expand Down Expand Up @@ -111,6 +112,32 @@ def lesson_static(lesson, path):
return send_from_directory(directory, filename)


def get_recent_runs(course):
"""Build a list of "recent" runs based on a course.
By recent we mean: haven't ended yet, or ended up to ~2 months ago
(Note: even if naucse is hosted dynamically,
it's still beneficial to show recently ended runs.)
"""
recent_runs = []
if not course.start_date:
today = datetime.date.today()
cutoff = today - datetime.timedelta(days=2*30)
this_year = today.year
for year, run_year in reversed(course.root.run_years.items()):
for run in run_year.runs.values():
if run.base_course is course and run.end_date > cutoff:
recent_runs.append(run)
if year < this_year:
# Assume no run lasts for more than a year,
# e.g. if it's Jan 2018, some run that started in 2017 may
# be included, but don't even look through runs from 2016
# or earlier.
break
recent_runs.sort(key=lambda r: r.start_date, reverse=True)
return recent_runs


@app.route('/<course:course>/')
def course(course):
def lesson_url(lesson, *args, **kwargs):
Expand All @@ -123,6 +150,7 @@ def lesson_url(lesson, *args, **kwargs):
plan=course.sessions,
title=course.title,
lesson_url=lesson_url,
recent_runs=get_recent_runs(course),
**vars_functions(course.vars),
edit_path=course.edit_path)
except TemplateNotFound:
Expand Down Expand Up @@ -266,3 +294,34 @@ def session_url(session):
homework_section=homework_section,
link_section=link_section,
cheatsheet_section=cheatsheet_section)


def list_months(start_date, end_date):
"""Return a span of months as a list of (year, month) tuples
The months of start_date and end_date are both included.
"""
months = []
year = start_date.year
month = start_date.month
while (year, month) <= (end_date.year, end_date.month):
months.append((year, month))
month += 1
if month > 12:
month = 1
year += 1
return months


@app.route('/<course:course>/calendar/')
def course_calendar(course):
if not course.start_date:
abort(404)
sessions_by_date = {s.date: s for s in course.sessions.values()}
return render_template('course_calendar.html',
edit_path=course.edit_path,
course=course,
sessions_by_date=sessions_by_date,
months=list_months(course.start_date,
course.end_date),
calendar=calendar.Calendar())
72 changes: 72 additions & 0 deletions naucse/static/css/calendar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.calendar-heading {
margin-top: 2em;
margin-bottom: 1em;
text-align: center;
}

table.calendar {
border-spacing: 0.25em;
border-collapse: separate;
margin: 0.5em auto;
margin-left: auto;
margin-right: auto;
}

table.calendar tr {
height: 4em;
}

table.calendar td,
table.calendar th {
width: 14.28%;
height: 100%;
background-color: rgba(0,0,0,.03);
vertical-align: center;
text-align: center;
box-sizing: border-box;
padding: 0;
}

table.calendar td.foreign-month {
background-color: transparent;
color: rgba(0,0,0,.1);
}

table.calendar td.no-event {
color: #343a40;
}

table.calendar td.event {
background-color: #3fb0ac;
color: white;
}

table.calendar td.event a {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 100%;
padding: 0.5em;
color: white;
}

table.calendar .session-number {
display: block;
}

table.calendar .session-title {
display: block;
text-align: center;
text-overflow: '…';
white-space: nowrap;
width: 4em;
overflow: hidden;
}

@media (min-width: 768px) {
table.calendar td,
table.calendar th {
min-width: 5em;
}
}
13 changes: 13 additions & 0 deletions naucse/static/css/nausce.css
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ a:hover {
margin-bottom: 1rem;
}

.course-card {
margin-top: 3em;
}
@media (min-width: 992px) {
.course-card {
margin-top: 0;
}
}

.course-card .recent-runs li {
margin-top: 1em;
}

/*************************/

pre {
Expand Down
12 changes: 11 additions & 1 deletion naucse/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ def __str__(self):
}


@template_filter()
def format_date(date, relative_to=None):
return '{d.day}. {d.month}. {d.year}'.format(d=date)


@template_filter()
def format_date_range(start_and_end):
start, end = start_and_end
Expand All @@ -182,5 +187,10 @@ def format_date_range(start_and_end):
else:
parts += ['{start.day}.']
parts += [' – ']
parts += ['{end.day}. {end.month}. {end.year}']
parts += [format_date(end)]
return ''.join(parts).format(start=start, end=end)

@template_filter()
def monthname(number):
return ('Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec',
'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec')[number-1]
8 changes: 4 additions & 4 deletions naucse/templates/_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{% endif %}
</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">

{% if page is defined and page.latex %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
Expand Down Expand Up @@ -76,9 +76,9 @@
</div>
</div>

<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

{% if page is defined and page.latex %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js" integrity="sha384-/y1Nn9+QQAipbNQWU65krzJralCnuOasHncUFXGkdwntGeSvQicrYkiUBwsgUqc1" crossorigin="anonymous"></script>
Expand Down
46 changes: 0 additions & 46 deletions naucse/templates/_lessons_list.html

This file was deleted.

6 changes: 3 additions & 3 deletions naucse/templates/backpage.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ <h2>Zajímavé odkazy</h2>
<hr class="lesson-end">
<div class="row prev-next">
<div class="col text-left">
<a href="{{ session_url(course.slug, session.slug) }}"><span class="hidden-xs-down">Lekce: {{ session.title }}</span></a>
<a href="{{ session_url(course.slug, session.slug) }}"><span class="d-none d-sm-block">Lekce: {{ session.title }}</span></a>
</div>

<div class="col text-left">
<a href="{{ course_url(course) }}"><span class="hidden-xs-down">{{ course.title }}</span></a>
<a href="{{ course_url(course) }}"><span class="d-none d-sm-block">{{ course.title }}</span></a>
</div>

<div class="col text-right">
{% if session.next is defined and session.next != None %}
<a href="{{ session_url(course.slug, session.next.slug) }}"><span class="hidden-xs-down">Lekce: {{ session.next.title }}</span></a>
<a href="{{ session_url(course.slug, session.next.slug) }}"><span class="d-none d-sm-block">Lekce: {{ session.next.title }}</span></a>
{% endif %}
</div>
</div>
Expand Down
Loading

0 comments on commit 8a977aa

Please sign in to comment.