Skip to content
Snippets Groups Projects
Commit d9c51eb9 authored by Martin Mareš's avatar Martin Mareš
Browse files

App: The first attempt

parent cf4d01cd
Branches
No related tags found
No related merge requests found
......@@ -7,3 +7,5 @@
další instance, které mají stejné id, ale jiné uuid?)
- hooky na create/delete user
- přehlednější log
- type=1 ignorovat (nestěžovat si, že je unknown)
- indexy
#!/bin/sh
export FLASK_APP=zoom.py
export FLASK_ENV=development
flask "$@"
<!DOCTYPE html>
<html>
<head>
<style>
#heading {
position: relative;
}
#schedule {
position: relative;
top: 2.5ex;
}
.room {
border: 1px solid green;
}
.hour {
border-bottom: 1px solid green;
}
.roomhead p {
text-align: center;
font-weight: bold;
margin-top: 0;
}
.meeting {
border: 1px solid blue;
font-size: smaller;
background-color: #ccccff;
}
</style>
</head>
<body>
<h1>MFF Zoom</h1>
<form method=GET action="?">
<label for=date>Date:</label>
<input id=date type=date name=date value="{{ g.date }}">
<select name=hours>
<option value=0{{ " selected" if g.hours==0 else "" }}>Working hours</option>
<option value=1{{ " selected" if g.hours==1 else "" }}>Whole day</option>
</select>
<input type=submit name=submit value="Submit">
</form>
<h2>Schedule for {{ g.dow }} {{ g.date }}</h2>
<div id=heading>
{% for r in g.rooms %}
<div class=roomhead style='position: absolute; left: {{ r.x }}px; top: 0px; width: {{ r.w }}px;'>
<p>{{ r.name }}</p>
</div>
{% endfor %}
</div>
<div id=schedule>
{% for r in g.rooms %}
<div class=room style='position: absolute; left: {{ r.x }}px; top: 0px; width: {{ r.w }}px; height: {{ r.h }}px;'></div>
{% endfor %}
{% for h in g.hours %}
<div class=hour style='position: absolute; left: {{ h.x }}px; top: {{ h.y }}px; width: {{ h.w }}px; height: {{ h.h }}px;'></div>
{% endfor %}
{% for m in g.meetings %}
<div class=meeting style='position: absolute; left: {{ m.x }}px; top: {{ m.y }}px; width: {{ m.w }}px; height: {{ m.h }}px;' title='{{ m.topic|e }}'>
{{ m.start }} – {{ m.end }}
</div>
{% endfor %}
</div>
</body>
</html>
import json
from flask import Flask, render_template, request, g
import psycopg2
import psycopg2.extras
import time
import sys
### Flask app object ###
app = Flask(__name__)
app.config.from_pyfile('config.py')
### Database connection ###
db_connection = None
db = None
# XXX: This is safe only because we never write to the database. Otherwise, we would
# have to handle transactions and roll them back if an exception occurs during
# processing of the request.
def db_connect():
global db_connection, db
db_connection = psycopg2.connect(
host = 'localhost',
user = app.config['DB_USER'],
password = app.config['DB_PASSWD'],
dbname = app.config['DB_NAME'],
)
db = db_connection.cursor(cursor_factory=psycopg2.extras.NamedTupleCursor)
def db_query(query, args=()):
if db is None:
db_connect()
try:
db.execute(query, args)
except psycopg2.DatabaseError:
# Reconnect if the connection died (timeout, server restart etc.)
db_connect()
db.execute(query, args)
### Schedule ###
def get_date():
try:
d = request.args.get('date', "")
return time.strptime(d, "%Y-%m-%d")
except ValueError:
return time.localtime()
rooms = [
('Z1', 'zoom-1@d3s.mff.cuni.cz'),
('Z2', 'zoom-2@d3s.mff.cuni.cz'),
('Z3', 'zoom-3@d3s.mff.cuni.cz'),
('Z4', 'zoom-4@d3s.mff.cuni.cz'),
('Z5', 'zoom-5@d3s.mff.cuni.cz'),
('Z6', 'zoom-6@d3s.mff.cuni.cz'),
('Z7', 'zoom-7@d3s.mff.cuni.cz'),
('Z8', 'zoom-8@d3s.mff.cuni.cz'),
]
@app.route('/')
def main_page():
dt = get_date()
date = time.strftime("%Y-%m-%d", dt)
t = time.mktime(dt)
g.date = date
g.dow = time.strftime("%A", dt)
hours_arg = request.args.get("hours", "")
if hours_arg in ["0", "1"]:
g.hours = int(hours_arg)
else:
g.hours = 0
if g.hours == 0:
hour_min = 8
hour_max = 24
else:
hour_min = 0
hour_max = 24
num_hours = hour_max - hour_min
num_rooms = len(rooms)
email_to_room_index = { rooms[i][1]: i for i in range(num_rooms) }
room_box_width = 100
room_hour_height = 50
g.total_width = room_box_width * num_rooms
g.total_height = num_hours * room_hour_height
g.rooms = [{
"x": i * room_box_width + 1,
"w": room_box_width - 1,
"h": g.total_height - 1,
"name": rooms[i][0],
} for i in range(num_rooms)]
g.hours = [{
"x": 1,
"y": i * room_hour_height + 1,
"w": num_rooms * room_box_width - 1,
"h": room_hour_height - 1,
} for i in range(num_hours)]
# XXX: No meeting is ever longer than 24 hours
db_query("""
SELECT m.meeting_id, m.topic, m.start_time, m.duration, u.email, u.full_name
FROM zoom_meetings m
JOIN zoom_users u ON u.id = m.host_id
WHERE start_time >= DATE %s - INTERVAL '1 day'
AND start_time < DATE %s + INTERVAL '1 day'
""",
(date, date))
g.meetings = []
for r in db.fetchall():
i = email_to_room_index.get(r.email, -1)
if i < 0:
continue
start_t = int(r.start_time.timestamp())
end_t = start_t + r.duration*60
rel_start = start_t - t - hour_min*3600
rel_end = rel_start + r.duration*60
start = max(0, int(rel_start))
end = min(num_hours * 3600, int(rel_end))
app.logger.debug("Meeting: %s start=%s end=%s room_i=%s", r, start, end, i)
if start < end:
g.meetings.append({
"x": i * room_box_width + 4,
"y": int(start / 3600. * room_hour_height),
"w": room_box_width - 7,
"h": int((end - start) / 3600 * room_hour_height),
"start": time.strftime("%H:%M", time.localtime(start_t)),
"end": time.strftime("%H:%M", time.localtime(end_t)),
"topic": r.topic,
})
return render_template('main.html')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment