def get_type_by_title(self, title: str) -> models.NotebookType: """Return type with given title from the database. Args: title: A notebook type's title. Raises: db.Error: An error occured executing the query. """ type_ = models.NotebookType('', 0, 0) connection = None try: connection = self._connect() cursor = connection.execute(const.SQL_GET_TYPE_BY_TITLE, (title, )) row = cursor.fetchone() if row: type_ = self._make_type_from_row(row) except sqlite3.Error as exception: self._handle_error('Failed to get notebook type from database', exception) finally: if connection: connection.close() return type_
def test_scan_paired_pages(self): type_ = models.NotebookType('', 160, 200) type_.pages_paired = True notebook = models.Notebook('', type_, '') pages_queue = collections.deque() pages_queue.extend([1, 2, 3]) scanner_ = scanner.Scanner(self.conf, self.callback) scanner_.scan(notebook, pages_queue) self.callback.on_start.assert_called_once_with('device', [1, 2, 3]) self.callback.on_start_scan_page.assert_has_calls([ mock.call(1), mock.call(2), mock.call(3), ]) page_width_pt = math.ceil(type_.page_width * 150 / 25.4) page_height_pt = math.ceil(type_.page_height * 150 / 25.4) self.image = self.image.crop((0, 0, page_width_pt, page_height_pt)) self.callback.on_finish_scan_page.assert_has_calls([ mock.call(notebook, 1, self.image), mock.call(notebook, 2, self.image), mock.call(notebook, 3, self.image), ]) self.assertEqual(notebook.total_pages, 3)
def _create_type(self): """Asks for the information about new type and saves it in database.""" validator = validators.TypeValidator(self._db) answers = self._view.ask_for_new_type_info(validator) if not answers: log.info('Type creation stopped due to keyboard interrupt') self._view.show_info('Nothing created.') return type_ = models.NotebookType(answers['title'], answers['page_width'], answers['page_height']) type_.pages_paired = answers['pages_paired'] try: self._db.save_type(type_) except db.Error as exception: self.exit_with_error(exception) message = (f"Created type '{type_.title}' " f"{type_.page_width}x{type_.page_height}mm") if type_.pages_paired: message += " with paired pages" self._view.show_info(f'{message}.') log.info(message)
def setUp(self): self.setUpPyfakefs() logging.disable() type_ = models.NotebookType('A4', 210, 297) path = pathlib.Path('/test/notebook.pdf') self.notebook = models.Notebook('notebook', type_, path) self.fs.create_file(str(self.notebook.path)) self.pages_dir = pathlib.Path('~/.local/share/smth/pages').expanduser() self.fs.create_dir(str(self.pages_dir / self.notebook.title)) untitled_notebook = models.Notebook('Untitled', None, None) self.db = mock.MagicMock(**{ 'get_notebook_titles.return_value': [self.notebook.title], 'get_notebook_by_title.return_value': self.notebook, 'get_notebook_by_path.return_value': untitled_notebook, 'notebook_exists.return_value': False, }) self.view = mock.MagicMock(**{ 'ask_for_notebook.return_value': self.notebook.title, }) self.args = mock.MagicMock()
def get_type_by_id(self, id_: int) -> models.NotebookType: """Return notebook type with specified id from database. Args: id_: A notebook type's ID. Raises: db.Error: An error occured executing the query. """ type_ = models.NotebookType('', 0, 0) connection = None try: connection = self._connect() cursor = connection.execute(const.SQL_GET_TYPE_BY_ID, (id_, )) row = cursor.fetchone() if row: type_ = self._make_type_from_row(row) except sqlite3.Error as exception: self._handle_error('Failed to get notebook type from database', exception) finally: if connection: connection.close() return type_
def get_notebook_by_title(self, title: str) -> models.Notebook: """Return notebook with specific title from database. Args: title: A title of a notebook. Raises: db.Error: An error occured executing the query. """ notebook = models.Notebook('', models.NotebookType('', 0, 0), pathlib.Path()) connection = None try: connection = self._connect() cursor = connection.execute(const.SQL_GET_NOTEBOOK_BY_TITLE, (title, )) row = cursor.fetchone() if row: notebook = self._make_notebook_from_row(row) except (sqlite3.Error, Error) as exception: self._handle_error('Failed to get notebook from database', exception) finally: if connection: connection.close() return notebook
def test_scan_nothing_to_scan(self): scanner_ = scanner.Scanner(self.conf, self.callback) notebook = models.Notebook('', models.NotebookType('', 0, 0), '') pages_queue = collections.deque() scanner_.scan(notebook, pages_queue) sane.scan.assert_not_called() self.callback.on_error.assert_called_once()
def setUp(self): logging.disable() type_ = models.NotebookType('A4', 210, 297) self.notebook = models.Notebook('Notebook', type_, '/test/path.pdf') self.notebook.total_pages = 3 self.db = mock.MagicMock( **{ 'get_notebook_titles.return_value': [self.notebook.title], 'get_notebook_by_title.return_value': self.notebook, }) self.scan_prefs = { 'device': 'device', 'notebook': self.notebook.title, 'append': '3' } self.view = mock.MagicMock( **{ 'ask_for_notebook.return_value': self.notebook.title, 'ask_for_pages_to_append.return_value': 3, 'ask_for_pages_to_replace.return_value': ['1', '2', '3-4'], }) self.args = mock.MagicMock(**{ 'pdf_only': False, 'set_device': False, }) self.conf = mock.MagicMock(**{ 'scanner_device': None, 'scanner_delay': 0, }) config_patcher = mock.patch('smth.config.Config') config_patcher.start().return_value = self.conf self.addCleanup(config_patcher.stop) self.pdf = mock.MagicMock() fpdf_patcher = mock.patch('fpdf.FPDF') fpdf_patcher.start().return_value = self.pdf self.addCleanup(fpdf_patcher.stop) self.image = mock.MagicMock(size=(100, 200)) self.scanner = mock.MagicMock(**{'scan.return_value': self.image}) sane.init = mock.MagicMock() devices = [ ('pixma:04A9176D_3EBCC9', 'vendor', 'mode', 'scanner device'), ] sane.get_devices = mock.MagicMock(return_value=devices) sane.open = mock.MagicMock(return_value=self.scanner)
def test_title(self): type_ = models.NotebookType('', 100, 200) self.assertEqual(type_.title, 'Untitled') type_.title = 'Test' self.assertEqual(type_.title, 'Test') type_.title = None self.assertEqual(type_.title, 'Untitled')
def test_scan_keyboard_interrupt(self): sane.open.side_effect = KeyboardInterrupt scanner_ = scanner.Scanner(self.conf, self.callback) notebook = models.Notebook('', models.NotebookType('', 0, 0), '') pages_queue = collections.deque() scanner_.scan(notebook, pages_queue) sane.scan.assert_not_called() self.callback.on_error.assert_called_once() sane.exit.assert_called_once()
def test_on_finish(self): type_ = models.NotebookType('', 160, 200) notebook = models.Notebook('', type_, pathlib.Path('/test/path.pdf')) notebook.total_pages = 3 with mock.patch('importlib.util.find_spec') as find_spec: find_spec.return_value = None self.callback.on_finish(notebook) self.db.save_notebook.assert_called_once() self.assertEqual(self.pdf.add_page.call_count, 3) self.assertTrue(notebook.path.exists())
def setUp(self): self.db = db.DB(self.DB_PATH) # Types for tests self.types = self.db.get_types() type1 = models.NotebookType('Type 1', 100, 200) type2 = models.NotebookType('Type 2', 200, 100) type2.pages_paired = True self.types.append(type1) self.types.append(type2) for type_ in self.types: self.db.save_type(type_) # Notebooks for tests notebook1 = models.Notebook('Notebook 1', type1, '/test/notebook1.pdf') notebook2 = models.Notebook('Notebook 2', type2, '/test/notebook2.pdf') notebook2.total_pages = 10 notebook2.first_page_number = 0 notebook3 = models.Notebook('Notebook 3', type1, '/test/notebook3.pdf') notebook3.first_page_number = 2 self.notebooks = [notebook1, notebook2, notebook3] for notebook in self.notebooks: self.db.save_notebook(notebook)
def test_on_finish_missing_images(self): """Should create PDF but show errors.""" self.pdf.image.side_effect = RuntimeError type_ = models.NotebookType('', 160, 200) notebook = models.Notebook('', type_, pathlib.Path('/test/path.pdf')) notebook.total_pages = 3 with mock.patch('importlib.util.find_spec') as find_spec: find_spec.return_value = None self.callback.on_finish(notebook) self.db.save_notebook.assert_called_once() self.assertEqual(self.pdf.add_page.call_count, 3) self.assertEqual(self.view.show_error.call_count, 3) self.assertTrue(notebook.path.exists())
def __init__(self, path='smth.db'): """Create tables and the default notebook type if necessary. The default notebook type is of A4 format in portrait orientation. """ self._path = path connection = None try: connection = self._connect() cursor = connection.execute(const.SQL_TABLE_EXISTS, ('notebook_type', )) table_exists = cursor.fetchone()[0] > 0 if not table_exists: connection.execute(const.SQL_CREATE_TABLE_NOTEBOOK_TYPE) log.info("Table 'notebook_type' created") type_a4 = models.NotebookType('A4', 210, 297) self.save_type(type_a4) log.info("Type 'A4' created") cursor = connection.execute(const.SQL_TABLE_EXISTS, ('notebook', )) table_exists = cursor.fetchone()[0] > 0 if not table_exists: connection.execute(const.SQL_CREATE_TABLE_NOTEBOOK) log.info("Table 'notebook' created") connection.commit() except sqlite3.Error as exception: self._handle_error('Failed to initialize the database', exception) finally: if connection: connection.close()
def setUp(self): self.type = models.NotebookType('', 100, 200) self.notebook = models.Notebook('', self.type, '') self.resolution = 150
def setUp(self): self.type_ = models.NotebookType('Test', 100, 200)
def _make_type_from_row(self, row: sqlite3.Row) -> models.NotebookType: # pylint: disable=no-self-use # noqa: E501 type_ = models.NotebookType(row['title'], row['page_width'], row['page_height']) type_.id = row['id'] type_.pages_paired = row['pages_paired'] > 0 return type_