Skip to content

Commit 52fb5a6

Browse files
ask for file overwrite on sd card (#269)
1 parent 2f19b9e commit 52fb5a6

File tree

8 files changed

+165
-154
lines changed

8 files changed

+165
-154
lines changed

src/apps/bip85.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
from embit import bip85
77
from gui.common import add_button, add_button_pair, align_button_pair
88
from gui.decorators import on_release
9-
from gui.screens import Menu, NumericScreen, QRAlert, Alert
9+
from gui.screens import Menu, NumericScreen, QRAlert, Alert, Prompt
1010
from gui.screens.mnemonic import MnemonicScreen
11-
from helpers import SDCardFile
11+
import platform
1212

1313
class QRWithSD(QRAlert):
1414
SAVE = 1
@@ -119,8 +119,14 @@ async def menu(self, show_screen):
119119
fname = "bip85-%s-mnemonic-%d-%d.txt" % (
120120
fgp, num_words, index
121121
)
122-
with SDCardFile(fname, "w") as f:
123-
f.write(mnemonic)
122+
with platform.sdcard as sd:
123+
if sd.file_exists(fname):
124+
scr = Prompt("Overwrite?", message="File %s already exists on the SD card. Overwrite?" % fname)
125+
confirm = await show_screen(scr)
126+
if not confirm:
127+
return True
128+
with sd.open(fname, "w") as f:
129+
f.write(mnemonic)
124130
await show_screen(
125131
Alert(
126132
title="Success",
@@ -169,8 +175,9 @@ async def menu(self, show_screen):
169175
)
170176
if action == QRWithSD.SAVE:
171177
fname = "bip85-%s-%s-%d.txt" % (fgp, file_suffix, index)
172-
with SDCardFile(fname, "w") as f:
173-
f.write(res)
178+
with platform.sdcard as sd:
179+
with sd.open(fname, "w") as f:
180+
f.write(res)
174181
await show_screen(
175182
Alert(
176183
title="Success",

src/apps/wallets/wallet.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from embit.transaction import SIGHASH
1212
from .screens import WalletScreen, WalletInfoScreen
1313
from .commands import DELETE, EDIT, MENU, INFO, EXPORT
14-
from gui.screens import Menu, QRAlert, Alert
14+
from gui.screens import Menu, QRAlert, Alert, Prompt
1515
import lvgl as lv
1616

1717
class WalletError(AppError):
@@ -69,7 +69,7 @@ async def export_menu(self, show_screen):
6969
buttons = [
7070
(None, "Export options"),
7171
(1, "Show QR code"),
72-
(2, "Save to SD card", platform.is_sd_present()),
72+
(2, "Save to SD card", platform.sdcard.is_present),
7373
]
7474
menuitem = await show_screen(Menu(buttons, last=(255, None), title="Export wallet %s" % self.name))
7575
desc = add_checksum(str(self.descriptor.branch(0)))
@@ -83,13 +83,16 @@ async def export_menu(self, show_screen):
8383
await show_screen(QRAlert(title="Export wallet %s" % self.name, qr_width=450,
8484
message="Scan this QR code with compatible software wallet", qr_message=json.dumps(obj)))
8585
elif menuitem == 2:
86-
if not platform.is_sd_present():
86+
if not platform.sdcard.is_present:
8787
raise WalletError("SD card is not present")
88-
platform.mount_sdcard()
89-
fname = "/sd/%s.json" % self.name
90-
with open(platform.fpath(fname), "w") as f:
91-
json.dump(obj, f)
92-
platform.unmount_sdcard()
88+
with platform.sdcard as sd:
89+
fname = "%s.json" % (self.name or "wallet")
90+
if sd.file_exists(fname):
91+
confirm = await show_screen(Prompt("Overwrite?", message="File %s already exists on the SD card. Overwrite?" % fname))
92+
if not confirm:
93+
return
94+
with sd.open(fname, "w") as f:
95+
json.dump(obj, f)
9396
await show_screen(Alert("Success!", "Wallet descriptor is written to\n\n%s" % fname))
9497
else:
9598
return

src/apps/xpubs/xpubs.py

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from app import BaseApp, AppError
2-
from gui.screens import Menu, DerivationScreen, NumericScreen, Alert, InputScreen
2+
from gui.screens import Menu, DerivationScreen, NumericScreen, Alert, InputScreen, Prompt
33
from .screens import XPubScreen
44
import json
55
from binascii import hexlify
66
from embit.liquid.networks import NETWORKS
77
from embit import bip32
8-
from helpers import is_liquid, SDCardFile
8+
from helpers import is_liquid
99
from io import BytesIO
1010
import platform
1111
from collections import OrderedDict
@@ -101,12 +101,13 @@ async def menu(self, show_screen, show_all=False):
101101
elif menuitem == 3:
102102
file_format = await self.save_menu(show_screen)
103103
if file_format:
104-
filename = self.save_all_to_sd(file_format)
105-
await show_screen(
106-
Alert("Saved!",
107-
"Public keys are saved to the file:\n\n%s" % filename,
108-
button_text="Close")
109-
)
104+
filename = await self.save_all_to_sd(file_format, self.account, show_screen)
105+
if filename is not None:
106+
await show_screen(
107+
Alert("Saved!",
108+
"Public keys are saved to the file:\n\n%s" % filename,
109+
button_text="Close")
110+
)
110111
elif menuitem == 4:
111112
from_account = await show_screen(
112113
NumericScreen(
@@ -137,9 +138,7 @@ async def menu(self, show_screen, show_all=False):
137138
return True
138139
return False
139140

140-
def save_all_to_sd(self, file_format, account=None):
141-
if account is None:
142-
account = self.account
141+
async def save_all_to_sd(self, file_format, account, show_screen):
143142

144143
fingerprint = hexlify(self.keystore.fingerprint).decode()
145144

@@ -148,11 +147,16 @@ def save_all_to_sd(self, file_format, account=None):
148147
file_format, fingerprint, account, extension,
149148
)
150149

151-
if not platform.is_sd_present():
150+
if not platform.sdcard.is_present:
152151
raise AppError("Please insert SD card")
153152

154-
with SDCardFile(filename, "w") as f:
155-
self._dump_account(f, file_format, account)
153+
with platform.sdcard as sd:
154+
if sd.file_exists(filename):
155+
confirm = await show_screen(Prompt("Overwrite?", message="File %s already exists on the SD card. Overwrite?" % filename))
156+
if not confirm:
157+
return
158+
with sd.open(filename, "w") as f:
159+
self._dump_account(f, file_format, account)
156160

157161
return filename
158162

@@ -173,10 +177,15 @@ async def export_multiple_accounts_xpubs(
173177
filename = "%s-%s-%d-%d.txt" % (
174178
file_format, fingerprint, from_account, to_account
175179
)
176-
with SDCardFile(filename, "w") as f:
177-
for account in range(from_account, to_account+1):
178-
self.show_loader(title="Exporting account %d..." % account)
179-
self._dump_account(f, file_format, account)
180+
with platform.sdcard as sd:
181+
if sd.file_exists(filename):
182+
confirm = await show_screen(Prompt("Overwrite?", message="File %s already exists on the SD card. Overwrite?" % filename))
183+
if not confirm:
184+
return
185+
with sd.open(filename, "w") as f:
186+
for account in range(from_account, to_account+1):
187+
self.show_loader(title="Exporting account %d..." % account)
188+
self._dump_account(f, file_format, account)
180189
await show_screen(
181190
Alert(
182191
"Success!",
@@ -187,7 +196,7 @@ async def export_multiple_accounts_xpubs(
187196
else: # cc format - one file per account
188197
for account in range(from_account, to_account+1):
189198
self.show_loader(title="Exporting account %d..." % account)
190-
self.save_all_to_sd(file_format, account)
199+
await self.save_all_to_sd(file_format, account, show_screen)
191200
await show_screen(
192201
Alert(
193202
"Success!",
@@ -290,8 +299,9 @@ async def show_xpub(self, derivation, show_screen):
290299
await self.create_wallet(derivation, canonical, prefix, ver, show_screen)
291300
elif res:
292301
filename = "%s-%s.txt" % (fingerprint, derivation[2:].replace("/", "-"))
293-
with SDCardFile(filename, "w") as f:
294-
f.write(res)
302+
with platform.sdcard as sd:
303+
with sd.open(filename, "w") as f:
304+
f.write(res)
295305
await show_screen(
296306
Alert("Saved!",
297307
"Extended public key is saved to the file:\n\n%s" % filename,

src/helpers.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -175,37 +175,3 @@ def read_write(fin, fout, chunk_size=32):
175175
total += fout.write(chunk)
176176
return total
177177

178-
class SDCardFile:
179-
"""open file on SD card, mount card on enter, unmount on exit
180-
181-
Usage:
182-
183-
with SDCardFile("/sd/blah", "w") as f:
184-
f.write("blah")
185-
"""
186-
def __init__(self, filename, *args, **kwargs):
187-
self._filename = filename
188-
self._args = args
189-
self._kwargs = kwargs
190-
self.file = None
191-
192-
def mount(self):
193-
platform.mount_sdcard()
194-
195-
def unmount(self):
196-
platform.unmount_sdcard()
197-
198-
def __enter__(self):
199-
self.mount()
200-
self.file = open(
201-
platform.fpath("/sd/" + self._filename),
202-
*self._args, **self._kwargs
203-
)
204-
return self.file
205-
206-
def __exit__(self, exc_type, exc_value, traceback):
207-
if self.file:
208-
self.file.close()
209-
self.file = None
210-
self.unmount()
211-

src/hosts/sd.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ def reset_and_mount(self):
2828
self.f.close()
2929
os.remove(self.fram)
3030
self.f = None
31-
if not platform.is_sd_present:
31+
if not platform.sdcard.is_present:
3232
raise HostError("SD card is not inserted")
33-
platform.mount_sdcard()
33+
platform.sdcard.mount()
3434

3535
def copy(self, fin, fout):
3636
b = bytearray(100)
@@ -60,7 +60,7 @@ async def get_data(self, raw=False, chunk_timeout=0.1):
6060
self.copy(fin, fout)
6161
self.f = open(self.fram,"rb")
6262
finally:
63-
platform.unmount_sdcard()
63+
platform.sdcard.unmount()
6464
return self.f
6565

6666
def truncate(self, fname):
@@ -120,6 +120,13 @@ async def send_data(self, stream, *args, **kwargs):
120120
new_fname = self.completed_filename(self.sd_file)
121121
self.reset_and_mount()
122122
try:
123+
if platform.file_exists(new_fname):
124+
confirm = await self.manager.gui.prompt("Overwrite?",
125+
"File %s exists. Overwrite?" % new_fname.split("/")[-1]
126+
)
127+
if not confirm:
128+
platform.sdcard.unmount()
129+
return
123130
if isinstance(stream, str):
124131
with open(stream, "rb") as fin:
125132
with open(new_fname, "wb") as fout:
@@ -129,7 +136,7 @@ async def send_data(self, stream, *args, **kwargs):
129136
self.copy(stream, fout)
130137
stream.seek(0)
131138
finally:
132-
platform.unmount_sdcard()
139+
platform.sdcard.unmount()
133140
show_qr = await self.manager.gui.prompt("Success!", "\n\nProcessed request is saved to\n\n%s\n\nShow as QR code?" % new_fname.split("/")[-1])
134141
if show_qr:
135142
await self._show_qr(stream, *args, **kwargs)

src/keystore/ram.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -395,14 +395,17 @@ async def show_mnemonic(self):
395395
msg = self.mnemonic
396396
await self.show(QRAlert(title="Your mnemonic as QR code", message=msg, qr_message=qr_msg, transcribe=True))
397397
elif v == ExportMnemonicScreen.SD:
398-
if not platform.is_sd_present:
398+
if not platform.sdcard.is_present:
399399
raise KeyStoreError("SD card is not present")
400400
if await self.show(Prompt("Are you sure?", message="Your mnemonic will be saved as a simple plaintext file.\n\nAnyone with access to it will be able to read your key.\n\nContinue?")):
401-
platform.mount_sdcard()
402-
fname = "/sd/%s.txt" % self.mnemonic.split()[0]
403-
with open(platform.fpath(fname), "w") as f:
404-
f.write(self.mnemonic)
405-
platform.unmount_sdcard()
401+
with platform.sdcard as sd:
402+
fname = "%s.txt" % self.mnemonic.split()[0]
403+
if sd.file_exists(fname):
404+
confirm = await self.show(Prompt("Overwrite?", message="File %s already exists on the SD card. Overwrite?" % fname))
405+
if not confirm:
406+
return
407+
with sd.open(fname, "w") as f:
408+
f.write(self.mnemonic)
406409
await self.show(Alert(title="Mnemonic is saved!", message="You mnemonic is saved in plaintext to\n\n%s\n\nPlease keep it safe." % fname))
407410
else:
408411
return

0 commit comments

Comments
 (0)