diff --git a/soitool/codebook.py b/soitool/codebook.py index b1a5f3cc0f9cabfac71cc59bc8f62abf120d29c5..84c3ccfcbcfaa12d3e605b55aa7f82eed97c5132 100644 --- a/soitool/codebook.py +++ b/soitool/codebook.py @@ -1,4 +1,4 @@ -"""Codebook. +"""GUI-interface towards database-table 'CodeBook'. Contains functionality for viewing, editing and inserting new rows in the database-table 'CodeBook'. @@ -6,7 +6,6 @@ in the database-table 'CodeBook'. from PySide2.QtWidgets import QTableView from PySide2.QtSql import QSqlDatabase, QSqlTableModel from PySide2.QtCore import Qt -from soitool.database import DBPATH # , Database from soitool.style import CODEBOOK_HEADER_FONT, CODEBOOK_HEADER_BACKGROUND_CSS # Name and type of database @@ -17,17 +16,19 @@ DBTYPE = "QSQLITE" class CodeBookTableView(QTableView): """TableView with a model of the 'codebook'-table from database. - This modified QTableView creates a CodeBookTableModel, - which reads the codebook-table. - User can add, edit and insert entries to the database through this View. + This modified QTableView creates a CodeBookTableModel, which reads the + codebook-table. User can add, edit, delete and insert entries through this + view. + Parameter 'database' should be an instance of soitool.database.Database, + and is used to create a QSqlDatabase from the database-file. Raises RuntimeError if database does not open. """ - def __init__(self): + def __init__(self, database): super().__init__() db = QSqlDatabase.addDatabase(DBTYPE, CONNAME) - db.setDatabaseName(DBPATH) + db.setDatabaseName(database.db_path) if not db.open(): raise RuntimeError("Could not open database.") diff --git a/soitool/codebook_to_pdf.py b/soitool/codebook_to_pdf.py index 7d090539a86b35ed5eb5600c67a8cc52b07e155b..0fe35b87c2f5c31400432166fc17402975f2e95d 100644 --- a/soitool/codebook_to_pdf.py +++ b/soitool/codebook_to_pdf.py @@ -14,7 +14,6 @@ from reportlab.lib.styles import ParagraphStyle from reportlab.lib import colors from reportlab.lib.pagesizes import A4, portrait from reportlab.lib.units import cm -from soitool.database import Database from soitool.enumerates import CodebookSort A4_WIDTH, A4_HEIGHT = A4 @@ -53,11 +52,15 @@ TABLE_STYLE = TableStyle( ) -def generate_codebook_pdf(small=False, page_size=A4, orientation=portrait): +def generate_codebook_pdf( + database, small=False, page_size=A4, orientation=portrait +): """Generate PDF with data from database-table 'CodeBook'. Parameters ---------- + database : soitool.database.Database + Reference to database-instance small : bool, optional Data is from full codebook if False (default), from small codebook if True. @@ -75,7 +78,7 @@ def generate_codebook_pdf(small=False, page_size=A4, orientation=portrait): title_decode = Paragraph(TITLE_FULL_DECODE, TITLE_STYLE) # Get data from database - data_code, data_decode = get_codebook_data(small) + data_code, data_decode = get_codebook_data(database, small) # Create Tables with data sorted by Word/Code and set predefined style table_code = Table(data_code, repeatRows=1) @@ -130,11 +133,13 @@ def generate_filename(small=False): return f"Kodebok_{today}.pdf" -def get_codebook_data(small=False): +def get_codebook_data(database, small=False): """Read and format codebook-data from database sorted by Word and Code. Parameters ---------- + database : soitool.database.Database + Reference to database-instance small : bool Retrieves full codebook if False (default), small codebook if True. @@ -145,9 +150,8 @@ def get_codebook_data(small=False): the second list is a decodebook (sorted by Code). """ # Get data from CodeBook-table - db = Database() - db_data_code = db.get_codebook(small, sort=CodebookSort.WORD) - db_data_decode = db.get_codebook(small, sort=CodebookSort.CODE) + db_data_code = database.get_codebook(small, sort=CodebookSort.WORD) + db_data_decode = database.get_codebook(small, sort=CodebookSort.CODE) # Lists to append column-headers and formatted data data_code = [] diff --git a/soitool/database.py b/soitool/database.py index 71d799ef000684cb94a2330b4b060a987199faa6..8814aef0d69db18be92b59f012b8e761ca073848 100644 --- a/soitool/database.py +++ b/soitool/database.py @@ -6,7 +6,7 @@ from datetime import datetime import soitool.coder from soitool.enumerates import CodebookSort -# Set name and path to (future) database +# Set name and path to default (, future) database DBNAME = "database" CURDIR = os.path.dirname(__file__) DBPATH = os.path.join(CURDIR, DBNAME) @@ -31,18 +31,20 @@ LASTUPDATED = "CREATE TABLE LastUpdated(Timestamp DATETIME PRIMARY KEY)" class Database: - """ - Holds database-connection and related functions. + """Holds database-connection and related functions. Connects to existing db if found, creates new db if not. If db is created, tables are created and filled. + Uses default database unless parameter 'db_path' is given. Holds a QTimer that requests an update of CodeBook on every timeout. """ def __init__(self, db_path=DBPATH): - db_exists = os.path.exists(db_path) + self.db_path = db_path + + db_exists = os.path.exists(self.db_path) if db_exists: print("Connecting to existing DB.") diff --git a/soitool/main_window.py b/soitool/main_window.py index bf2fb3d706c30a3cbeebb7c25d9c9498d6db86e0..aac45496be4a7cfd317d77fee564dd27d09f4dfb 100644 --- a/soitool/main_window.py +++ b/soitool/main_window.py @@ -42,15 +42,15 @@ class MainWindow(QMainWindow): self.statusBar() # Database instance - database = Database() + self.database = Database() # Timer for automatic update of codes in CodeBook self.timer = QTimer() # Interval i set to msec since last 24h update self.timer.setInterval( - database.seconds_to_next_update(60 * 60 * 24) * 1000 + self.database.seconds_to_next_update(60 * 60 * 24) * 1000 ) self.timer.timeout.connect( - lambda: database.update_codebook_auto(self.timer) + lambda: self.database.update_codebook_auto(self.timer) ) self.timer.start() @@ -114,14 +114,16 @@ class MainWindow(QMainWindow): # Export full codebook export_codebook_full = QAction("Stor kodebok", self) export_codebook_full.setStatusTip("Eksporter stor kodebok som PDF") - export_codebook_full.triggered.connect(generate_codebook_pdf) + export_codebook_full.triggered.connect( + partial(generate_codebook_pdf, database=self.database) + ) export_codebook.addAction(export_codebook_full) # Export small codebook export_codebook_small = QAction("Liten kodebok", self) export_codebook_small.setStatusTip("Eksporter liten kodebok som PDF") export_codebook_small.triggered.connect( - partial(generate_codebook_pdf, small=True) + partial(generate_codebook_pdf, database=self.database, small=True) ) export_codebook.addAction(export_codebook_small) @@ -164,7 +166,7 @@ class MainWindow(QMainWindow): else: # Create widgets tab = QWidget() - view = CodeBookTableView() + view = CodeBookTableView(self.database) row_adder = CodebookRowAdder(view) # Add widgets to layouts diff --git a/test/test_codebook_to_pdf.py b/test/test_codebook_to_pdf.py index 5aa94bee06349f604c97f6065d7c10d0dc8112ab..fa553e016cba32106e2803c48c3455efc166fc98 100644 --- a/test/test_codebook_to_pdf.py +++ b/test/test_codebook_to_pdf.py @@ -5,6 +5,8 @@ from functools import partial from pathlib import Path from datetime import datetime from soitool import codebook_to_pdf +from soitool.database import Database +from test.test_database import TESTDBPATH SOITOOL_ROOT_PATH = Path(__file__).parent.parent @@ -29,15 +31,20 @@ class ExportTest(unittest.TestCase): def test_generate_codebook_pdf(self): """Test generated PDF-file exist.""" + + self.database = Database(TESTDBPATH) + # Test full codebook (default) - codebook_to_pdf.generate_codebook_pdf() + codebook_to_pdf.generate_codebook_pdf(database=self.database) file_name = codebook_to_pdf.generate_filename(small=False) file_path_full = os.path.join(SOITOOL_ROOT_PATH, file_name) # Assert file exists self.assertTrue(os.path.exists(file_path_full)) # Test small codebook - codebook_to_pdf.generate_codebook_pdf(small=True) + codebook_to_pdf.generate_codebook_pdf( + database=self.database, small=True + ) file_name = codebook_to_pdf.generate_filename(small=True) file_path_small = os.path.join(SOITOOL_ROOT_PATH, file_name) # Assert file exists