Module soitool.modules.module_authentication_board
Module containing SOI-module 'Autentiseringstavle'.
Expand source code
"""Module containing SOI-module 'Autentiseringstavle'."""
import string
from secrets import choice
from PySide2.QtWidgets import QTableWidgetItem
from PySide2 import QtGui
from PySide2.QtCore import Qt
from soitool.modules.module_base import (
resize_table,
qfont_with_pixel_size,
DEFAULT_FONT,
)
from soitool.modules.code_table_base import CodeTableBase
# Characters for first column,
# it's length determines maximum number of codes (rows).
ROW_IDENTIFIERS = string.ascii_uppercase
# Maximum number of codes depends on ROW_IDENTIFIERS
MAXIMUM_NO_OF_CODES = len(ROW_IDENTIFIERS)
START_NO_OF_CODES = 10
CODE_LENGTH = 25
# Has to be 'ascii', 'digits' or 'combo'
# Codes will consist of A-Z if 'ascii', 0-9 if 'digits' and A-Z+0-9 if 'combo'
CODE_CHARACTER_TYPE = "ascii"
# Font for authentication codes, should be a monospaced font
CODE_FONT = qfont_with_pixel_size("Consolas", DEFAULT_FONT.pixelSize())
# Adds space between sets of characters, 0 => no spaces
# If code is 123456 and interval is 2, code will be 12 34 56
SPACE_INTERVAL = 5
SPACE_AMOUNT = 2
HEADLINE_TEXT = "AUTENTISERINGSTAVLE"
class AuthenticationBoardModule(CodeTableBase):
"""Modified QTableWidget representing SOI-module 'Autentiseringstavle'.
The default widget-initialization has a headline, a row-count of
START_NO_OF_CODES and three columns.
Row x in the first column contains the character ROW_IDENTIFIERS[x].
Row x in the second column contains the character x, for x = 0-9.
Row x in the third column contains an authentication code of length
CODE_LENGTH, spaced out for readability if SPACE_INTERVAL and SPACE_AMOUNT
is larger than 0.
The authentication codes have their own monospaced font for increased
readability, meaning each character has the same width.
If parameter 'data' is given, the widget initializes based on the content.
'data' is a dict with keys "cells", "code_length", "space_interval",
"space_amount" and "code_character_type". "cells" is a 2D list where
cells[0] is the headline and cells[x][y] represents the value in row x,
column y. The other keys contain an integer.
The widget does not use more room than needed, and resizes dynamically.
It has shortcuts for adding and removing rows.
"""
def __init__(self, data=None):
self.type = "AuthenticationBoardModule"
if CODE_CHARACTER_TYPE == "ascii":
self.code_characters = string.ascii_uppercase
elif CODE_CHARACTER_TYPE == "digits":
self.code_characters = string.digits
elif CODE_CHARACTER_TYPE == "combo":
self.code_characters = string.ascii_uppercase + string.digits
else:
raise ValueError(
"Invalid value for CONSTANT 'CODE_CHARACTER_TYPE': "
"'{}'".format(CODE_CHARACTER_TYPE)
)
self.code_font = CODE_FONT
self.maximum_no_of_codes = MAXIMUM_NO_OF_CODES
# Set default values for table to be generated
if data is None:
self.start_no_of_codes = START_NO_OF_CODES
self.code_length = CODE_LENGTH
self.space_interval = SPACE_INTERVAL
self.space_amount = SPACE_AMOUNT
self.code_character_type = CODE_CHARACTER_TYPE
numbers = self.generate_authentication_numbers()
self.start_headline = (
HEADLINE_TEXT
+ " ("
+ str(numbers[0])
+ " & "
+ str(numbers[1])
+ ")"
)
CodeTableBase.__init__(self, data)
# Make cell-borders black for increased readability
self.setStyleSheet("QTableView { gridline-color: black; }")
def insert_row_identifiers(self):
"""Insert values in column one and two."""
for i in range(self.rowCount()):
# Insert non-editable row identifier in first column
item_first = QTableWidgetItem(ROW_IDENTIFIERS[i])
item_first.setTextAlignment(Qt.AlignCenter)
item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable)
self.setItem(i, 0, item_first)
# Insert non-editable row identifier (int) in second column
text_second = str(i) if i < 10 else ""
item_second = QTableWidgetItem(text_second)
item_second.setTextAlignment(Qt.AlignCenter)
item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable)
self.setItem(i, 1, item_second)
def add_row(self, selected_row_index):
"""Insert row below the selected row and add data.
Parameters
----------
selected_row_index : int
Index of the selected row.
"""
# If maximum amount of rows not reached (- 1 to skip headline)
if self.rowCount() - 1 < len(ROW_IDENTIFIERS):
# Generate unique code and insert row
code = self.generate_unique_code()
self.insertRow(selected_row_index + 1)
# Loop through all rows starting with the new row
for i in range(selected_row_index + 1, self.rowCount()):
# Insert row identifier in first column
item_first = QTableWidgetItem(self.code_characters[i - 1])
item_first.setTextAlignment(Qt.AlignCenter)
item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable)
self.setItem(i, 0, item_first)
# Insert row identifier (int) in second column
text_second = str(i - 1) if i <= 10 else ""
item_second = QTableWidgetItem(text_second)
item_second.setTextAlignment(Qt.AlignCenter)
item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable)
self.setItem(i, 1, item_second)
# Insert authentication-code in third column
item_third = QTableWidgetItem(code)
item_third.setFont(self.code_font)
item_third.setTextAlignment(Qt.AlignCenter)
item_third.setFlags(item_third.flags() ^ Qt.ItemIsEditable)
self.setItem(selected_row_index + 1, 2, item_third)
self.resizeRowToContents(selected_row_index + 1)
resize_table(self, columns=False, has_headline=True)
def remove_row(self, row_index):
"""Remove selected row.
Parameters
----------
row_index : int
Index of the row to remove.
"""
self.removeRow(row_index)
# 'Decrease' row identifiers below the removed row
# If first row is removed, identifier A,B,C becomes A,B (not B,C)
for i in range(row_index, self.rowCount()):
self.item(i, 0).setText(self.code_characters[i - 1])
text_second = str(i - 1) if i <= 10 else ""
self.item(i, 1).setText(text_second)
resize_table(self, columns=False, has_headline=True)
def generate_authentication_numbers(self):
"""Generate two non-equal numbers between 1 and self.code_length.
Returns
-------
list
Containing two integers, sorted in ascending order.
"""
available_numbers = list(range(1, self.code_length + 1))
numbers = []
numbers.append(choice(available_numbers))
numbers.append(choice(available_numbers))
while numbers[0] == numbers[1]:
numbers[1] = choice(available_numbers)
numbers.sort()
return numbers
@staticmethod
def get_user_friendly_name():
"""Get user-friendly name of module."""
return "Autentiseringstavle"
@staticmethod
def get_icon():
"""Get icon of module."""
return QtGui.QIcon("soitool/media/authenticationboardmodule.png")
Classes
class AuthenticationBoardModule (data=None)
-
Modified QTableWidget representing SOI-module 'Autentiseringstavle'.
The default widget-initialization has a headline, a row-count of START_NO_OF_CODES and three columns. Row x in the first column contains the character ROW_IDENTIFIERS[x]. Row x in the second column contains the character x, for x = 0-9. Row x in the third column contains an authentication code of length CODE_LENGTH, spaced out for readability if SPACE_INTERVAL and SPACE_AMOUNT is larger than 0.
The authentication codes have their own monospaced font for increased readability, meaning each character has the same width.
If parameter 'data' is given, the widget initializes based on the content. 'data' is a dict with keys "cells", "code_length", "space_interval", "space_amount" and "code_character_type". "cells" is a 2D list where cells[0] is the headline and cells[x][y] represents the value in row x, column y. The other keys contain an integer.
The widget does not use more room than needed, and resizes dynamically. It has shortcuts for adding and removing rows.
Class-variable 'type' should be set by derived class.
Expand source code
class AuthenticationBoardModule(CodeTableBase): """Modified QTableWidget representing SOI-module 'Autentiseringstavle'. The default widget-initialization has a headline, a row-count of START_NO_OF_CODES and three columns. Row x in the first column contains the character ROW_IDENTIFIERS[x]. Row x in the second column contains the character x, for x = 0-9. Row x in the third column contains an authentication code of length CODE_LENGTH, spaced out for readability if SPACE_INTERVAL and SPACE_AMOUNT is larger than 0. The authentication codes have their own monospaced font for increased readability, meaning each character has the same width. If parameter 'data' is given, the widget initializes based on the content. 'data' is a dict with keys "cells", "code_length", "space_interval", "space_amount" and "code_character_type". "cells" is a 2D list where cells[0] is the headline and cells[x][y] represents the value in row x, column y. The other keys contain an integer. The widget does not use more room than needed, and resizes dynamically. It has shortcuts for adding and removing rows. """ def __init__(self, data=None): self.type = "AuthenticationBoardModule" if CODE_CHARACTER_TYPE == "ascii": self.code_characters = string.ascii_uppercase elif CODE_CHARACTER_TYPE == "digits": self.code_characters = string.digits elif CODE_CHARACTER_TYPE == "combo": self.code_characters = string.ascii_uppercase + string.digits else: raise ValueError( "Invalid value for CONSTANT 'CODE_CHARACTER_TYPE': " "'{}'".format(CODE_CHARACTER_TYPE) ) self.code_font = CODE_FONT self.maximum_no_of_codes = MAXIMUM_NO_OF_CODES # Set default values for table to be generated if data is None: self.start_no_of_codes = START_NO_OF_CODES self.code_length = CODE_LENGTH self.space_interval = SPACE_INTERVAL self.space_amount = SPACE_AMOUNT self.code_character_type = CODE_CHARACTER_TYPE numbers = self.generate_authentication_numbers() self.start_headline = ( HEADLINE_TEXT + " (" + str(numbers[0]) + " & " + str(numbers[1]) + ")" ) CodeTableBase.__init__(self, data) # Make cell-borders black for increased readability self.setStyleSheet("QTableView { gridline-color: black; }") def insert_row_identifiers(self): """Insert values in column one and two.""" for i in range(self.rowCount()): # Insert non-editable row identifier in first column item_first = QTableWidgetItem(ROW_IDENTIFIERS[i]) item_first.setTextAlignment(Qt.AlignCenter) item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable) self.setItem(i, 0, item_first) # Insert non-editable row identifier (int) in second column text_second = str(i) if i < 10 else "" item_second = QTableWidgetItem(text_second) item_second.setTextAlignment(Qt.AlignCenter) item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable) self.setItem(i, 1, item_second) def add_row(self, selected_row_index): """Insert row below the selected row and add data. Parameters ---------- selected_row_index : int Index of the selected row. """ # If maximum amount of rows not reached (- 1 to skip headline) if self.rowCount() - 1 < len(ROW_IDENTIFIERS): # Generate unique code and insert row code = self.generate_unique_code() self.insertRow(selected_row_index + 1) # Loop through all rows starting with the new row for i in range(selected_row_index + 1, self.rowCount()): # Insert row identifier in first column item_first = QTableWidgetItem(self.code_characters[i - 1]) item_first.setTextAlignment(Qt.AlignCenter) item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable) self.setItem(i, 0, item_first) # Insert row identifier (int) in second column text_second = str(i - 1) if i <= 10 else "" item_second = QTableWidgetItem(text_second) item_second.setTextAlignment(Qt.AlignCenter) item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable) self.setItem(i, 1, item_second) # Insert authentication-code in third column item_third = QTableWidgetItem(code) item_third.setFont(self.code_font) item_third.setTextAlignment(Qt.AlignCenter) item_third.setFlags(item_third.flags() ^ Qt.ItemIsEditable) self.setItem(selected_row_index + 1, 2, item_third) self.resizeRowToContents(selected_row_index + 1) resize_table(self, columns=False, has_headline=True) def remove_row(self, row_index): """Remove selected row. Parameters ---------- row_index : int Index of the row to remove. """ self.removeRow(row_index) # 'Decrease' row identifiers below the removed row # If first row is removed, identifier A,B,C becomes A,B (not B,C) for i in range(row_index, self.rowCount()): self.item(i, 0).setText(self.code_characters[i - 1]) text_second = str(i - 1) if i <= 10 else "" self.item(i, 1).setText(text_second) resize_table(self, columns=False, has_headline=True) def generate_authentication_numbers(self): """Generate two non-equal numbers between 1 and self.code_length. Returns ------- list Containing two integers, sorted in ascending order. """ available_numbers = list(range(1, self.code_length + 1)) numbers = [] numbers.append(choice(available_numbers)) numbers.append(choice(available_numbers)) while numbers[0] == numbers[1]: numbers[1] = choice(available_numbers) numbers.sort() return numbers @staticmethod def get_user_friendly_name(): """Get user-friendly name of module.""" return "Autentiseringstavle" @staticmethod def get_icon(): """Get icon of module.""" return QtGui.QIcon("soitool/media/authenticationboardmodule.png")
Ancestors
- CodeTableBase
- ModuleBase
- abc.ABC
- PySide2.QtWidgets.QTableWidget
- PySide2.QtWidgets.QTableView
- PySide2.QtWidgets.QAbstractItemView
- PySide2.QtWidgets.QAbstractScrollArea
- PySide2.QtWidgets.QFrame
- PySide2.QtWidgets.QWidget
- PySide2.QtCore.QObject
- PySide2.QtGui.QPaintDevice
- Shiboken.Object
Class variables
var staticMetaObject
Static methods
def get_icon()
-
Get icon of module.
Expand source code
@staticmethod def get_icon(): """Get icon of module.""" return QtGui.QIcon("soitool/media/authenticationboardmodule.png")
def get_user_friendly_name()
-
Get user-friendly name of module.
Expand source code
@staticmethod def get_user_friendly_name(): """Get user-friendly name of module.""" return "Autentiseringstavle"
Methods
def add_row(self, selected_row_index)
-
Insert row below the selected row and add data.
Parameters
selected_row_index
:int
- Index of the selected row.
Expand source code
def add_row(self, selected_row_index): """Insert row below the selected row and add data. Parameters ---------- selected_row_index : int Index of the selected row. """ # If maximum amount of rows not reached (- 1 to skip headline) if self.rowCount() - 1 < len(ROW_IDENTIFIERS): # Generate unique code and insert row code = self.generate_unique_code() self.insertRow(selected_row_index + 1) # Loop through all rows starting with the new row for i in range(selected_row_index + 1, self.rowCount()): # Insert row identifier in first column item_first = QTableWidgetItem(self.code_characters[i - 1]) item_first.setTextAlignment(Qt.AlignCenter) item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable) self.setItem(i, 0, item_first) # Insert row identifier (int) in second column text_second = str(i - 1) if i <= 10 else "" item_second = QTableWidgetItem(text_second) item_second.setTextAlignment(Qt.AlignCenter) item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable) self.setItem(i, 1, item_second) # Insert authentication-code in third column item_third = QTableWidgetItem(code) item_third.setFont(self.code_font) item_third.setTextAlignment(Qt.AlignCenter) item_third.setFlags(item_third.flags() ^ Qt.ItemIsEditable) self.setItem(selected_row_index + 1, 2, item_third) self.resizeRowToContents(selected_row_index + 1) resize_table(self, columns=False, has_headline=True)
def generate_authentication_numbers(self)
-
Generate two non-equal numbers between 1 and self.code_length.
Returns
list
- Containing two integers, sorted in ascending order.
Expand source code
def generate_authentication_numbers(self): """Generate two non-equal numbers between 1 and self.code_length. Returns ------- list Containing two integers, sorted in ascending order. """ available_numbers = list(range(1, self.code_length + 1)) numbers = [] numbers.append(choice(available_numbers)) numbers.append(choice(available_numbers)) while numbers[0] == numbers[1]: numbers[1] = choice(available_numbers) numbers.sort() return numbers
def insert_row_identifiers(self)
-
Insert values in column one and two.
Expand source code
def insert_row_identifiers(self): """Insert values in column one and two.""" for i in range(self.rowCount()): # Insert non-editable row identifier in first column item_first = QTableWidgetItem(ROW_IDENTIFIERS[i]) item_first.setTextAlignment(Qt.AlignCenter) item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable) self.setItem(i, 0, item_first) # Insert non-editable row identifier (int) in second column text_second = str(i) if i < 10 else "" item_second = QTableWidgetItem(text_second) item_second.setTextAlignment(Qt.AlignCenter) item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable) self.setItem(i, 1, item_second)
def remove_row(self, row_index)
-
Remove selected row.
Parameters
row_index
:int
- Index of the row to remove.
Expand source code
def remove_row(self, row_index): """Remove selected row. Parameters ---------- row_index : int Index of the row to remove. """ self.removeRow(row_index) # 'Decrease' row identifiers below the removed row # If first row is removed, identifier A,B,C becomes A,B (not B,C) for i in range(row_index, self.rowCount()): self.item(i, 0).setText(self.code_characters[i - 1]) text_second = str(i - 1) if i <= 10 else "" self.item(i, 1).setText(text_second) resize_table(self, columns=False, has_headline=True)
Inherited members