#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Author: Hendrik Schutter, localhorst@mosad.xyz Date of creation: 2022/11/16 Date of last modification: 2022/11/16 """ import re import os import sys import time import subprocess import shlex import shutil from dataclasses import dataclass import glob import PIL from PIL import Image from PIL import ImageFont from PIL import ImageDraw import datetime rehddversion="bV0.2.2" # read this from rehdd process @dataclass class DriveData: drive_index: int drive_state: str #none, deleted, shredded modelfamiliy: str modelname: str capacity: int #in bytes serialnumber: str power_on_hours: int #in hours power_cycle: int smart_error_count: int shred_timestamp: int #unix timestamp shred_duration: int #in seconds @dataclass class DriveDataPrintable: modelfamiliy: str #max lenght 25 modelname: str #max lenght 25 capacity: str #max lenght 25, in human-readable format with unit (GB/TB) serialnumber: str #max lenght 25 power_on_hours: str #max lenght 25, in hours and days and years power_cycle: str #max lenght 25 smart_error_count: str #max lenght 25 shred_timestamp: str #max lenght 25, human-readable shred_duration: str #max lenght 25, human-readable temp_drive = DriveData(drive_index=0, drive_state="shredded", modelfamiliy="Toshiba 2.5\\ HDD MK..65GSSX",\ modelname="TOSHIBA MK3265GSDX", capacity=343597383680, serialnumber="70fFr-_/ tefrtg", power_on_hours=7074,\ power_cycle=4792, smart_error_count=1, shred_timestamp=1647937421, shred_duration=81718) def get_font_path(): path = "/usr/share/fonts" files = glob.glob(path + "/**/DejaVuSans-Bold.ttf", recursive = True) return files[0] def human_readable_capacity(size, decimal_places=0): for unit in ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']: if size < 1024.0 or unit == 'PiB': break size /= 1024.0 return f"{size:.{decimal_places}f} {unit}" def human_readable_power_on_hours(hours, decimal_places=2): return str(hours) + "h or " + str(int(hours/24)) + "d or " + str("{:.2f}".format(float(hours/24/365))) + "y" def cut_string(max_lenght, data): if (len(data) > max_lenght): return data[0:(max_lenght-4)] + " ..." else: return data def format_to_printable(drive): #print(cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelfamiliy))) #print(cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelname))) #print(cut_string(20, human_readable_capacity(drive.capacity))) #print(cut_string(20, re.sub(r"[^a-zA-Z0-9.-_]", "", drive.serialnumber))) #print(cut_string(30, human_readable_power_on_hours(drive.power_on_hours))) #print(cut_string(10, str(drive.power_cycle))) #print(cut_string(10, str(drive.smart_error_count))) #print(cut_string(30, datetime.datetime.utcfromtimestamp(drive.shred_timestamp).strftime('%Y-%m-%d %H:%M:%S'))) #print(cut_string(30, str(datetime.timedelta(seconds = drive.shred_duration)))) return DriveDataPrintable(cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelfamiliy)),\ cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelname)),\ cut_string(20, human_readable_capacity(drive.capacity)),\ cut_string(20, re.sub(r"[^a-zA-Z0-9.-_]", "", drive.serialnumber)),\ cut_string(30, human_readable_power_on_hours(drive.power_on_hours)),\ cut_string(10, str(drive.power_cycle)),\ cut_string(10, str(drive.smart_error_count)),\ cut_string(30, datetime.datetime.utcfromtimestamp(drive.shred_timestamp).strftime('%Y-%m-%d %H:%M:%S')),\ cut_string(30, str(datetime.timedelta(seconds = drive.shred_duration)))) def main(): output_width = 696 output_height = 348 printable_data = format_to_printable(temp_drive) print(printable_data) text_y_offset= int(output_width / 3) output_image = Image.new('1', (output_width, output_height), "white") font_file = get_font_path() draw = ImageDraw.Draw(output_image) draw.text((text_y_offset, 5), "modelfamiliy: " + printable_data.modelfamiliy,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 20), "modelname: " + printable_data.modelname,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 35), "serial: " + printable_data.serialnumber,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 50), "poweronhours: " + printable_data.power_on_hours,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 65), "powercycle: " + printable_data.power_cycle,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 80), "errorcount: " + printable_data.smart_error_count,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 95), "shredtimestamp: " + printable_data.shred_timestamp,(0),font=ImageFont.truetype(font_file, 15)) draw.text((text_y_offset, 110), "shredduration: " + printable_data.shred_duration,(0),font=ImageFont.truetype(font_file, 15)) output_image.save("output.png") if __name__ == "__main__": main()