178 lines
8.4 KiB
HTML
178 lines
8.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Todoist Backup - {{ date }}</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; background: #f8f9fa; color: #222; margin: 0; padding: 0; }
|
|
.container { max-width: 900px; margin: 2em auto; background: #fff; padding: 2em; border-radius: 8px; box-shadow: 0 2px 8px #0001; }
|
|
h1, h2, h3 { color: #2d72d9; }
|
|
.project { margin-bottom: 2em; }
|
|
.task-list { margin: 0 0 1em 1em; }
|
|
.task { border-bottom: 1px solid #eee; padding: 0.5em 0; }
|
|
.completed { color: #888; }
|
|
.attachments { margin: 0.5em 0 0.5em 1em; }
|
|
.comments { margin: 0.5em 0 0.5em 1em; font-size: 0.95em; color: #444; }
|
|
.task-name { font-weight: bold; }
|
|
.field-label { font-style: italic; }
|
|
a.attachment-link { color: #2d72d9; text-decoration: underline; }
|
|
.meta { color: #666; font-size: 0.95em; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>Todoist Backup ({{ date }})</h1>
|
|
<!-- Table of Contents -->
|
|
<nav style="margin-bottom:2em;">
|
|
<h2 style="font-size:1.2em;">Projects</h2>
|
|
<ul>
|
|
{% for project in projects %}
|
|
<li><a href="#project-{{ project.id }}">{{ project.name }}{% if project.is_archived %} <span class="meta">[Archived]</span>{% endif %}</a></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</nav>
|
|
{% for project in projects %}
|
|
<div class="project" id="project-{{ project.id }}">
|
|
<h2>{{ project.name }} {% if project.is_archived %}<span class="meta">[Archived]</span>{% endif %}</h2>
|
|
<div class="meta">
|
|
<span>ID: {{ project.id }}</span> | <span>Color: {{ project.color }}</span> | <span>Created: {{ project.created_at }}</span>
|
|
</div>
|
|
<h3>Active Tasks</h3>
|
|
<div class="task-list">
|
|
{% for task in project.tasks %}
|
|
<div class="task">
|
|
<div class="task-name">{{ task.content | markdown | safe }}</div>
|
|
{% if task.description %}
|
|
<div class="task-desc">{{ task.description | markdown | safe }}</div>
|
|
{% endif %}
|
|
<div class="meta">
|
|
{% set meta_fields = [] %}
|
|
{% if task.id is not none %}
|
|
{% set _ = meta_fields.append('ID: ' ~ task.id) %}
|
|
{% endif %}
|
|
{% if task.due and task.due.date %}
|
|
{% set due_dt = task.due.date %}
|
|
{% if due_dt.__class__.__name__ == 'datetime' or due_dt.__class__.__name__ == 'date' %}
|
|
{% set due_fmt = due_dt.strftime('%Y-%m-%d') %}
|
|
{% else %}
|
|
{% set due_str = due_dt|string %}
|
|
{% if 'T' in due_str %}
|
|
{% set due_fmt = due_str[:10] %}
|
|
{% else %}
|
|
{% set due_fmt = due_str %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% set _ = meta_fields.append('Due: ' ~ due_fmt) %}
|
|
{% endif %}
|
|
{% if task.due and task.due.is_recurring %}
|
|
{% if task.due.string %}
|
|
{% set _ = meta_fields.append('Recurring: ' ~ task.due.string) %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if task.priority is not none %}
|
|
{% set _ = meta_fields.append('Priority: ' ~ task.priority) %}
|
|
{% endif %}
|
|
{{ meta_fields|join(' | ') }}
|
|
</div>
|
|
{% if task.attachments %}
|
|
<div class="attachments">
|
|
<span class="field-name">Attachments:</span>
|
|
<ul>
|
|
{% for att in task.attachments %}
|
|
<li><a class="attachment-link" href="{{ att.local_file }}" download>{{ att.file_name or att.local_file }}</a></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
{% if task.comments %}
|
|
<div class="comments">
|
|
<span class="field-name">Comments:</span>
|
|
<ul>
|
|
{% for comment in task.comments %}
|
|
<li>{{ comment.content }} <span class="meta">({{ comment.posted_at }})</span></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<h3>Completed Tasks</h3>
|
|
<div class="task-list">
|
|
{% for task in project.completed_tasks %}
|
|
<div class="task completed">
|
|
<div class="task-name">{{ task.content | markdown | safe }}</div>
|
|
{% if task.description %}
|
|
<div class="task-desc">{{ task.description | markdown | safe }}</div>
|
|
{% endif %}
|
|
<div class="meta">
|
|
{% set meta_fields = [] %}
|
|
{% if task.id is not none %}
|
|
{% set _ = meta_fields.append('ID: ' ~ task.id) %}
|
|
{% endif %}
|
|
{% if task.due and task.due.date %}
|
|
{% set due_dt = task.due.date %}
|
|
{% if due_dt.__class__.__name__ == 'datetime' or due_dt.__class__.__name__ == 'date' %}
|
|
{% set due_fmt = due_dt.strftime('%Y-%m-%d %H:%M') if due_dt.__class__.__name__ == 'datetime' else due_dt.strftime('%Y-%m-%d 00:00') %}
|
|
{% else %}
|
|
{% set due_str = due_dt|string %}
|
|
{% if 'T' in due_str %}
|
|
{% set due_fmt = due_str[:16].replace('T', ' ') %}
|
|
{% else %}
|
|
{% set due_fmt = due_str %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% set _ = meta_fields.append('Due: ' ~ due_fmt) %}
|
|
{% endif %}
|
|
{% if task.due and task.due.is_recurring %}
|
|
{% if task.due.string %}
|
|
{% set _ = meta_fields.append('Recurring: ' ~ task.due.string) %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if task.priority is not none %}
|
|
{% set _ = meta_fields.append('Priority: ' ~ task.priority) %}
|
|
{% endif %}
|
|
{% if task.completed_at %}
|
|
{% if task.completed_at.__class__.__name__ == 'datetime' or task.completed_at.__class__.__name__ == 'date' %}
|
|
{% set completed_fmt = task.completed_at.strftime('%Y-%m-%d') %}
|
|
{% else %}
|
|
{% set completed_str = task.completed_at|string %}
|
|
{% if 'T' in completed_str %}
|
|
{% set completed_fmt = completed_str[:10] %}
|
|
{% else %}
|
|
{% set completed_fmt = completed_str %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% set _ = meta_fields.append('Completed: ' ~ completed_fmt) %}
|
|
{% endif %}
|
|
{{ meta_fields|join(' | ') }}
|
|
</div>
|
|
{% if task.attachments %}
|
|
<div class="attachments">
|
|
<span class="field-name">Attachments:</span>
|
|
<ul>
|
|
{% for att in task.attachments %}
|
|
<li><a class="attachment-link" href="{{ att.local_file }}" download>{{ att.file_name or att.local_file }}</a></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
{% if task.comments %}
|
|
<div class="comments">
|
|
<span class="field">Comments:</span>
|
|
<ul>
|
|
{% for comment in task.comments %}
|
|
<li>{{ comment.content }} <span class="meta">({{ comment.posted_at }})</span></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</body>
|
|
</html>
|