bouquin 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bouquin might be problematic. Click here for more details.

bouquin/db.py CHANGED
@@ -64,6 +64,25 @@ class DBManager:
64
64
  cur.execute("PRAGMA user_version = 1;")
65
65
  self.conn.commit()
66
66
 
67
+ def rekey(self, new_key: str) -> None:
68
+ """
69
+ Change the SQLCipher passphrase in-place, then reopen the connection
70
+ with the new key to verify.
71
+ """
72
+ if self.conn is None:
73
+ raise RuntimeError("Database is not connected")
74
+ cur = self.conn.cursor()
75
+ # Change the encryption key of the currently open database
76
+ cur.execute(f"PRAGMA rekey = '{new_key}';")
77
+ self.conn.commit()
78
+
79
+ # Close and reopen with the new key to verify and restore PRAGMAs
80
+ self.conn.close()
81
+ self.conn = None
82
+ self.cfg.key = new_key
83
+ if not self.connect():
84
+ raise sqlite.Error("Re-open failed after rekey")
85
+
67
86
  def get_entry(self, date_iso: str) -> str:
68
87
  cur = self.conn.cursor()
69
88
  cur.execute("SELECT content FROM entries WHERE date = ?;", (date_iso,))
bouquin/main_window.py CHANGED
@@ -72,7 +72,8 @@ class MainWindow(QMainWindow):
72
72
  act_save.setShortcut("Ctrl+S")
73
73
  act_save.triggered.connect(lambda: self._save_current(explicit=True))
74
74
  file_menu.addAction(act_save)
75
- act_settings = QAction("&Settings", self)
75
+ act_settings = QAction("S&ettings", self)
76
+ act_save.setShortcut("Ctrl+E")
76
77
  act_settings.triggered.connect(self._open_settings)
77
78
  file_menu.addAction(act_settings)
78
79
  file_menu.addSeparator()
@@ -97,6 +98,13 @@ class MainWindow(QMainWindow):
97
98
  nav_menu.addAction(act_next)
98
99
  self.addAction(act_next)
99
100
 
101
+ act_today = QAction("Today", self)
102
+ act_today.setShortcut("Ctrl+T")
103
+ act_today.setShortcutContext(Qt.ApplicationShortcut)
104
+ act_today.triggered.connect(self._adjust_today)
105
+ nav_menu.addAction(act_today)
106
+ self.addAction(act_today)
107
+
100
108
  # Autosave
101
109
  self._dirty = False
102
110
  self._save_timer = QTimer(self)
@@ -176,6 +184,11 @@ class MainWindow(QMainWindow):
176
184
  d = self.calendar.selectedDate().addDays(delta)
177
185
  self.calendar.setSelectedDate(d)
178
186
 
187
+ def _adjust_today(self):
188
+ """Jump to today."""
189
+ today = QDate.currentDate()
190
+ self.calendar.setSelectedDate(today)
191
+
179
192
  def _on_date_changed(self):
180
193
  """
181
194
  When the calendar selection changes, save the previous day's note if dirty,
@@ -219,7 +232,7 @@ class MainWindow(QMainWindow):
219
232
  self._save_date(self._current_date_iso(), explicit)
220
233
 
221
234
  def _open_settings(self):
222
- dlg = SettingsDialog(self.cfg, self)
235
+ dlg = SettingsDialog(self.cfg, self.db, self)
223
236
  if dlg.exec() == QDialog.Accepted:
224
237
  new_cfg = dlg.config
225
238
  if new_cfg.path != self.cfg.path:
@@ -13,17 +13,20 @@ from PySide6.QtWidgets import (
13
13
  QFileDialog,
14
14
  QDialogButtonBox,
15
15
  QSizePolicy,
16
+ QMessageBox,
16
17
  )
17
18
 
18
- from .db import DBConfig
19
+ from .db import DBConfig, DBManager
19
20
  from .settings import save_db_config
21
+ from .key_prompt import KeyPrompt
20
22
 
21
23
 
22
24
  class SettingsDialog(QDialog):
23
- def __init__(self, cfg: DBConfig, parent=None):
25
+ def __init__(self, cfg: DBConfig, db: DBManager, parent=None):
24
26
  super().__init__(parent)
25
27
  self.setWindowTitle("Settings")
26
28
  self._cfg = DBConfig(path=cfg.path, key="")
29
+ self._db = db
27
30
 
28
31
  form = QFormLayout()
29
32
  form.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
@@ -44,12 +47,17 @@ class SettingsDialog(QDialog):
44
47
  h.setStretch(1, 0)
45
48
  form.addRow("Database path", path_row)
46
49
 
50
+ # Change key button
51
+ self.rekey_btn = QPushButton("Change key")
52
+ self.rekey_btn.clicked.connect(self._change_key)
53
+
47
54
  bb = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel)
48
55
  bb.accepted.connect(self._save)
49
56
  bb.rejected.connect(self.reject)
50
57
 
51
58
  v = QVBoxLayout(self)
52
59
  v.addLayout(form)
60
+ v.addWidget(self.rekey_btn)
53
61
  v.addWidget(bb)
54
62
 
55
63
  def _browse(self):
@@ -67,6 +75,26 @@ class SettingsDialog(QDialog):
67
75
  save_db_config(self._cfg)
68
76
  self.accept()
69
77
 
78
+ def _change_key(self):
79
+ p1 = KeyPrompt(self, title="Change key", message="Enter new key")
80
+ if p1.exec() != QDialog.Accepted:
81
+ return
82
+ new_key = p1.key()
83
+ p2 = KeyPrompt(self, title="Change key", message="Re-enter new key")
84
+ if p2.exec() != QDialog.Accepted:
85
+ return
86
+ if new_key != p2.key():
87
+ QMessageBox.warning(self, "Key mismatch", "The two entries did not match.")
88
+ return
89
+ if not new_key:
90
+ QMessageBox.warning(self, "Empty key", "Key cannot be empty.")
91
+ return
92
+ try:
93
+ self._db.rekey(new_key)
94
+ QMessageBox.information(self, "Key changed", "The database key was updated.")
95
+ except Exception as e:
96
+ QMessageBox.critical(self, "Error", f"Could not change key:\n{e}")
97
+
70
98
  @property
71
99
  def config(self) -> DBConfig:
72
100
  return self._cfg
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bouquin
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher.
5
5
  License: GPL-3.0-or-later
6
6
  Author: Miguel Jacq
@@ -49,7 +49,6 @@ There is deliberately no network connectivity or syncing intended.
49
49
 
50
50
  * Search
51
51
  * Taxonomy/tagging
52
- * Ability to change the SQLCipher key
53
52
  * Export to other formats (plaintext, json, sql etc)
54
53
 
55
54
 
@@ -0,0 +1,14 @@
1
+ bouquin/__init__.py,sha256=-bBNFYOq80A2Egtpo5V5zWJtYOxQfRZFQ_feve5lkFU,23
2
+ bouquin/__main__.py,sha256=Vdhw8YA1K3wPMlbJQYL5WqvRzAKVeZ16mZQFO9VRmCo,62
3
+ bouquin/db.py,sha256=-RCWeStZD-eZ2TEUaUTj67cBvq30q2aiSmLoP-K67Jk,3396
4
+ bouquin/highlighter.py,sha256=UPP4G4jdN7U8y1c3nk9zTswkHHJw0Tpl3PX6obZrSG0,4077
5
+ bouquin/key_prompt.py,sha256=RNrW0bN4xnwDGeBlgbmFaBSs_2iQyYrBYpKOQhe4E0c,1092
6
+ bouquin/main.py,sha256=tx59cJZnGgHQ1UHQbdlYgaC36_L0ulyKaOoy6oURXVA,348
7
+ bouquin/main_window.py,sha256=OQQ1BhPp3F3ULVrtjeTsKTraZZDzRECjYCORrRpWmis,9291
8
+ bouquin/settings.py,sha256=bJYQXbTqX_r_DfOKuGnah6IVZLiNwZAuBuz2OgdhA_E,670
9
+ bouquin/settings_dialog.py,sha256=NA40-RvXvM8SND-o5K6b-yKMrShY6NQnQuDAxUoCzyI,3120
10
+ bouquin-0.1.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
11
+ bouquin-0.1.1.dist-info/METADATA,sha256=j1CnzeNbB-bzfHaXN9rS66RDaG3-q4Ic6erwzKjqxBw,2148
12
+ bouquin-0.1.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
13
+ bouquin-0.1.1.dist-info/entry_points.txt,sha256=d2C5Mc85suj1vWg_mmcfFuEBAYEkdwhZquusme5EWuQ,49
14
+ bouquin-0.1.1.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- bouquin/__init__.py,sha256=-bBNFYOq80A2Egtpo5V5zWJtYOxQfRZFQ_feve5lkFU,23
2
- bouquin/__main__.py,sha256=Vdhw8YA1K3wPMlbJQYL5WqvRzAKVeZ16mZQFO9VRmCo,62
3
- bouquin/db.py,sha256=0fCr--ko-StUMRPG96Nwzotq7a7xz1-9ZlmaEKs_2PA,2697
4
- bouquin/highlighter.py,sha256=UPP4G4jdN7U8y1c3nk9zTswkHHJw0Tpl3PX6obZrSG0,4077
5
- bouquin/key_prompt.py,sha256=RNrW0bN4xnwDGeBlgbmFaBSs_2iQyYrBYpKOQhe4E0c,1092
6
- bouquin/main.py,sha256=tx59cJZnGgHQ1UHQbdlYgaC36_L0ulyKaOoy6oURXVA,348
7
- bouquin/main_window.py,sha256=qWDM1ZJcPRHsX8oju_TaoLmBLGAwkaLcUIf44wSRLEQ,8830
8
- bouquin/settings.py,sha256=bJYQXbTqX_r_DfOKuGnah6IVZLiNwZAuBuz2OgdhA_E,670
9
- bouquin/settings_dialog.py,sha256=XW7SFg3_bD4rGj9D3jA65j7Jvq6049CxvRilfcGCKDU,2014
10
- bouquin-0.1.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
11
- bouquin-0.1.0.dist-info/METADATA,sha256=SFda5ee4tRfifEa10WNRbMG9uIhK5IrB1Pz4TbobBNI,2187
12
- bouquin-0.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
13
- bouquin-0.1.0.dist-info/entry_points.txt,sha256=d2C5Mc85suj1vWg_mmcfFuEBAYEkdwhZquusme5EWuQ,49
14
- bouquin-0.1.0.dist-info/RECORD,,