Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 7 additions & 15 deletions bitcoin_safe/pdf_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@

from __future__ import annotations

import logging
import os
from pathlib import Path
from typing import Any

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

from bitcoin_safe.i18n import translate
from bitcoin_safe.pdfrecovery import BasePDF, white_space

logger = logging.getLogger(__name__)
from bitcoin_safe.pdfrecovery import BasePDF, white_space, write_and_open_temp_pdf


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

filename = (
translate("pdf", "Hardware signer labels for {id}", no_translate=pdf_labels.no_translate).format(
id=wallet_id
)
+ ".pdf"
)
temp_file = os.path.join(Path.home(), filename)
pdf_labels.save_pdf(temp_file)
pdf_labels.open_pdf(temp_file)
filename = translate(
"pdf",
"Hardware signer labels for {id}",
no_translate=pdf_labels.no_translate,
).format(id=wallet_id)
write_and_open_temp_pdf(pdf_labels, filename)
8 changes: 2 additions & 6 deletions bitcoin_safe/pdf_statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@

import datetime
import logging
import os
from pathlib import Path
from typing import Any

import bdkpython as bdk
Expand All @@ -46,7 +44,7 @@
from reportlab.platypus import PageBreak, Paragraph, Table, TableStyle

from bitcoin_safe.i18n import translate
from bitcoin_safe.pdfrecovery import BasePDF, pilimage_to_reportlab, white_space
from bitcoin_safe.pdfrecovery import BasePDF, pilimage_to_reportlab, white_space, write_and_open_temp_pdf

from .wallet import Wallet

Expand Down Expand Up @@ -359,6 +357,4 @@ def make_and_open_pdf_statement(wallet: Wallet, lang_code: str, label_sync_nsec:
label_sync_nsec=label_sync_nsec,
)

temp_file = os.path.join(Path.home(), f"{file_title}.pdf")
pdf_statement.save_pdf(temp_file)
pdf_statement.open_pdf(temp_file)
write_and_open_temp_pdf(pdf_statement, file_title)
41 changes: 36 additions & 5 deletions bitcoin_safe/pdfrecovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@

from __future__ import annotations

import atexit
import io
import logging
import os
import tempfile
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import Any

import platformdirs
from bitcoin_qr_tools.qr_generator import QRGenerator
from bitcoin_usb.address_types import DescriptorInfo
from PIL.Image import Image as PilImage
Expand Down Expand Up @@ -64,11 +67,42 @@

logger = logging.getLogger(__name__)

_TEMP_PDFS: set[Path] = set()


def _cleanup_temp_pdfs() -> None:
for path in list(_TEMP_PDFS):
try:
path.unlink()
except FileNotFoundError:
pass
except PermissionError:
logger.warning("Could not remove temporary PDF at %s", path)


atexit.register(_cleanup_temp_pdfs)


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


def _safe_filename_prefix(filename: str) -> str:
return "".join(char if char.isalnum() or char in {"-", "_"} else "_" for char in filename)


def write_and_open_temp_pdf(pdf: BasePDF, filename: str) -> None:
"""Write a PDF to the user cache directory and open it with the OS."""
safe_prefix = _safe_filename_prefix(filename)
cache_dir = Path(platformdirs.user_cache_dir("bitcoin_safe"))
cache_dir.mkdir(parents=True, exist_ok=True)
temp_fd, temp_file = tempfile.mkstemp(prefix=f"{safe_prefix}-", suffix=".pdf", dir=cache_dir)
os.close(temp_fd)
pdf.save_pdf(temp_file)
pdf.open_pdf(temp_file)
_TEMP_PDFS.add(Path(temp_file))


def pilimage_to_reportlab(pilimage: PilImage, width=200, height=200) -> Image:
"""Pilimage to reportlab."""
buffer = io.BytesIO()
Expand Down Expand Up @@ -602,8 +636,5 @@ def make_and_open_pdf(wallet: Wallet, lang_code: str) -> None:
keystore_label=keystore.label,
)
pdf_recovery.add_page_break()
temp_file = os.path.join(
Path.home(), translate("pdf", "Seed backup of {id}").format(id=wallet.id) + ".pdf"
)
pdf_recovery.save_pdf(temp_file)
pdf_recovery.open_pdf(temp_file)
filename = translate("pdf", "Seed backup of {id}").format(id=wallet.id)
write_and_open_temp_pdf(pdf_recovery, filename)
12 changes: 7 additions & 5 deletions tests/gui/qt/test_setup_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@

import inspect
import logging
import os
from datetime import datetime
from pathlib import Path
from unittest.mock import patch

import bdkpython as bdk
import platformdirs
import pytest
from bitcoin_safe_lib.gui.qt.satoshis import Satoshis
from bitcoin_safe_lib.util import insert_invisible_spaces_for_wordwrap
Expand Down Expand Up @@ -321,10 +321,12 @@ def page_backup() -> None:
step.custom_yes_button.click()
mock_open.assert_called_once()

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

page_backup()

Expand Down
12 changes: 7 additions & 5 deletions tests/gui/qt/test_wallet_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@

import inspect
import logging
import os
import platform
import tempfile
from datetime import datetime
from pathlib import Path
from unittest.mock import patch

import bdkpython as bdk
import platformdirs
import pytest
from bitcoin_qr_tools.gui.bitcoin_video_widget import BitcoinVideoWidget
from bitcoin_usb.address_types import AddressTypes
Expand Down Expand Up @@ -293,10 +293,12 @@ def menu_action_export_pdf() -> None:

mock_open.assert_called_once()

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

menu_action_export_pdf()

Expand Down
Loading