diff --git a/borgweb/borg/models/repo.py b/borgweb/borg/models/repo.py
index 90f1fcd..c91c749 100644
--- a/borgweb/borg/models/repo.py
+++ b/borgweb/borg/models/repo.py
@@ -96,11 +96,11 @@ class Repo(models.Model):
def size_on_dates(self, units, dates: list):
archives = self.archives_on_dates(dates)
- return {
- "id": self.id,
- "label": self.label.label,
- "size": list(self.series_csize(archives, units))
- }
+ return self.series_csize(archives, units)
+
+ def size_on_months(self, units, months: int = 12):
+ archives = self.monthly_archives(months)
+ return self.series_csize(archives, units)
@staticmethod
def series_times(archives):
@@ -114,6 +114,20 @@ class Repo(models.Model):
def hourly_archive_string(self):
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):
archives = []
archive_queryset = self.archive_set.all()
diff --git a/borgweb/borg/static/borg/js/index.js b/borgweb/borg/static/borg/js/index.js
index fb34a23..ebf6435 100644
--- a/borgweb/borg/static/borg/js/index.js
+++ b/borgweb/borg/static/borg/js/index.js
@@ -2,6 +2,9 @@ window.addEventListener("DOMContentLoaded", function () {
$.getJSON( "repo_daily.json", function( json ) {
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);
function draw_time_graph(chartID, repos, dateLabels, sizeUnits) {
diff --git a/borgweb/borg/templates/borg/index.html b/borgweb/borg/templates/borg/index.html
index d2150c2..f5412f8 100644
--- a/borgweb/borg/templates/borg/index.html
+++ b/borgweb/borg/templates/borg/index.html
@@ -57,6 +57,9 @@
+
+
+
{% else %}
diff --git a/borgweb/borg/urls.py b/borgweb/borg/urls.py
index 485fafd..804092d 100644
--- a/borgweb/borg/urls.py
+++ b/borgweb/borg/urls.py
@@ -5,7 +5,8 @@ from . import views
urlpatterns = [
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/', views.repo, name='repo'),
path('post/repo', views.post_repo, name='post repo'),
path('post/archive', views.post_archive, name='post archive'),
diff --git a/borgweb/borg/views/__init__.py b/borgweb/borg/views/__init__.py
index 3bd35ca..944d908 100644
--- a/borgweb/borg/views/__init__.py
+++ b/borgweb/borg/views/__init__.py
@@ -1,3 +1,3 @@
from .views import index, repo, axes
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
diff --git a/borgweb/borg/views/json.py b/borgweb/borg/views/json.py
index 6944a08..b75153e 100644
--- a/borgweb/borg/views/json.py
+++ b/borgweb/borg/views/json.py
@@ -2,16 +2,65 @@ from datetime import datetime, timedelta
from django.http import JsonResponse
from ..models import Repo
from ..utility import data
+import calendar
-def repo_daily_dict(repo_list, n_days=14):
- dates = [(datetime.utcnow() - timedelta(days=day)) for day in range(n_days)][::-1]
- date_labels = list([day.strftime("%d %b") for day in dates])
+def repo_monthly_json(request, months_ago: int = 12):
+ date_labels = monthly_date_labels(months_ago)
- max_repo_size = max(repo.latest_archive().cache.unique_csize for repo in repo_list)
- _, max_unit = data.convert_bytes(max_repo_size)
+ repo_list = Repo.objects.all()
- 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 {
"dates": date_labels,
@@ -20,6 +69,8 @@ def repo_daily_dict(repo_list, n_days=14):
}
-def repo_daily_json(request):
- repo_list = Repo.objects.all()
- return JsonResponse(repo_daily_dict(repo_list, 31))
+def get_units(repo_list):
+ max_repo_size = max(repo.latest_archive().cache.unique_csize for repo in repo_list)
+ _, max_unit = data.convert_bytes(max_repo_size)
+ return max_unit
+