Added WIP Backup System

This commit is contained in:
st01765
2026-02-04 13:32:37 +11:00
parent 74d6f48136
commit 3d23a13f99
7 changed files with 499 additions and 10 deletions
@@ -0,0 +1,84 @@
{% extends 'admin/base.html' %}
{% block extrahead %}
{{ block.super }}
<style>
/* Collapsible diff styles */
.diff-list, .diff-list ul { list-style: none; margin-left: 1em; padding-left: 0; }
.nested { display: none; }
.toggle { cursor: pointer; user-select: none; font-weight: bold; }
.new { color: green; }
.removed { color: red; }
.updated { color: orange; }
</style>
{% endblock %}
{% block content %}
<h1>Backup & Restore</h1>
<!-- Export backup -->
<section>
<h2>Download Backup</h2>
<form method="get" action="{% url 'settings:export_backup' %}">
<button type="submit">Download New Backup</button>
</form>
</section>
<hr>
<!-- Upload backup -->
<section>
<h2>Upload Backup</h2>
<form id="upload-form" method="post" enctype="multipart/form-data" action="">
{% csrf_token %}
<input type="file" name="backup_file" required>
<button type="submit">Upload & Compare Backup</button>
</form>
</section>
<hr>
<!-- Compare summary & diffs -->
{% if compare_summary %}
<section>
<h2>Comparison Summary</h2>
<ul>
{% for model, counts in compare_summary.items %}
<li>{{ model }}: Added {{ counts.add }}, Removed {{ counts.remove }}, Modified {{ counts.modify }}</li>
{% endfor %}
</ul>
<h2>Details</h2>
{% include "diff_list.html" with items=diffs.suburbs title="Suburbs" %}
{% include "diff_list.html" with items=diffs.schools title="Schools" %}
{% include "diff_list.html" with items=diffs.travellers title="Travellers" %}
{% include "diff_list.html" with items=diffs.companies title="Companies" %}
<!-- Execute Recovery -->
<form method="post" action="">
{% csrf_token %}
<!-- Pass the uploaded file content for restore -->
<input type="hidden" name="backup_content" value="{{ uploaded_file_content|escape }}">
<button type="submit" name="execute_restore"
onclick="return confirm('Are you sure you want to restore this backup? This cannot be undone.')">
Execute Recovery
</button>
</form>
</section>
{% endif %}
{% endblock %}
{% block extrajs %}
<script>
document.addEventListener("DOMContentLoaded", () => {
// Collapsible diffs
document.querySelectorAll('.toggle').forEach(el => {
el.addEventListener('click', () => {
const nested = el.nextElementSibling;
if (nested) nested.style.display = (nested.style.display === "none" || nested.style.display === "") ? "block" : "none";
});
});
});
</script>
{% endblock %}
@@ -0,0 +1,20 @@
{% extends "admin/base_site.html" %}
{% block content %}
<h1>Backup Comparison</h1>
<h2>Summary</h2>
<ul>
{% for model, counts in summary.items %}
<li>{{ model }}: Added {{ counts.add }}, Removed {{ counts.remove }}, Modified {{ counts.modify }}</li>
{% endfor %}
</ul>
<!-- Optional: show details -->
<pre>{{ details|safe }}</pre>
<form method="post" action="{% url 'restore_backup' %}">
{% csrf_token %}
<button type="submit">Execute Recovery</button>
</form>
{% endblock %}
@@ -0,0 +1,26 @@
<h3>{{ title }}</h3>
<ul class="diff-list">
{% for item in items %}
<li>
<span class="toggle">{{ item.name }} ({{ item.type }})</span>
{% if item.modifications %}
<ul class="nested">
{% for mod in item.modifications %}
<li class="{{ mod.type|lower }}">
{{ mod.type }}: {{ mod.key }} → {{ mod.old_value }} → {{ mod.new_value }}
</li>
{% endfor %}
</ul>
{% endif %}
{% if item.inline_modifications %}
{% for inline in item.inline_modifications %}
<ul class="nested">
{% include "diff_list.html" with items=inline.modifications title=inline.name %}
</ul>
{% endfor %}
{% endif %}
</li>
{% endfor %}
</ul>
@@ -3,7 +3,7 @@
{% block content %}
<div><a href={% url 'settings:nightly_task' %}>Run nightly task</a></div>
<div><a href={% url 'settings:sms_test' %}>Send SMS test message</a></div>
<div><a href={% url 'settings:export' %}>Export</a></div>
<div><a href={% url 'settings:export_backup' %}>Export</a></div>
<div>
<div class="flex-container">
<label for="id_traveller_term_cost">