Add monthly backup size graph

This commit is contained in:
George Lacey 2021-05-21 20:19:46 +01:00
parent 76fb5b3763
commit 35c0b1946f
6 changed files with 88 additions and 16 deletions

View File

@ -96,11 +96,11 @@ class Repo(models.Model):
def size_on_dates(self, units, dates: list): def size_on_dates(self, units, dates: list):
archives = self.archives_on_dates(dates) archives = self.archives_on_dates(dates)
return { return self.series_csize(archives, units)
"id": self.id,
"label": self.label.label, def size_on_months(self, units, months: int = 12):
"size": list(self.series_csize(archives, units)) archives = self.monthly_archives(months)
} return self.series_csize(archives, units)
@staticmethod @staticmethod
def series_times(archives): def series_times(archives):
@ -114,6 +114,20 @@ class Repo(models.Model):
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):
archives = []
for month in range(n_months):
current_date = subtract_months(datetime.utcnow(), month)
archive_current_month = self.archive_set.all() \
.filter(start__year=current_date.year,
start__month=current_date.month) \
.order_by('-start')
if len(archive_current_month) > 0:
archives.append(archive_current_month[0])
else:
archives.append(None)
return archives[::-1]
def archives_on_dates(self, dates: list): def archives_on_dates(self, dates: list):
archives = [] archives = []
archive_queryset = self.archive_set.all() archive_queryset = self.archive_set.all()

View File

@ -2,6 +2,9 @@ window.addEventListener("DOMContentLoaded", function () {
$.getJSON( "repo_daily.json", function( json ) { $.getJSON( "repo_daily.json", function( json ) {
draw_time_graph("daily_backup_size", json.repos, json.dates, json.units); draw_time_graph("daily_backup_size", json.repos, json.dates, json.units);
}); });
$.getJSON( "repo_monthly.json", function( json ) {
draw_time_graph("monthly_backup_size", json.repos, json.dates, json.units);
});
}, false); }, false);
function draw_time_graph(chartID, repos, dateLabels, sizeUnits) { function draw_time_graph(chartID, repos, dateLabels, sizeUnits) {

View File

@ -57,6 +57,9 @@
<div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden"> <div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden">
<canvas id="daily_backup_size" width="400" height="200"></canvas> <canvas id="daily_backup_size" width="400" height="200"></canvas>
</div> </div>
<div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden">
<canvas id="monthly_backup_size" width="400" height="200"></canvas>
</div>
{% else %} {% else %}
<div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden"> <div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden">
<div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden"> <div style="width: 600px;" class="repo-container shadow rounded bg-primary overflow-hidden">

View File

@ -5,7 +5,8 @@ from . import views
urlpatterns = [ urlpatterns = [
path('', cache_page(60)(views.index), name='index'), path('', cache_page(60)(views.index), name='index'),
path('repo_daily.json', cache_page(3600)(views.repo_daily_json), name='repo json'), path('repo_daily.json', cache_page(3600)(views.repo_daily_json), name='daily repo json'),
path('repo_monthly.json', cache_page(3600 * 12)(views.repo_monthly_json), name='monthly repo json'),
path('repo/<str:repo_label>', views.repo, name='repo'), path('repo/<str:repo_label>', views.repo, name='repo'),
path('post/repo', views.post_repo, name='post repo'), path('post/repo', views.post_repo, name='post repo'),
path('post/archive', views.post_archive, name='post archive'), path('post/archive', views.post_archive, name='post archive'),

View File

@ -1,3 +1,3 @@
from .views import index, repo, axes from .views import index, repo, axes
from .post import post_repo, post_archive, post_error, post_location from .post import post_repo, post_archive, post_error, post_location
from .json import repo_daily_json from .json import repo_daily_json, repo_monthly_json

View File

@ -2,16 +2,65 @@ from datetime import datetime, timedelta
from django.http import JsonResponse from django.http import JsonResponse
from ..models import Repo from ..models import Repo
from ..utility import data from ..utility import data
import calendar
def repo_daily_dict(repo_list, n_days=14): def repo_monthly_json(request, months_ago: int = 12):
dates = [(datetime.utcnow() - timedelta(days=day)) for day in range(n_days)][::-1] date_labels = monthly_date_labels(months_ago)
date_labels = list([day.strftime("%d %b") for day in dates])
max_repo_size = max(repo.latest_archive().cache.unique_csize for repo in repo_list) repo_list = Repo.objects.all()
_, max_unit = data.convert_bytes(max_repo_size)
repo_dicts = [repo.size_on_dates(max_unit, dates) for repo in repo_list] max_unit = get_units(repo_list)
repo_dicts = [{
"id": repo.id,
"label": repo.label.label,
"size": repo.size_on_months(max_unit, months_ago)
} for repo in repo_list]
response_dict = {
"dates": date_labels,
"repos": repo_dicts,
"units": max_unit
}
return JsonResponse(response_dict)
def monthly_date_labels(months_ago: int):
dates = []
current_date = datetime.utcnow().date()
current_year = current_date.year
current_month = current_date.month
dates.append(current_date)
for month in range(months_ago - 1):
if current_month == 1:
current_year -= 1
current_month = 12
else:
current_month -= 1
last_day = calendar.monthrange(current_year, current_month)[1]
current_date = current_date.replace(year=current_year, month=current_month, day=last_day)
dates.append(current_date)
return [date.strftime("%b %Y") for date in dates][::-1]
def repo_daily_json(request, days_ago: int = 30):
repo_list = Repo.objects.all()
dates = [(datetime.utcnow() - timedelta(days=day)) for day in range(days_ago)][::-1]
return JsonResponse(repo_size_dict(repo_list, dates, "%d %b"))
def repo_size_dict(repo_list, dates: list, date_format: str):
date_labels = list([day.strftime(date_format) for day in dates])
max_unit = get_units(repo_list)
repo_dicts = [{
"id": repo.id,
"label": repo.label.label,
"size": repo.size_on_dates(max_unit, dates)
} for repo in repo_list]
return { return {
"dates": date_labels, "dates": date_labels,
@ -20,6 +69,8 @@ def repo_daily_dict(repo_list, n_days=14):
} }
def repo_daily_json(request): def get_units(repo_list):
repo_list = Repo.objects.all() max_repo_size = max(repo.latest_archive().cache.unique_csize for repo in repo_list)
return JsonResponse(repo_daily_dict(repo_list, 31)) _, max_unit = data.convert_bytes(max_repo_size)
return max_unit