Compare commits

..

No commits in common. "c10b1cd3427f33ee9a9ea40f2933215319ca0452" and "954bed9e56c1be3c43e7037decfffbf7d5f23dab" have entirely different histories.

2 changed files with 39 additions and 125 deletions

View File

@ -21,9 +21,10 @@ FONT_PATH = "/usr/share/fonts"
DEFAULT_FONT_REGULAR = "DejaVuSans.ttf" DEFAULT_FONT_REGULAR = "DejaVuSans.ttf"
DEFAULT_FONT_BOLD = "DejaVuSans-Bold.ttf" DEFAULT_FONT_BOLD = "DejaVuSans-Bold.ttf"
OUTPUT_WIDTH = 696 # px OUTPUT_WIDTH = 696 # px
OUTPUT_HEIGHT = 190 # px OUTPUT_HEIGHT = 300 # px
TEXT_X_OFFSET = 190 # px TEXT_X_OFFSET = 300 # px
QR_CODE_SIZE = 179 # px QR_CODE_SIZE = 289 # px
# Configure logging # Configure logging
logging.basicConfig( logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
@ -45,20 +46,6 @@ class DriveData:
shred_duration: int shred_duration: int
@dataclasses.dataclass
class DriveDataJson:
state: str
fam: str
name: str
cap: int
sn: str
poh: int
pc: int
err: int
time: int
dur: int
@dataclasses.dataclass @dataclasses.dataclass
class DriveDataPrintable: class DriveDataPrintable:
modelfamily: str modelfamily: str
@ -74,13 +61,13 @@ class DriveDataPrintable:
@dataclasses.dataclass @dataclasses.dataclass
class ReHddInfo: class ReHddInfo:
ref: str link: str
ver: str version: str
@dataclasses.dataclass @dataclasses.dataclass
class QrDataJson: class DriveDataJson:
drive: DriveDataJson drive: DriveData
rehdd: ReHddInfo rehdd: ReHddInfo
@ -135,7 +122,7 @@ def format_to_printable(drive):
cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelfamily), "end"), cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelfamily), "end"),
cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelname), "end"), cut_string(20, re.sub(r"[^a-zA-Z0-9. ]", "", drive.modelname), "end"),
cut_string(20, human_readable_capacity(drive.capacity), "end"), cut_string(20, human_readable_capacity(drive.capacity), "end"),
cut_string(20, re.sub(r"[^a-zA-Z0-9.-_]", "", drive.serialnumber), "start"), cut_string(16, re.sub(r"[^a-zA-Z0-9.-_]", "", drive.serialnumber), "start"),
cut_string(30, human_readable_power_on_hours(drive.power_on_hours), "end"), cut_string(30, human_readable_power_on_hours(drive.power_on_hours), "end"),
cut_string(10, str(drive.power_cycle), "end"), cut_string(10, str(drive.power_cycle), "end"),
cut_string(10, str(drive.smart_error_count), "end"), cut_string(10, str(drive.smart_error_count), "end"),
@ -151,98 +138,40 @@ def format_to_printable(drive):
def draw_text(drawable, printable_data, font_regular, font_bold, font_bold_bigger): def draw_text(drawable, printable_data, font_regular, font_bold, font_bold_bigger):
"""Draws formatted text with Cycles and Errors on one row.""" """Draws the formatted text onto the image."""
text_y_offset = 10
value_column_x_offset = 120
font_size = 20
line_height = 26
label_x = TEXT_X_OFFSET
value_offset = 115
right_field_spacing = 200 # Horizontal gap between Cycles and Errors
x_capacity = 520
y_capacity = 142
y_start = 4
# Serial Number
drawable.text((label_x, y_start), "Serial:", fill=0, font=font_bold)
drawable.text( drawable.text(
(label_x + value_offset, y_start), (TEXT_X_OFFSET, text_y_offset), printable_data.serialnumber, (0), font=font_bold
printable_data.serialnumber,
fill=0,
font=font_bold,
) )
text_y_offset += 25
y1 = y_start + line_height fields = [
y2 = y1 + line_height ("Family:", printable_data.modelfamily, font_regular),
y3 = y2 + line_height ("Model:", printable_data.modelname, font_regular),
y4 = y3 + line_height ("Hours:", printable_data.power_on_hours, font_regular),
y5 = y4 + line_height ("Cycles:", printable_data.power_cycle, font_regular),
y6 = y5 + line_height ("Errors:", printable_data.smart_error_count, font_regular),
("Shred on:", printable_data.shred_timestamp, font_regular),
("Duration:", printable_data.shred_duration, font_regular),
]
# Left-Aligned Fields (One per row) for label, value, font in fields:
drawable.text((label_x, y1), "Family:", fill=0, font=font_bold) drawable.text((TEXT_X_OFFSET, text_y_offset), label, fill=0, font=font_bold)
drawable.text( drawable.text(
(label_x + value_offset, y1), (TEXT_X_OFFSET + value_column_x_offset, text_y_offset),
printable_data.modelfamily, value,
fill=0, fill=0,
font=font_regular, font=font,
) )
text_y_offset += 25
drawable.text((label_x, y2), "Model:", fill=0, font=font_bold)
drawable.text(
(label_x + value_offset, y2),
printable_data.modelname,
fill=0,
font=font_regular,
)
drawable.text((label_x, y3), "Hours:", fill=0, font=font_bold)
drawable.text(
(label_x + value_offset, y3),
printable_data.power_on_hours,
fill=0,
font=font_regular,
)
# Cycles and Errors on the same line
drawable.text((label_x, y4), "Cycles:", fill=0, font=font_bold)
drawable.text(
(label_x + value_offset, y4),
printable_data.power_cycle,
fill=0,
font=font_regular,
)
drawable.text( drawable.text(
(label_x + right_field_spacing, y4), "Errors:", fill=0, font=font_bold (TEXT_X_OFFSET, text_y_offset),
)
drawable.text(
(label_x + right_field_spacing + value_offset, y4),
printable_data.smart_error_count,
fill=0,
font=font_regular,
)
# Continue remaining fields
drawable.text((label_x, y5), "Shred on:", fill=0, font=font_bold)
drawable.text(
(label_x + value_offset, y5),
printable_data.shred_timestamp,
fill=0,
font=font_regular,
)
drawable.text((label_x, y6), "Duration:", fill=0, font=font_bold)
drawable.text(
(label_x + value_offset, y6),
printable_data.shred_duration,
fill=0,
font=font_regular,
)
# Capacity at the bottom
drawable.text(
(x_capacity, y_capacity),
printable_data.capacity, printable_data.capacity,
fill=0, (0),
font=font_bold_bigger, font=font_bold_bigger,
) )
@ -303,21 +232,7 @@ def draw_outline(drawable, margin, width, output_width, output_height):
def generate_image(drive, rehdd_info, output_file): def generate_image(drive, rehdd_info, output_file):
"""Generates an image containing drive data and a QR code.""" """Generates an image containing drive data and a QR code."""
try: try:
qr_data = json.dumps(dataclasses.asdict(DriveDataJson(drive, rehdd_info)))
drive_json = DriveDataJson(
state=drive.drive_state,
fam=drive.modelfamily,
name=drive.modelname,
cap=drive.capacity,
sn=drive.serialnumber,
poh=drive.power_on_hours,
pc=drive.power_cycle,
err=drive.smart_error_count,
time=int(drive.shred_timestamp),
dur=drive.shred_duration,
)
qr_data = json.dumps(dataclasses.asdict(QrDataJson(drive_json, rehdd_info)))
printable_data = format_to_printable(drive) printable_data = format_to_printable(drive)
except Exception as e: except Exception as e:
logging.error(f"Error preparing data: {e}") logging.error(f"Error preparing data: {e}")
@ -328,9 +243,9 @@ def generate_image(drive, rehdd_info, output_file):
font_regular = ImageFont.truetype(find_font_path(DEFAULT_FONT_REGULAR), 20) font_regular = ImageFont.truetype(find_font_path(DEFAULT_FONT_REGULAR), 20)
font_bold = ImageFont.truetype(find_font_path(DEFAULT_FONT_BOLD), 20) font_bold = ImageFont.truetype(find_font_path(DEFAULT_FONT_BOLD), 20)
font_bold_bigger = ImageFont.truetype(find_font_path(DEFAULT_FONT_BOLD), 42) font_bold_bigger = ImageFont.truetype(find_font_path(DEFAULT_FONT_BOLD), 60)
draw_outline(draw, 0, 3, OUTPUT_WIDTH + 1, OUTPUT_HEIGHT + 1) draw_outline(draw, 1, 4, OUTPUT_WIDTH, OUTPUT_HEIGHT)
draw_text(draw, printable_data, font_regular, font_bold, font_bold_bigger) draw_text(draw, printable_data, font_regular, font_bold, font_bold_bigger)
draw_qr_code(output_image, qr_data) draw_qr_code(output_image, qr_data)
@ -349,7 +264,7 @@ def main():
drive_state="shredded", drive_state="shredded",
modelfamily='Toshiba 2.5" HDD MK..65GSSX', modelfamily='Toshiba 2.5" HDD MK..65GSSX',
modelname="TOSHIBA MK3265GSDX", modelname="TOSHIBA MK3265GSDX",
capacity=343597383000, capacity=343597383680,
serialnumber="YG6742U56UDRL123456789ABCDEFGJKL", serialnumber="YG6742U56UDRL123456789ABCDEFGJKL",
power_on_hours=7074, power_on_hours=7074,
power_cycle=4792, power_cycle=4792,
@ -360,6 +275,5 @@ def main():
generate_image(temp_drive, rehdd_info, "output.png") generate_image(temp_drive, rehdd_info, "output.png")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB