Compare commits

..

No commits in common. "main" and "repo-request-variables" have entirely different histories.

24 changed files with 181 additions and 326 deletions

1
.gitignore vendored
View File

@ -35,7 +35,6 @@ borgweb/borgweb/secrets.py
# db # db
*.sqlite *.sqlite
*.db
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/

View File

@ -1,4 +1,4 @@
from .repoform import RepoForm, ToggleVisibility from .repoform import RepoForm
from .archiveform import ArchiveForm from .archiveform import ArchiveForm
from .errorform import ErrorForm from .errorform import ErrorForm
from .locationform import LocationForm from .locationform import LocationForm

View File

@ -6,7 +6,3 @@ class RepoForm(forms.Form):
fingerprint = forms.CharField(label='Fingerprint') fingerprint = forms.CharField(label='Fingerprint')
location = forms.CharField(label='Location') location = forms.CharField(label='Location')
last_modified = forms.DateTimeField(label='Last Modified', input_formats=["%Y-%m-%dT%H:%M:%S.%z"]) last_modified = forms.DateTimeField(label='Last Modified', input_formats=["%Y-%m-%dT%H:%M:%S.%z"])
class ToggleVisibility(forms.Form):
label = forms.CharField(label='Label')

View File

@ -1,18 +0,0 @@
# Generated by Django 4.0.6 on 2022-07-26 15:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('borg', '0002_location'),
]
operations = [
migrations.AddField(
model_name='label',
name='visible',
field=models.BooleanField(default=True),
),
]

View File

@ -1,63 +0,0 @@
# Generated by Django 4.0.6 on 2022-10-05 18:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('borg', '0003_label_visible'),
]
operations = [
migrations.AlterField(
model_name='archive',
name='compressed_size',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='archive',
name='deduplicated_size',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='archive',
name='file_count',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='archive',
name='original_size',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='cache',
name='total_chunks',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='cache',
name='total_csize',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='cache',
name='total_size',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='cache',
name='total_unique_chunks',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='cache',
name='unique_csize',
field=models.BigIntegerField(),
),
migrations.AlterField(
model_name='cache',
name='unique_size',
field=models.BigIntegerField(),
),
]

View File

@ -8,9 +8,9 @@ class Archive(models.Model):
name = models.TextField() name = models.TextField()
start = models.DateTimeField() start = models.DateTimeField()
end = models.DateTimeField() end = models.DateTimeField()
file_count = models.BigIntegerField() file_count = models.IntegerField()
original_size = models.BigIntegerField() original_size = models.IntegerField()
compressed_size = models.BigIntegerField() compressed_size = models.IntegerField()
deduplicated_size = models.BigIntegerField() deduplicated_size = models.IntegerField()
cache = models.OneToOneField(Cache, on_delete=models.CASCADE) cache = models.OneToOneField(Cache, on_delete=models.CASCADE)

View File

@ -2,9 +2,9 @@ from django.db import models
class Cache(models.Model): class Cache(models.Model):
total_chunks = models.BigIntegerField() total_chunks = models.IntegerField()
total_csize = models.BigIntegerField() total_csize = models.IntegerField()
total_size = models.BigIntegerField() total_size = models.IntegerField()
total_unique_chunks = models.BigIntegerField() total_unique_chunks = models.IntegerField()
unique_csize = models.BigIntegerField() unique_csize = models.IntegerField()
unique_size = models.BigIntegerField() unique_size = models.IntegerField()

View File

@ -3,7 +3,6 @@ from django.db import models
class Label(models.Model): class Label(models.Model):
label = models.TextField(blank=True, unique=True) label = models.TextField(blank=True, unique=True)
visible = models.BooleanField(default=True)
def __str__(self): def __str__(self):
return self.label return self.label

View File

@ -11,10 +11,10 @@ class Repo(models.Model):
last_modified = models.DateTimeField() last_modified = models.DateTimeField()
label = models.OneToOneField(Label, on_delete=models.CASCADE, unique=True) label = models.OneToOneField(Label, on_delete=models.CASCADE, unique=True)
def warning(self, hours_ago=4): def warning(self, hours_ago=2):
return not self.latest_archive().start > datetime.utcnow() - timedelta(hours=hours_ago) return not self.latest_archive().start > datetime.utcnow() - timedelta(hours=hours_ago)
def error(self, hours_ago=12): def error(self, hours_ago=4):
latest_archive = self.latest_archive() latest_archive = self.latest_archive()
if latest_archive is None or not self.archive_after_latest_error(): if latest_archive is None or not self.archive_after_latest_error():
return True return True
@ -102,23 +102,23 @@ class Repo(models.Model):
@staticmethod @staticmethod
def series_csize(archives, units=None): def series_csize(archives, units=None):
return [convert_bytes(archive.cache.unique_csize, units)[0] return [convert_bytes(archive.cache.unique_csize, units)[0]
if archive is not None else 0 for archive in archives] if archive is not None else None for archive in archives]
def hourly_archive_string(self): def hourly_archive_string(self):
return ''.join(['H' if archive is not None else '-' for archive in self.hourly_archives(8)]) return ''.join(['H' if archive is not None else '-' for archive in self.hourly_archives(8)])
def monthly_archives(self, n_months: int = 12): def monthly_archives(self, n_months: int = 12):
archives = [] archives = []
archive_set = self.archive_set.all().order_by('-start') for month in range(n_months):
current_date = subtract_months(datetime.utcnow(), month)
current_date = datetime.utcnow() archive_current_month = self.archive_set.all() \
for archive in archive_set: .filter(start__year=current_date.year,
if len(archives) >= n_months: start__month=current_date.month) \
break .order_by('-start')
if archive.start.year == current_date.year and archive.start.month == current_date.month: if len(archive_current_month) > 0:
archives.append(archive) archives.append(archive_current_month[0])
current_date = subtract_months(current_date, 1) else:
archives.append(None)
return archives[::-1] return archives[::-1]
def archives_on_dates(self, dates: list): def archives_on_dates(self, dates: list):

View File

@ -1,19 +1,19 @@
function draw_time_series_graph(canvas, data) { function draw_time_series_graph(chartID, repo, dateLabels, sizeUnits) {
let datasets = [{ let datasets = [{
label: data.label, label: repo.label,
data: data.size, data: repo.size,
fill: false, fill: false,
borderColor: 'rgb(7, 59, 76)' borderColor: 'rgb(7, 59, 76)'
}] }]
const graphData = { const data = {
labels: data.dates, labels: dateLabels,
datasets: datasets datasets: datasets
}; };
const config = { const config = {
type: 'line', type: 'line',
data: graphData, data,
options: { options: {
plugins: { plugins: {
tooltip: { tooltip: {
@ -21,16 +21,13 @@ function draw_time_series_graph(canvas, data) {
label: function (context) { label: function (context) {
const yValue = context.parsed.y const yValue = context.parsed.y
if (yValue !== null) { if (yValue !== null) {
return `${yValue} ${data.units}` return `${yValue} ${sizeUnits}`
} else { } else {
return "" return ""
} }
} }
} }
}, }
legend: {
display: false
},
}, },
scales: { scales: {
y: { y: {
@ -44,7 +41,7 @@ function draw_time_series_graph(canvas, data) {
}, },
ticks: { ticks: {
callback: function (value, index, values) { callback: function (value, index, values) {
return `${value} ${data.units}` return `${value} ${sizeUnits}`
} }
} }
} }
@ -52,8 +49,69 @@ function draw_time_series_graph(canvas, data) {
} }
} }
const newGraph = new Chart( var newChart = new Chart(
canvas, document.getElementById(chartID),
config
);
}
function draw_time_graph(chartID, repos, dateLabels, sizeUnits) {
let datasets = []
repos.forEach(function (repo) {
datasets.push({
label: repo.label,
data: repo.size,
fill: false,
borderColor: 'rgb(7, 59, 76)'
});
})
const data = {
labels: dateLabels,
datasets: datasets
};
const config = {
type: 'line',
data,
options: {
plugins: {
tooltip: {
callbacks: {
label: function (context) {
const yValue = context.parsed.y
if (yValue !== null) {
return `${yValue} ${sizeUnits}`
} else {
return ""
}
}
}
}
},
scales: {
y: {
min: 0,
title: {
display: true,
text: "Compressed Size",
font: {
size: 18
}
},
ticks: {
callback: function (value, index, values) {
return `${value} ${sizeUnits}`
}
}
}
}
}
}
var newChart = new Chart(
document.getElementById(chartID),
config config
); );
} }

View File

@ -12,37 +12,29 @@ function colourRepo(repo_json, label, container_id) {
$(container_id).find(repoLabel).addClass(bg_class); $(container_id).find(repoLabel).addClass(bg_class);
} }
function stringRequests() {
window.addEventListener("DOMContentLoaded", function () {
// todo: inflate each repo and colour background accordingly
const container = $('#repo-container');
$('[data-json-string-request]').each(function (index, element) { $('[data-json-string-request]').each(function (index, element) {
$.getJSON($(this).attr("data-json-string-request"), function (data) { $.getJSON($(this).attr("data-json-string-request"), function (data) {
$(element).html(data['data']); $(element).html(data['data']);
})
}); });
});
}
function graphRequests() { $.getJSON(`/repo-list.json`, function (repo_list) {
$('[data-json-graph-request]').each(function (index, element) {
$.getJSON($(this).attr("data-json-graph-request"), function (data) {
let newGraph = $('<canvas/>').width(400).height(200);
draw_time_series_graph(newGraph, data)
$(element).html(newGraph);
});
});
}
function colourRepos(repo_list) {
const container = $('#repo-container');
repo_list.labels.forEach(function (repo_label) { repo_list.labels.forEach(function (repo_label) {
$.getJSON(`/repo/${repo_label}.json`, function (repo_json) { $.getJSON(`/repo/${repo_label}.json`, function (repo_json) {
colourRepo(repo_json, repo_label, container); colourRepo(repo_json, repo_label, container);
}); })
});
} $.getJSON(`/repo/${repo_label}/monthly-size.json`, function (repo_size_json) {
draw_time_series_graph(`repo-${repo_label}-size-graph`, repo_size_json.repo,
repo_size_json.dates, repo_size_json.units);
})
window.addEventListener("DOMContentLoaded", function () {
setTimeout(stringRequests, 0);
setTimeout(graphRequests, 0);
$.getJSON(`/repo-list.json`, function (repo_list) {
setTimeout(colourRepos.bind(null, repo_list), 0);
}); });
})
}, false); }, false);

View File

@ -1,35 +0,0 @@
{% extends "borg/base.html" %}
{% load cache %}
{% load static %}
{% block title %}{{ repo.label }} errors{% endblock %}
{% block script %}
{% endblock %}
{% block style %}
{{ block.super }}
.error-container {
padding: 8px;
margin: 8px;
}
{% endblock %}
{% block body %}
{% if errors %}
<div class="error-container" class="grid justify-content-left">
<ul class="att-label row ps-3 col-11">
{% for error in errors %}
<li class="shadow rounded overflow-hidden bg-primary m-1">
<span>{{ error.error }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<div style="width: 600px;" class="error-container shadow rounded bg-primary overflow-hidden">
<div style="width: 600px;" class="error-container bg-primary overflow-hidden">
<h2 class="h2">No errors found</h2>
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -6,6 +6,7 @@
{% block script %} {% block script %}
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.4.1/dist/chart.min.js" <script src="https://cdn.jsdelivr.net/npm/chart.js@3.4.1/dist/chart.min.js"
integrity="sha256-GMN9UIJeUeOsn/Uq4xDheGItEeSpI5Hcfp/63GclDZk=" crossorigin="anonymous"></script> integrity="sha256-GMN9UIJeUeOsn/Uq4xDheGItEeSpI5Hcfp/63GclDZk=" crossorigin="anonymous"></script>
{% include "borg/repo-template.html" %}
<script src="{% static 'borg/js/chart.js' %}"></script> <script src="{% static 'borg/js/chart.js' %}"></script>
<script src="{% static 'borg/js/index.js' %}"></script> <script src="{% static 'borg/js/index.js' %}"></script>
{% endblock %} {% endblock %}
@ -37,7 +38,7 @@
<dt class="col-4">Latest backup:</dt> <dt class="col-4">Latest backup:</dt>
<dd class="repo-latest-backup col-8" <dd class="repo-latest-backup col-8"
data-json-string-request="/repo/{{ repo.label }}/latest-backup.json"> data-json-string-request="/repo/{{ repo.label }}/latest-backup.json">
<div class="spinner-border spinner-border-sm" role="status"> <div class="spinner-border" role="status">
</div> </div>
</dd> </dd>
</dl> </dl>
@ -45,7 +46,7 @@
<dt class="col-4">Size:</dt> <dt class="col-4">Size:</dt>
<dd class="repo-size col-8" <dd class="repo-size col-8"
data-json-string-request="/repo/{{ repo.label }}/size.json"> data-json-string-request="/repo/{{ repo.label }}/size.json">
<div class="spinner-border spinner-border-sm" role="status"> <div class="spinner-border" role="status">
</div> </div>
</dd> </dd>
</dl> </dl>
@ -53,16 +54,12 @@
<dt class="col-4">Recent errors:</dt> <dt class="col-4">Recent errors:</dt>
<dd class="repo-recent-errors col-8" <dd class="repo-recent-errors col-8"
data-json-string-request="/repo/{{ repo.label }}/recent-errors.json"> data-json-string-request="/repo/{{ repo.label }}/recent-errors.json">
<div class="spinner-border spinner-border-sm" role="status"> <div class="spinner-border" role="status">
</div> </div>
</dd> </dd>
</dl> </dl>
<div id="repo-{{ repo.label }}-size-graph" <canvas id="repo-{{ repo.label }}-size-graph" width="400" height="200"></canvas>
class="d-flex justify-content-center" </dl>
data-json-graph-request="/repo/{{ repo.label }}/monthly-size.json">
<div class="spinner-border" role="status">
</div>
</div>
</div> </div>
{% endfor %} {% endfor %}
{% else %} {% else %}

View File

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Toggle repo visibility</title>
</head>
<body>
<form action="toggle" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
</body>
</html>

View File

@ -0,0 +1,23 @@
<script id="repo-template" type="text/x-custom-template">
<div style="width: 600px;" class="repo-container shadow rounded overflow-hidden">
<div class="row me-1 overflow-hidden text-truncate">
<h2 class="h2"> <span class="repo-label"></span>
<small class="repo-location text-muted"></small>
</h2>
</div>
<dl class="att-label row ps-3">
<dt class="col-4">Latest backup:</dt>
<dd class="repo-latest-backup col-8"></dd>
</dl>
<dl class="att-label row ps-3">
<dt class="col-4">Size:</dt>
<dd class="repo-size col-8"></dd>
</dl>
<dl class="att-label row ps-3">
<dt class="col-4">Recent errors:</dt>
<dd class="repo-recent-errors col-8"></dd>
</dl>
<canvas class="repo-size-graph" width="400" height="200"></canvas>
</dl>
</div>
</script>

View File

@ -10,7 +10,7 @@ urlpatterns = [
path('repo-list.json', cache_page(60)(views.repo_list_json), name='repo list'), path('repo-list.json', cache_page(60)(views.repo_list_json), name='repo list'),
# Repo # Repo
path('repo/<str:repo_label>/monthly-size.json', cache_page(60)(views.repo_monthly_size_json), path('repo/<str:repo_label>/monthly-size.json', cache_page(3600)(views.repo_monthly_size_json),
name='repo size time series'), name='repo size time series'),
path('repo/<str:repo_label>.json', cache_page(60)(views.repo_json), name='repo json'), path('repo/<str:repo_label>.json', cache_page(60)(views.repo_json), name='repo json'),
path('repo/<str:repo_label>/latest-backup.json', cache_page(60)(views.repo_latest_backup_json), name='repo json'), path('repo/<str:repo_label>/latest-backup.json', cache_page(60)(views.repo_latest_backup_json), name='repo json'),
@ -20,11 +20,9 @@ urlpatterns = [
# Repo page # Repo page
path('repo/<str:repo_label>', cache_page(60)(views.repo), name='repo'), path('repo/<str:repo_label>', cache_page(60)(views.repo), name='repo'),
path('repo/<str:repo_label>/errors', cache_page(60)(views.repo_errors), name='repo'),
# POST # POST
path('post/repo', views.post_repo, name='post repo'), path('post/repo', views.post_repo, name='post repo'),
path('post/toggle', views.toggle_visibility, name='toggle repo visibility'),
path('post/archive', views.post_archive, name='post archive'), path('post/archive', views.post_archive, name='post archive'),
path('post/error', views.post_error, name='post error'), path('post/error', views.post_error, name='post error'),
path('post/location', views.post_location, name='post location'), path('post/location', views.post_location, name='post location'),

View File

@ -35,10 +35,14 @@ def repo_monthly_size_json(request, repo_label, months_ago: int = 12):
max_unit = get_units([repo]) max_unit = get_units([repo])
repo_dict = {"id": repo.id,
"label": repo.label.label,
"size": repo.size_on_months(max_unit, months_ago)}
response_dict = { response_dict = {
"dates": date_labels, "dates": date_labels,
"units": max_unit, "repo": repo_dict,
"size": repo.size_on_months(max_unit, months_ago) "units": max_unit
} }
return JsonResponse(response_dict) return JsonResponse(response_dict)

View File

@ -3,34 +3,9 @@ from django.http import HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.core.cache import cache as django_cache from django.core.cache import cache
from ..models import Repo, Label, Archive, Cache, Error, Location from ..models import Repo, Label, Archive, Cache, Error, Location
from ..forms import RepoForm, ArchiveForm, ErrorForm, LocationForm, ToggleVisibility from ..forms import RepoForm, ArchiveForm, ErrorForm, LocationForm
import logging
logger = logging.getLogger(__file__)
@permission_required("borg.change_repo")
def toggle_visibility(request):
if request.method == 'POST':
form = ToggleVisibility(request.POST)
if form.is_valid():
cdata = form.cleaned_data
label = get_object_or_404(Label, label=cdata['label'])
label.visible = not label.visible
label.save()
django_cache.clear()
return HttpResponseRedirect(reverse('index'))
else:
form = ToggleVisibility()
return render(request, 'borg/post/toggle.html', {'form': form})
@permission_required("borg.add_repo") @permission_required("borg.add_repo")
@ -53,7 +28,7 @@ def post_repo(request):
'last_modified': cdata['last_modified'], 'last_modified': cdata['last_modified'],
'label': label}) 'label': label})
repo.save() repo.save()
django_cache.clear() cache.clear()
return HttpResponseRedirect(reverse('index')) return HttpResponseRedirect(reverse('index'))
else: else:
@ -67,7 +42,6 @@ def post_archive(request):
if request.method == 'POST': if request.method == 'POST':
form = ArchiveForm(request.POST) form = ArchiveForm(request.POST)
if form.is_valid(): if form.is_valid():
try:
cdata = form.cleaned_data cdata = form.cleaned_data
repo = get_object_or_404(Repo, label__label=cdata['label']) repo = get_object_or_404(Repo, label__label=cdata['label'])
@ -83,9 +57,7 @@ def post_archive(request):
archive = Archive(**archive_dict, repo=repo, cache=cache) archive = Archive(**archive_dict, repo=repo, cache=cache)
archive.save() archive.save()
django_cache.clear() cache.clear()
except Exception:
logger.exception("Archive post failed")
return HttpResponseRedirect(reverse('index')) return HttpResponseRedirect(reverse('index'))
else: else:
@ -104,7 +76,7 @@ def post_error(request):
error = Error(label=label, error=cdata['error'], time=cdata['time']) error = Error(label=label, error=cdata['error'], time=cdata['time'])
error.save() error.save()
django_cache.clear() cache.clear()
return HttpResponseRedirect(reverse('index')) return HttpResponseRedirect(reverse('index'))
else: else:
@ -122,7 +94,7 @@ def post_location(request):
label, _ = Location.objects.get_or_create(label=cdata['label'], label, _ = Location.objects.get_or_create(label=cdata['label'],
defaults={"path": cdata["path"]}) defaults={"path": cdata["path"]})
label.save() label.save()
django_cache.clear() cache.clear()
return HttpResponseRedirect(reverse('index')) return HttpResponseRedirect(reverse('index'))
else: else:

View File

@ -1,10 +1,9 @@
from django.contrib.auth.decorators import permission_required
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from ..models import Repo from ..models import Repo
def index(request): def index(request):
repo_list = Repo.objects.filter(label__visible=True) repo_list = Repo.objects.all()
context = { context = {
'repo_list': repo_list, 'repo_list': repo_list,
@ -17,11 +16,5 @@ def repo(request, repo_label: str):
return render(request, 'borg/repo.html', {'repo': s_repo}) return render(request, 'borg/repo.html', {'repo': s_repo})
@permission_required("borg.view_error")
def repo_errors(request, repo_label: str):
s_repo = get_object_or_404(Repo, label__label=repo_label)
return render(request, 'borg/errors.html', {'errors': s_repo.label.errors.all().order_by('-time')})
def axes(request, credentials, *args, **kwargs): def axes(request, credentials, *args, **kwargs):
return render(request, 'error/axes.html', {}) return render(request, 'error/axes.html', {})

View File

@ -1 +1 @@
from .secrets import SECRET_KEY, DATABASE_PASSWORD from .secrets import SECRET_KEY

View File

@ -2,7 +2,6 @@ import os
from pathlib import Path from pathlib import Path
from . import SECRET_KEY as __SECRET_KEY from . import SECRET_KEY as __SECRET_KEY
from . import DATABASE_PASSWORD as __DATABASE_PASSWORD
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@ -10,11 +9,9 @@ SECRET_KEY = __SECRET_KEY
DEBUG = False DEBUG = False
AXES_META_PRECEDENCE_ORDER = ('HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR', 'REMOTE_ADDR')
AXES_LOCKOUT_CALLABLE = "borg.views.axes" AXES_LOCKOUT_CALLABLE = "borg.views.axes"
ALLOWED_HOSTS = ['127.0.0.1', 'borg.george.ooo', 'george.ooo', 'www.george.ooo', '10.10.10.100', 'proxy.george.ooo'] ALLOWED_HOSTS = ['127.0.0.1', 'borg.george.ooo', 'george.ooo', 'www.george.ooo']
AUTHENTICATION_BACKENDS = [ AUTHENTICATION_BACKENDS = [
'axes.backends.AxesBackend', 'axes.backends.AxesBackend',
@ -68,12 +65,8 @@ WSGI_APPLICATION = 'borgweb.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'borgweb', 'NAME': "/home/web/sites/db/borg.db",
'USER': 'borgweb',
'PASSWORD': __DATABASE_PASSWORD,
'HOST': 'db.george.ooo',
'PORT': '5432',
} }
} }
@ -127,7 +120,7 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CACHES = { CACHES = {
"default": { "default": {
"BACKEND": "django_redis.cache.RedisCache", "BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://cache.george.ooo:6379/1", "LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": { "OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient" "CLIENT_CLASS": "django_redis.client.DefaultClient"
}, },
@ -135,36 +128,6 @@ CACHES = {
} }
} }
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"root": {"level": "INFO", "handlers": ["file"]},
"handlers": {
"file": {
"level": "INFO",
"class": "logging.FileHandler",
"filename": "/var/log/django/borgweb.log",
"formatter": "app",
},
},
"loggers": {
"django": {
"handlers": ["file"],
"level": "INFO",
"propagate": True
},
},
"formatters": {
"app": {
"format": (
u"%(asctime)s [%(levelname)-8s] "
"(%(module)s.%(funcName)s) %(message)s"
),
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
}
# security # security
SESSION_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True SECURE_SSL_REDIRECT = True

View File

@ -80,7 +80,7 @@ WSGI_APPLICATION = 'borgweb.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'borg.db', 'NAME': BASE_DIR / 'borg.sqlite',
} }
} }

View File

@ -35,7 +35,7 @@ print_action "Installing pip packages, this may take a while..."
# install required pip packages # install required pip packages
yes | python -m pip install --upgrade wheel yes | python -m pip install --upgrade wheel
yes | python -m pip install django gunicorn django-libsass django-compressor django-axes django-redis psycopg2-binary yes | python -m pip install django gunicorn django-libsass django-compressor django-axes django-redis
print_action "Setting up static files and database" print_action "Setting up static files and database"

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
cd "${0%/*}"
source ./venv/bin/activate
python ./manage.py collectstatic --noinput
python ./manage.py compress
python ./manage.py migrate --noinput
deactivate