added migration status to system page
This commit is contained in:
parent
dd3e91e10d
commit
0fed6b9fb3
@ -3,6 +3,7 @@
|
||||
<words>
|
||||
<w>pinia</w>
|
||||
<w>selfhosted</w>
|
||||
<w>unapplied</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
@ -1,5 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
|
@ -83,51 +83,94 @@
|
||||
{% trans 'Everything is fine!' %}
|
||||
{% endif %}
|
||||
|
||||
<h4 class="mt-3">{% trans 'Database' %}
|
||||
<span class="badge badge-{{postgres_status}}">
|
||||
<h4 class="mt-3">{% trans 'Database' %}
|
||||
<span class="badge badge-{{ postgres_status }}">
|
||||
{% if postgres_status == 'warning' %}
|
||||
{% trans 'Info' %}
|
||||
{% elif postgres_status == 'danger'%}
|
||||
{% elif postgres_status == 'danger' %}
|
||||
{% trans 'Warning' %}
|
||||
{% else %}
|
||||
{% trans 'Ok' %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</h4>
|
||||
{{postgres_message}}
|
||||
{{ postgres_message }}
|
||||
|
||||
{# <h4 class="mt-3">#}
|
||||
{# {% trans 'Orphaned Files' %}#}
|
||||
{##}
|
||||
{# <span class="badge badge-{% if orphans|length == 0 %}success{% elif orphans|length <= 25 %}warning{% else %}danger{% endif %}">#}
|
||||
{# {% if orphans|length == 0 %}{% trans 'Success' %}#}
|
||||
{# {% elif orphans|length <= 25 %}{% trans 'Warning' %}#}
|
||||
{# {% else %}{% trans 'Danger' %}#}
|
||||
{# {% endif %}#}
|
||||
{# </span>#}
|
||||
{# </h4>#}
|
||||
<h4 class="mt-3">{% trans 'Migrations' %}
|
||||
<span
|
||||
class="badge badge-{% if missing_migration %}danger{% else %}success{% endif %}">{% if missing_migration %}
|
||||
{% trans 'Warning' %}{% else %}{% trans 'Ok' %}{% endif %}</span></h4>
|
||||
|
||||
{% if orphans|length == 0 %}
|
||||
{% trans 'Everything is fine!' %}
|
||||
{% else %}
|
||||
{% blocktrans with orphan_count=orphans|length %}
|
||||
There are currently {{ orphan_count }} orphaned files.
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
Migrations should never fail!
|
||||
Failed migrations will likely cause major parts of the app to not function correctly.
|
||||
If a migration fails make sure you are on the latest version and if so please post the migration log and the overview below in a GitHub issue.
|
||||
{% endblocktrans %}
|
||||
<br>
|
||||
<button id="toggle-button" class="btn btn-info btn-sm" onclick="toggleOrphans()">{% trans 'Show' %}</button>
|
||||
<button class="btn btn-info btn-sm" onclick="deleteOrphans()">{% trans 'Delete' %}</button>
|
||||
{% endif %}
|
||||
<textarea id="orphans-list" style="display:none;" class="form-control" rows="20">
|
||||
{% for orphan in orphans %}{{ orphan }}
|
||||
{% endfor %}
|
||||
</textarea>
|
||||
</p>
|
||||
|
||||
<table class="table mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>App</th>
|
||||
<th class="text-right">{% trans 'Migrations' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for key,value in migration_info.items %}
|
||||
<tr>
|
||||
|
||||
<td>{{ value.app }}</td>
|
||||
<td class="text-right">
|
||||
<span class="badge badge-{% if value.unapplied_migrations|length > 0 %}danger{% else %}success{% endif %}">
|
||||
{{ value.applied_migrations|length }} / {{ value.total }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% for u in value.unapplied_migrations %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ u }}
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
|
||||
{# <h4 class="mt-3">#}
|
||||
{# {% trans 'Orphaned Files' %}#}
|
||||
{##}
|
||||
{# <span class="badge badge-{% if orphans|length == 0 %}success{% elif orphans|length <= 25 %}warning{% else %}danger{% endif %}">#}
|
||||
{# {% if orphans|length == 0 %}{% trans 'Success' %}#}
|
||||
{# {% elif orphans|length <= 25 %}{% trans 'Warning' %}#}
|
||||
{# {% else %}{% trans 'Danger' %}#}
|
||||
{# {% endif %}#}
|
||||
{# </span>#}
|
||||
{# </h4>#}
|
||||
|
||||
{# {% if orphans|length == 0 %}#}
|
||||
{# {% trans 'Everything is fine!' %}#}
|
||||
{# {% else %}#}
|
||||
{# {% blocktrans with orphan_count=orphans|length %}#}
|
||||
{# There are currently {{ orphan_count }} orphaned files.#}
|
||||
{# {% endblocktrans %}#}
|
||||
{# <br>#}
|
||||
{# <button id="toggle-button" class="btn btn-info btn-sm" onclick="toggleOrphans()">{% trans 'Show' %}</button>#}
|
||||
{# <button class="btn btn-info btn-sm" onclick="deleteOrphans()">{% trans 'Delete' %}</button>#}
|
||||
{# {% endif %}#}
|
||||
{# <textarea id="orphans-list" style="display:none;" class="form-control" rows="20">#}
|
||||
{#{% for orphan in orphans %}{{ orphan }}#}
|
||||
{#{% endfor %}#}
|
||||
{# </textarea>#}
|
||||
|
||||
<h4 class="mt-3">Debug</h4>
|
||||
<textarea class="form-control" rows="20">
|
||||
Gunicorn Media: {{ gunicorn_media }}
|
||||
Sqlite: {% if postgres %} {% trans 'False' %} {% else %} {% trans 'True' %} {% endif %}
|
||||
{% if postgres %}PostgreSQL: {{postgres_version}} {% endif %}
|
||||
Debug: {{ debug }}
|
||||
{% if postgres %}PostgreSQL: {{ postgres_version }} {% endif %}
|
||||
Debug: {{ debug }}
|
||||
|
||||
{% for key,value in request.META.items %}{% if key in 'SERVER_PORT,REMOTE_HOST,REMOTE_ADDR,SERVER_PROTOCOL' %}{{ key }}:{{ value }}
|
||||
{% endif %}{% endfor %}
|
||||
@ -142,26 +185,27 @@ Debug: {{ debug }}
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="delete_orphans" value="false">
|
||||
</form>
|
||||
{% block script %}
|
||||
<script>
|
||||
function toggleOrphans() {
|
||||
var orphansList = document.getElementById('orphans-list');
|
||||
var button = document.getElementById('toggle-button');
|
||||
{% block script %}
|
||||
<script>
|
||||
function toggleOrphans() {
|
||||
var orphansList = document.getElementById('orphans-list');
|
||||
var button = document.getElementById('toggle-button');
|
||||
|
||||
if (orphansList.style.display === 'none') {
|
||||
orphansList.style.display = 'block';
|
||||
button.innerText = "{% trans 'Hide' %}";
|
||||
} else {
|
||||
orphansList.style.display = 'none';
|
||||
button.innerText = "{% trans 'Show' %}";
|
||||
}
|
||||
}
|
||||
function deleteOrphans() {
|
||||
document.getElementById('delete-form').delete_orphans.value = 'true';
|
||||
document.getElementById('delete-form').submit();
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
if (orphansList.style.display === 'none') {
|
||||
orphansList.style.display = 'block';
|
||||
button.innerText = "{% trans 'Hide' %}";
|
||||
} else {
|
||||
orphansList.style.display = 'none';
|
||||
button.innerText = "{% trans 'Show' %}";
|
||||
}
|
||||
}
|
||||
|
||||
function deleteOrphans() {
|
||||
document.getElementById('delete-form').delete_orphans.value = 'true';
|
||||
document.getElementById('delete-form').submit();
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
from io import StringIO
|
||||
from uuid import UUID
|
||||
import subprocess
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
@ -10,6 +12,7 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.password_validation import validate_password
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.management import call_command
|
||||
from django.db import models
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
@ -27,7 +30,7 @@ from cookbook.models import (Comment, CookLog, InviteLink, SearchFields, SearchP
|
||||
ShareLink, Space, UserSpace, ViewLog)
|
||||
from cookbook.tables import CookLogTable, ViewLogTable
|
||||
from cookbook.version_info import VERSION_INFO
|
||||
from recipes.settings import PLUGINS
|
||||
from recipes.settings import PLUGINS, BASE_DIR
|
||||
|
||||
|
||||
def index(request):
|
||||
@ -228,10 +231,10 @@ def shopping_settings(request):
|
||||
if not sp:
|
||||
sp = SearchPreferenceForm(user=request.user)
|
||||
fields_searched = (
|
||||
len(search_form.cleaned_data['icontains'])
|
||||
+ len(search_form.cleaned_data['istartswith'])
|
||||
+ len(search_form.cleaned_data['trigram'])
|
||||
+ len(search_form.cleaned_data['fulltext'])
|
||||
len(search_form.cleaned_data['icontains'])
|
||||
+ len(search_form.cleaned_data['istartswith'])
|
||||
+ len(search_form.cleaned_data['trigram'])
|
||||
+ len(search_form.cleaned_data['fulltext'])
|
||||
)
|
||||
if search_form.cleaned_data['preset'] == 'fuzzy':
|
||||
sp.search = SearchPreference.SIMPLE
|
||||
@ -348,6 +351,26 @@ def system(request):
|
||||
else:
|
||||
orphans = get_orphan_files()
|
||||
|
||||
out = StringIO()
|
||||
call_command('showmigrations', stdout=out)
|
||||
missing_migration = False
|
||||
migration_info = {}
|
||||
current_app = None
|
||||
for row in out.getvalue().splitlines():
|
||||
if '[ ]' in row and current_app:
|
||||
migration_info[current_app]['unapplied_migrations'].append(row.replace('[ ]', ''))
|
||||
missing_migration = True
|
||||
elif '[X]' in row and current_app:
|
||||
migration_info[current_app]['applied_migrations'].append(row.replace('[x]', ''))
|
||||
elif '(no migrations)' in row and current_app:
|
||||
pass
|
||||
else:
|
||||
current_app = row
|
||||
migration_info[current_app] = {'app': current_app, 'unapplied_migrations': [], 'applied_migrations': [], 'total': 0}
|
||||
|
||||
for key in migration_info.keys():
|
||||
migration_info[key]['total'] = len(migration_info[key]['unapplied_migrations']) + len(migration_info[key]['applied_migrations'])
|
||||
|
||||
return render(request, 'system.html', {
|
||||
'gunicorn_media': settings.GUNICORN_MEDIA,
|
||||
'debug': settings.DEBUG,
|
||||
@ -358,7 +381,9 @@ def system(request):
|
||||
'version_info': VERSION_INFO,
|
||||
'plugins': PLUGINS,
|
||||
'secret_key': secret_key,
|
||||
'orphans': orphans
|
||||
'orphans': orphans,
|
||||
'migration_info': migration_info,
|
||||
'missing_migration': missing_migration,
|
||||
})
|
||||
|
||||
|
||||
@ -514,6 +539,7 @@ def get_orphan_files(delete_orphans=False):
|
||||
|
||||
# Check each image file against model image fields
|
||||
return [img for img in image_files if img[0] not in image_paths]
|
||||
|
||||
orphans = find_orphans()
|
||||
if delete_orphans:
|
||||
for f in [img[1] for img in orphans]:
|
||||
|
@ -9,7 +9,7 @@ django-tables2==2.5.3
|
||||
djangorestframework==3.14.0
|
||||
drf-writable-nested==0.7.0
|
||||
django-oauth-toolkit==2.3.0
|
||||
django-debug-toolbar==3.8.1
|
||||
django-debug-toolbar==4.2.0
|
||||
bleach==6.0.0
|
||||
gunicorn==20.1.0
|
||||
lxml==4.9.3
|
||||
|
Loading…
Reference in New Issue
Block a user