vacuum-tube/main.py

86 lines
2.7 KiB
Python

from config import config
from datetime import datetime
from rich import print, box
from rich.console import Group
from rich.progress import Progress, BarColumn
from rich.panel import Panel
from rich.style import Style
import json
import os
# https://stackoverflow.com/questions/1094841/get-human-readable-version-of-file-size
# except, the units match the output of `df -h` and `borg info`
def readable_size(num, suffix=""):
for unit in ["B", "K", "M", "G", "T", "P", "E", "Z"]:
if abs(num) < 1000.0:
return f"{num:3.1f}{unit}{suffix}"
num /= 1000.0
return f"{num:.1f}Y{suffix}"
# setup
# get the repo information
if not config['repo']['path']:
raise Exception('No repo path provided!')
if not config['disk']['partition']:
raise Exception('No partition path provided!')
# check if a passphrase has been provided
if config['repo']['passphrase']:
passphrase = 'BORG_PASSPHRASE=' + config['repo']['passphrase'] + ' '
else:
passphrase = ''
borg_info = os.popen(passphrase + 'borg info --json ' + config['repo']['path']).read()
# parse repo info from json
borg_info = json.loads(borg_info)
stats = borg_info['cache']['stats']
csize = int(stats['unique_csize'])
borg_list = os.popen(passphrase + 'borg list --json ' + config['repo']['path']).read()
# parse repo info from json
borg_list = json.loads(borg_list)
last_archive = borg_list['archives'][-1]
# datetime format: https://borgbackup.readthedocs.io/en/stable/internals/frontends.html#standard-output
last_archive_time = datetime.strptime(last_archive['time'], '%Y-%m-%dT%H:%M:%S.%f')
last_archive_time = last_archive_time.strftime('%d/%m/%Y %H:%M')
# get free disk space
df_avail = os.popen(config['disk']['ssh'] + ' "df --block-size=1000 --output=avail ' + config['disk']['partition'] + ' | tail -1"').read().rstrip()
# actually print the thing
emphasis = Style(color="#d89961", bold=True)
# it's hacky, but should work as expected
used = Progress(
'[progress.description]{task.description}',
# space used
f'[{emphasis}]{readable_size(csize)}[/{emphasis}]',
BarColumn(complete_style=emphasis, finished_style="#d34141"),
# space available
f'[{emphasis}]{readable_size((int(df_avail) * 1000))}[/{emphasis}]',
'[progress.percentage]{task.percentage:>3.0f}%'
)
used.add_task("Used:", completed=csize, total=(int(df_avail) * 1000))
disk_usage = Panel(used, box=box.DOUBLE, border_style=emphasis)
avail_backups = Panel(f"Available: [{emphasis}]{len(borg_list['archives'])}[/{emphasis}] backups. Last backup from: [{emphasis}]{last_archive_time}[/{emphasis}]", box=box.DOUBLE, border_style=emphasis)
output_group = Group(
disk_usage,
avail_backups
)
print(Panel(
output_group,
box=box.SQUARE, border_style="#d89961"
))