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" ))