From b16d72415ed2c52c0b0da537722b1bbcb3f62773 Mon Sep 17 00:00:00 2001 From: localhorst Date: Tue, 22 Nov 2022 20:54:11 +0100 Subject: [PATCH] better styling with font --- layouter.py | 52 ++++++++++++++++++++++++++++++++++------------------ output.png | Bin 5514 -> 5596 bytes 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/layouter.py b/layouter.py index fe3d5cd..62e2f31 100644 --- a/layouter.py +++ b/layouter.py @@ -68,11 +68,16 @@ class DriveDataJson: rehdd_info = ReHddInfo("https://git.mosad.xyz/localhorst/reHDD", "bV0.2.2") # read this from rehdd process temp_drive = DriveData(drive_index=0, drive_state="shredded", modelfamiliy="Toshiba 2.5\\ HDD MK..65GSSX",\ - modelname="TOSHIBA MK3265GSDX", capacity=343597383680, serialnumber="YG6742U56UDRL", power_on_hours=7074,\ + modelname="TOSHIBA MK3265GSDX", capacity=343597383680, serialnumber="YG6742U56UDRL123", power_on_hours=7074,\ power_cycle=4792, smart_error_count=1, shred_timestamp=1647937421, shred_duration=81718) -def get_font_path(): +def get_font_path_regular(): + path = "/usr/share/fonts" + files = glob.glob(path + "/**/DejaVuSans.ttf", recursive = True) + return files[0] + +def get_font_path_bold(): path = "/usr/share/fonts" files = glob.glob(path + "/**/DejaVuSans-Bold.ttf", recursive = True) return files[0] @@ -105,10 +110,11 @@ def format_to_printable(drive): #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)),\ + 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(16, 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)),\ @@ -116,29 +122,39 @@ def format_to_printable(drive): cut_string(30, str(datetime.timedelta(seconds = drive.shred_duration)))) def draw_text(drawable, printable_data, text_x_offset): - font_file = get_font_path() + font_file_regular = get_font_path_regular() + font_file_bold = get_font_path_bold() font_size = 20 - text_y_offset = 15 + text_y_offset = 10 text_y_offset_increment = 25 + value_colum_x_offset = 120 - drawable.text((text_x_offset, text_y_offset), "Familiy: " + printable_data.modelfamiliy,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), printable_data.serialnumber,(0),font=ImageFont.truetype(font_file_bold, 30)) + text_y_offset += 40 + + drawable.text((text_x_offset, text_y_offset), "Familiy: ",(0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.modelfamiliy,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Model: " + printable_data.modelname,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), "Model: ",(0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.modelname,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Serial: " + printable_data.serialnumber,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), "Hours: " ,(0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.power_on_hours,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Hours: " + printable_data.power_on_hours,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), "Cycles: ",(0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.power_cycle,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Cycles: " + printable_data.power_cycle,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), "Errors: ", (0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.smart_error_count,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Errors: " + printable_data.smart_error_count,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), "Shred on: ",(0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.shred_timestamp,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Shred on: " + printable_data.shred_timestamp,(0),font=ImageFont.truetype(font_file, font_size)) - text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), "Duration: " + printable_data.shred_duration,(0),font=ImageFont.truetype(font_file, font_size)) + drawable.text((text_x_offset, text_y_offset), "Duration: " ,(0),font=ImageFont.truetype(font_file_bold, font_size)) + drawable.text((text_x_offset+value_colum_x_offset, text_y_offset), printable_data.shred_duration,(0),font=ImageFont.truetype(font_file_regular, font_size)) text_y_offset += text_y_offset_increment - drawable.text((text_x_offset, text_y_offset), printable_data.capacity,(0),font=ImageFont.truetype(font_file, font_size*3)) + drawable.text((text_x_offset, text_y_offset), printable_data.capacity,(0),font=ImageFont.truetype(font_file_bold, font_size*3)) def draw_outline(drawable, margin, width, output_width, output_height): #upper @@ -152,7 +168,7 @@ def draw_outline(drawable, margin, width, output_width, output_height): def draw_qr_code(image, data): qr_img = qrcode.make(data) - qr_img.thumbnail((290, 290), Image.Resampling.LANCZOS) + qr_img.thumbnail((291, 291), Image.Resampling.LANCZOS) image.paste(qr_img, (7, 7)) @@ -172,7 +188,7 @@ def main(): output_image = Image.new('1', (output_width, output_height), "white") draw = ImageDraw.Draw(output_image) - draw_outline(draw, 2, 5, output_width, output_height) + draw_outline(draw, 1, 4, output_width, output_height) draw_text(draw, printable_data, text_x_offset) draw_qr_code(output_image, str(json_qr_daten).replace(" ", "")) diff --git a/output.png b/output.png index c9784b1eb00bdda203dad770e89c6a0acfb9f331..1dda8ff229bb9e721ee905afeb89451de303b12f 100644 GIT binary patch literal 5596 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

y&3XOua^rdg6i;-mZRJ&oBPP)L+}j+xs(Sjz z5_WM$pRrQ7-Y6)Q7!7H^D(nxW+Zyhn9#=m>e{x49P3 zm$T?Y2Yh%U1{1sl7a%`G2*B5~w0GorUZe;y2Hy4nKW*-*-MxqRhUK{{wi3EM`D6>I zhJzH119dvnLi&EBI4~TZZ$K=>)d%P1jyyE~BzK~e6?cE^if&KzxzJ%!P6LO&J-*^b z{SoW&EU!Ep}m7U&Y?je;u)#Qy}^BSP5@1G zWC7Oxksd@J(Y;N{MYfbkY^H5LHKH|GGlr!h5SG4{sOO3x8i@h7z{eJm93{B3as8Pk zQ(Aw1+y8>wI6xD51?wT6nG~KVc=YcnBu!w0&JDJmxbrLgGn19ZRHd$ZIL*~NIz9|i zRBiW(*Elbs@4UwJY@E@Do_R09oqyM0hJ5c3FL(*=h1sV!Gked1imF>j4Zzj!Bf1d~ zw*7&duetep;b-GKH6$y{M6}EngE8PrK5JDa*faa#8S|`mJ6pvDR{%^Zf4GXh6uZDb za-gWmRfh`ClkW3Io>~1SSHrgN?A%=c@^X7>J9qbBu+-XEHudW6@j;3gb6>f99l36S zY^kKbhAH