1. 개요
- 시간을 블록화 해서 엄격히 관리해 주는 앱을 만들고 싶었음
- flask를 활용해서 진행함
2. 코드
- python script + html
1) app.py
from flask import Flask, render_template, request, redirect, url_for
import datetime
from jinja2 import Environment
app = Flask(__name__)
# Define the attention grade categories
attention_grades = ['LOW', 'MEDIUM', 'HIGH']
# Define the default time blocks (1 hour or 30 minutes)
time_blocks_1h = [f"{str(hour).zfill(2)}:00-{str(hour+1).zfill(2)}:00" for hour in range(24)]
time_blocks_30m = [f"{str(hour).zfill(2)}:{minute:02d}-{str(hour if minute == 0 else hour + 1).zfill(2)}:{minute + 30 if minute == 0 else 0:02d}" for hour in range(24) for minute in (0, 30)]
# Define the schedule data (for simplicity, it's initialized in-memory)
schedule_data = {
'Monday': [''] * len(time_blocks_1h),
'Tuesday': [''] * len(time_blocks_1h),
'Wednesday': [''] * len(time_blocks_1h),
'Thursday': [''] * len(time_blocks_1h),
'Friday': [''] * len(time_blocks_1h),
'Saturday': [''] * len(time_blocks_1h),
'Sunday': [''] * len(time_blocks_1h),
}
# Define tasks for each attention grade
tasks = {
'LOW': [],
'MEDIUM': [],
'HIGH': []
}
@app.route('/')
def index():
# Determine the current day to highlight
current_day = datetime.datetime.now().strftime("%A")
return render_template('index.html',
time_blocks=time_blocks_1h,
schedule_data=schedule_data,
attention_grades=attention_grades,
tasks=tasks,
current_day=current_day,
show_weekend=False,
enumerate=enumerate)
@app.route('/add_task', methods=['GET', 'POST'])
def add_task():
if request.method == 'POST':
grade = request.form.get('attention_grade')
task = request.form.get('task')
if grade in tasks:
tasks[grade].append(task)
return redirect(url_for('index'))
return render_template('add_task.html', attention_grades=attention_grades)
@app.route('/update_schedule', methods=['POST'])
def update_schedule():
# Update the schedule based on the form data
day = request.form.get('day')
time_slot = int(request.form.get('time_slot'))
task = request.form.get('task')
schedule_data[day][time_slot] = task
return redirect(url_for('index'))
@app.route('/toggle_time_blocks')
def toggle_time_blocks():
# Toggle between 1-hour and 30-minute time blocks
use_30_min_blocks = request.args.get('use_30_min_blocks', 'false') == 'true'
time_blocks = time_blocks_30m if use_30_min_blocks else time_blocks_1h
current_day = datetime.datetime.now().strftime("%A")
return render_template('index.html',
time_blocks=time_blocks,
schedule_data=schedule_data,
attention_grades=attention_grades,
tasks=tasks,
current_day=current_day,
show_weekend=False,
enumerate=enumerate)
@app.route('/toggle_weekend', methods=['GET'])
def toggle_weekend():
# Toggle weekend visibility
show_weekend = request.args.get('show_weekend', 'false') == 'true'
current_day = datetime.datetime.now().strftime("%A")
return render_template('index.html',
time_blocks=time_blocks_1h,
schedule_data=schedule_data,
attention_grades=attention_grades,
tasks=tasks,
current_day=current_day,
show_weekend=show_weekend,
enumerate=enumerate)
if __name__ == '__main__':
app.run(debug=True, port=5001)
2) index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BC-lock Schedule Dashboard</title>
<style>
.low { background-color: lightcoral; }
.medium { background-color: lightgoldenrodyellow; }
.high { background-color: lightgreen; }
.highlight { font-weight: bold; border: 2px solid black; }
table { width: 100%; border-collapse: collapse; font-size: 0.9em; }
th, td { border: 1px solid #ddd; padding: 4px; text-align: center; }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script>
function filterTasksByGrade(grade) {
let taskOptions = document.querySelectorAll('.task-option');
taskOptions.forEach(option => {
if (grade === '' || option.dataset.grade === grade) {
option.style.display = 'block';
} else {
option.style.display = 'none';
}
});
}
function takeScreenshot() {
html2canvas(document.body, { scale: 2 }).then(canvas => {
let link = document.createElement('a');
link.download = 'schedule_dashboard.png';
link.href = canvas.toDataURL('image/png');
link.click();
});
}
</script>
</head>
<body>
<h1>BC-lock Schedule Dashboard</h1>
<a href="/add_task"><button>Add Task</button></a>
<button onclick="takeScreenshot()">Take Screenshot</button>
<table>
<thead>
<tr>
<th>Time</th>
<th>Attention Grade</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
</tr>
</thead>
<tbody>
{% for idx, time_block in enumerate(time_blocks) %}
<tr>
<td>{{ time_block }}</td>
<td>
<select name="attention_grade" onchange="filterTasksByGrade(this.value)">
<option value="">--Select Grade--</option>
{% for grade in attention_grades %}
<option value="{{ grade }}">{{ grade }}</option>
{% endfor %}
</select>
</td>
{% for day in schedule_data.keys() if day not in ['Saturday', 'Sunday'] %}
<td class="{% if schedule_data[day][idx] == 'LOW' %}low{% elif schedule_data[day][idx] == 'MEDIUM' %}medium{% elif schedule_data[day][idx] == 'HIGH' %}high{% endif %} {% if day == current_day %}highlight{% endif %}">
<select name="task">
<option value="">--Select Task--</option>
{% for grade, task_list in tasks.items() %}
{% for task in task_list %}
<option class="task-option" data-grade="{{ grade }}" value="{{ task }}">{{ task }} ({{ grade }})</option>
{% endfor %}
{% endfor %}
</select>
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
3) add_task.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Task</title>
<script>
function addTask(event) {
event.preventDefault();
const grade = document.getElementById('attention_grade').value;
const task = document.getElementById('task').value;
if (grade && task) {
const taskList = document.getElementById('task_list');
const listItem = document.createElement('li');
listItem.textContent = `${task} (${grade})`;
taskList.appendChild(listItem);
document.getElementById('task').value = '';
}
}
</script>
</head>
<body>
<h1>Add Task</h1>
<form onsubmit="addTask(event)">
<label for="attention_grade">Attention Grade:</label>
<select name="attention_grade" id="attention_grade">
{% for grade in attention_grades %}
<option value="{{ grade }}">{{ grade }}</option>
{% endfor %}
</select>
<br>
<label for="task">Task:</label>
<input type="text" name="task" id="task" required>
<br>
<button type="submit">Add Task</button>
</form>
<h2>Current Tasks</h2>
<ul id="task_list">
{% if tasks %}
{% for grade, task_list in tasks.items() %}
{% for task in task_list %}
<li>{{ task }} ({{ grade }})</li>
{% endfor %}
{% endfor %}
{% else %}
<li>No tasks available</li>
{% endif %}
</ul>
<a href="/">Back to Dashboard</a>
</body>
</html>
3. 결과
- main dashboard
- add task page
- take screenshot > save image file
https://github.com/eunchanj/bc_lock