Skip to content

Commit 56628ec

Browse files
squash
1 parent 2668757 commit 56628ec

File tree

5 files changed

+59
-36
lines changed

5 files changed

+59
-36
lines changed

bitcoin_safe/pdf_labels.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
from __future__ import annotations
3030

31-
import logging
32-
import os
33-
from pathlib import Path
3431
from typing import Any
3532

3633
from reportlab.lib import colors
@@ -40,9 +37,7 @@
4037
from reportlab.platypus import KeepInFrame, Paragraph, Spacer, Table, TableStyle
4138

4239
from bitcoin_safe.i18n import translate
43-
from bitcoin_safe.pdfrecovery import BasePDF, white_space
44-
45-
logger = logging.getLogger(__name__)
40+
from bitcoin_safe.pdfrecovery import BasePDF, white_space, write_and_open_temp_pdf
4641

4742

4843
class PDFLabels(BasePDF):
@@ -166,12 +161,9 @@ def make_and_open_labels_pdf(wallet_id: str, label_pairs: list[tuple[str, str]],
166161
pdf_labels = PDFLabels(lang_code=lang_code)
167162
pdf_labels.add_labels(wallet_id=wallet_id, label_pairs=label_pairs)
168163

169-
filename = (
170-
translate("pdf", "Hardware signer labels for {id}", no_translate=pdf_labels.no_translate).format(
171-
id=wallet_id
172-
)
173-
+ ".pdf"
174-
)
175-
temp_file = os.path.join(Path.home(), filename)
176-
pdf_labels.save_pdf(temp_file)
177-
pdf_labels.open_pdf(temp_file)
164+
filename = translate(
165+
"pdf",
166+
"Hardware signer labels for {id}",
167+
no_translate=pdf_labels.no_translate,
168+
).format(id=wallet_id)
169+
write_and_open_temp_pdf(pdf_labels, filename)

bitcoin_safe/pdf_statement.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030

3131
import datetime
3232
import logging
33-
import os
34-
from pathlib import Path
3533
from typing import Any
3634

3735
import bdkpython as bdk
@@ -46,7 +44,7 @@
4644
from reportlab.platypus import PageBreak, Paragraph, Table, TableStyle
4745

4846
from bitcoin_safe.i18n import translate
49-
from bitcoin_safe.pdfrecovery import BasePDF, pilimage_to_reportlab, white_space
47+
from bitcoin_safe.pdfrecovery import BasePDF, pilimage_to_reportlab, white_space, write_and_open_temp_pdf
5048

5149
from .wallet import Wallet
5250

@@ -359,6 +357,4 @@ def make_and_open_pdf_statement(wallet: Wallet, lang_code: str, label_sync_nsec:
359357
label_sync_nsec=label_sync_nsec,
360358
)
361359

362-
temp_file = os.path.join(Path.home(), f"{file_title}.pdf")
363-
pdf_statement.save_pdf(temp_file)
364-
pdf_statement.open_pdf(temp_file)
360+
write_and_open_temp_pdf(pdf_statement, file_title)

bitcoin_safe/pdfrecovery.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828

2929
from __future__ import annotations
3030

31+
import atexit
3132
import io
3233
import logging
3334
import os
35+
import tempfile
3436
from dataclasses import dataclass
3537
from enum import Enum
3638
from pathlib import Path
3739
from typing import Any
3840

41+
import platformdirs
3942
from bitcoin_qr_tools.qr_generator import QRGenerator
4043
from bitcoin_usb.address_types import DescriptorInfo
4144
from PIL.Image import Image as PilImage
@@ -64,11 +67,42 @@
6467

6568
logger = logging.getLogger(__name__)
6669

70+
_TEMP_PDFS: set[Path] = set()
71+
72+
73+
def _cleanup_temp_pdfs() -> None:
74+
for path in list(_TEMP_PDFS):
75+
try:
76+
path.unlink()
77+
except FileNotFoundError:
78+
pass
79+
except PermissionError:
80+
logger.warning("Could not remove temporary PDF at %s", path)
81+
82+
83+
atexit.register(_cleanup_temp_pdfs)
84+
6785

6886
TEXT_24_WORDS = translate("pdf", "12 or 24")
6987
DEFAULT_MARGIN = 36
7088

7189

90+
def _safe_filename_prefix(filename: str) -> str:
91+
return "".join(char if char.isalnum() or char in {"-", "_"} else "_" for char in filename)
92+
93+
94+
def write_and_open_temp_pdf(pdf: BasePDF, filename: str) -> None:
95+
"""Write a PDF to the user cache directory and open it with the OS."""
96+
safe_prefix = _safe_filename_prefix(filename)
97+
cache_dir = Path(platformdirs.user_cache_dir("bitcoin_safe"))
98+
cache_dir.mkdir(parents=True, exist_ok=True)
99+
temp_fd, temp_file = tempfile.mkstemp(prefix=f"{safe_prefix}-", suffix=".pdf", dir=cache_dir)
100+
os.close(temp_fd)
101+
pdf.save_pdf(temp_file)
102+
pdf.open_pdf(temp_file)
103+
_TEMP_PDFS.add(Path(temp_file))
104+
105+
72106
def pilimage_to_reportlab(pilimage: PilImage, width=200, height=200) -> Image:
73107
"""Pilimage to reportlab."""
74108
buffer = io.BytesIO()
@@ -602,8 +636,5 @@ def make_and_open_pdf(wallet: Wallet, lang_code: str) -> None:
602636
keystore_label=keystore.label,
603637
)
604638
pdf_recovery.add_page_break()
605-
temp_file = os.path.join(
606-
Path.home(), translate("pdf", "Seed backup of {id}").format(id=wallet.id) + ".pdf"
607-
)
608-
pdf_recovery.save_pdf(temp_file)
609-
pdf_recovery.open_pdf(temp_file)
639+
filename = translate("pdf", "Seed backup of {id}").format(id=wallet.id)
640+
write_and_open_temp_pdf(pdf_recovery, filename)

tests/gui/qt/test_setup_wallet.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030

3131
import inspect
3232
import logging
33-
import os
3433
from datetime import datetime
3534
from pathlib import Path
3635
from unittest.mock import patch
3736

3837
import bdkpython as bdk
38+
import platformdirs
3939
import pytest
4040
from bitcoin_safe_lib.gui.qt.satoshis import Satoshis
4141
from bitcoin_safe_lib.util import insert_invisible_spaces_for_wordwrap
@@ -321,10 +321,12 @@ def page_backup() -> None:
321321
step.custom_yes_button.click()
322322
mock_open.assert_called_once()
323323

324-
temp_file = os.path.join(Path.home(), f"Seed backup of {wallet_name}.pdf")
325-
assert Path(temp_file).exists()
326-
# remove the file again
327-
Path(temp_file).unlink()
324+
cache_dir = Path(platformdirs.user_cache_dir("bitcoin_safe"))
325+
prefix = f"Seed backup of {wallet_name}".replace(" ", "_")
326+
temp_files = list(cache_dir.glob(f"{prefix}-*.pdf"))
327+
assert temp_files
328+
for temp_file in temp_files:
329+
temp_file.unlink()
328330

329331
page_backup()
330332

tests/gui/qt/test_wallet_features.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030

3131
import inspect
3232
import logging
33-
import os
3433
import tempfile
3534
from datetime import datetime
3635
from pathlib import Path
3736
from unittest.mock import patch
3837

3938
import bdkpython as bdk
39+
import platformdirs
4040
import pytest
4141
from bitcoin_qr_tools.gui.bitcoin_video_widget import BitcoinVideoWidget
4242
from bitcoin_usb.address_types import AddressTypes
@@ -291,10 +291,12 @@ def menu_action_export_pdf() -> None:
291291

292292
mock_open.assert_called_once()
293293

294-
temp_file = os.path.join(Path.home(), f"Seed backup of {wallet_name}.pdf")
295-
assert Path(temp_file).exists()
296-
# remove the file again
297-
Path(temp_file).unlink()
294+
cache_dir = Path(platformdirs.user_cache_dir("bitcoin_safe"))
295+
prefix = f"Seed backup of {wallet_name}".replace(" ", "_")
296+
temp_files = list(cache_dir.glob(f"{prefix}-*.pdf"))
297+
assert temp_files
298+
for temp_file in temp_files:
299+
temp_file.unlink()
298300

299301
menu_action_export_pdf()
300302

0 commit comments

Comments
 (0)