#!/usr/bin/env python from argparse import ArgumentParser from math import ceil, floor from random import randrange, choice from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.graphics.shapes import Drawing from reportlab.graphics.barcode.qr import QrCodeWidget from reportlab.graphics import renderPDF from urllib.parse import urljoin def generate_random_username(female_nouns, male_nouns, adjectives, used_usernames): random_username = None while True: nouns = choice([female_nouns, male_nouns]) random_username = f"{adjectives[randrange(len(adjectives)-1)]}{'' if nouns is female_nouns else 'r'}-{nouns[randrange(len(nouns)-1)].lower()}" if random_username not in used_usernames: used_usernames.add(random_username) print(random_username) return random_username if __name__ == "__main__": parser = ArgumentParser(description="Generates a QR code PDF with random usernames and prints the names to stdout.") parser.add_argument("url", help="Base URL, e.g. 'https://url.com'.") parser.add_argument("-n", "--number", type=int, help="Amount of requested usernames, defaults to 50.", default=50) parser.add_argument("-o", "--output", type=str, help="Output file, defaults to 'qrcodes.pdf'.", default="qrcodes.pdf") parser.add_argument("-s", "--size", type=int, help="QR code size, defaults to 45.", default=45) args = parser.parse_args() adjectives = set() female_nouns = set() male_nouns = set() with open('adjektive-weiblich.txt', 'r') as file: for line in file: adjectives.add(line.strip()) with open('nomen-weiblich.txt', 'r') as file: for line in file: female_nouns.add(line.strip()) with open('nomen-maennlich.txt', 'r') as file: for line in file: male_nouns.add(line.strip()) adjectives = list(adjectives) female_nouns = list(female_nouns) male_nouns = list(male_nouns) pdf = canvas.Canvas(args.output, pagesize=A4) page_width, page_height = A4 used_usernames = set() codes_per_row = floor(page_width/args.size) codes_per_col = floor(page_height/args.size) if codes_per_col == 0 or codes_per_row == 0: raise Exception(f"There is not enough space on A4 page to fit a QR code of size {args.size}x{args.size}!") codes_per_page = codes_per_row*codes_per_col required_pages = ceil(args.number/codes_per_page) generated_codes = 0 for page in range(required_pages): for y in range(codes_per_col): for x in range(codes_per_row): qr_code = QrCodeWidget(urljoin(args.url, generate_random_username(female_nouns, male_nouns, adjectives, used_usernames))) bounds = qr_code.getBounds() code_width = bounds[2] - bounds[0] code_height = bounds[3] - bounds[1] drawing = Drawing(args.size, args.size, transform=[args.size/code_width, 0, 0, args.size/code_height, 0, 0]) drawing.add(qr_code) renderPDF.draw(drawing, pdf, args.size*(x%codes_per_row), args.size*(y%codes_per_col)) generated_codes += 1 if generated_codes >= args.number: pdf.save() exit() pdf.showPage() pdf.save()