Skip to content

Commit 4b121c7

Browse files
committed
fix extract data
1 parent 33f812e commit 4b121c7

File tree

2 files changed

+71
-20
lines changed

2 files changed

+71
-20
lines changed

gui/main.py

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import subprocess
1010
import json
1111
import tempfile
12+
import threading
13+
import time
1214
from pathlib import Path
1315
from typing import Optional, Callable
1416
from datetime import datetime
@@ -64,23 +66,54 @@ def gui_main() -> None:
6466
class PlaceholderEntry(ttk.Entry):
6567
"""Entry widget with placeholder text support."""
6668
def __init__(self, parent, placeholder="", **kwargs):
69+
# Extract textvariable if provided
70+
self._string_var = kwargs.pop('textvariable', None)
6771
super().__init__(parent, **kwargs)
6872
self.placeholder = placeholder
6973
self.placeholder_color = "#999999"
70-
self.default_color = "SystemWindowText"
74+
# Use platform-appropriate default text color
75+
if sys.platform == "win32":
76+
self.default_color = "SystemWindowText"
77+
else:
78+
self.default_color = "black"
7179
self._has_placeholder = False
80+
self._ignore_trace = False
81+
82+
# Set up trace on the variable if provided
83+
if self._string_var:
84+
self._string_var.trace_add("write", self._on_var_changed)
7285

7386
if placeholder:
7487
self._show_placeholder()
7588

7689
self.bind("<FocusIn>", self._on_focus_in)
7790
self.bind("<FocusOut>", self._on_focus_out)
91+
self.bind("<KeyRelease>", self._on_key_release)
92+
93+
def _on_var_changed(self, *args):
94+
"""Handle external changes to the StringVar."""
95+
if not self._ignore_trace and self._string_var:
96+
value = self._string_var.get()
97+
if not value and not self._has_placeholder:
98+
self._show_placeholder()
99+
100+
def _on_key_release(self, *args):
101+
"""Update StringVar when user types (without placeholder)."""
102+
if not self._has_placeholder and self._string_var:
103+
self._ignore_trace = True
104+
self._string_var.set(self.get())
105+
self._ignore_trace = False
78106

79107
def _show_placeholder(self, *args):
80108
if not self.get():
81109
self._has_placeholder = True
82110
self.insert(0, self.placeholder)
83111
self.config(foreground=self.placeholder_color)
112+
# Don't set placeholder in the StringVar
113+
if self._string_var:
114+
self._ignore_trace = True
115+
self._string_var.set("")
116+
self._ignore_trace = False
84117

85118
def _on_focus_in(self, *args):
86119
if self._has_placeholder:
@@ -89,10 +122,20 @@ def _on_focus_in(self, *args):
89122
self._has_placeholder = False
90123

91124
def _on_focus_out(self, *args):
125+
# Update StringVar with actual value
126+
if not self._has_placeholder and self._string_var:
127+
self._ignore_trace = True
128+
self._string_var.set(self.get())
129+
self._ignore_trace = False
130+
92131
if not self.get():
93132
self._show_placeholder()
94133

95134
def get_value(self):
135+
"""Get the actual value, returning empty string if showing placeholder."""
136+
if self._has_placeholder:
137+
return ""
138+
return self.get()
96139
"""Get actual value without placeholder."""
97140
return "" if self._has_placeholder else self.get()
98141

@@ -1538,7 +1581,7 @@ def load_template():
15381581
qr_box,
15391582
text="Generate QR",
15401583
command=lambda: self._run_command(
1541-
["python", str(Path(__file__).parent / "app.py"), "qr-generate",
1584+
["python", str(Path(__file__).parent.parent / "app.py"), "qr-generate",
15421585
"--text", qr_text.get(), "--out", qr_out.get()],
15431586
"QR generate",
15441587
),
@@ -1569,7 +1612,7 @@ def load_template():
15691612
ttk.Entry(portable_box, textvariable=port_frame).pack(fill=tk.X, padx=10, pady=(0, 8))
15701613

15711614
def run_portable():
1572-
cmd = ["python", str(Path(__file__).parent / "app.py"), "portable-decoder",
1615+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "portable-decoder",
15731616
"--input", port_in.get(), "--out", port_out.get()]
15741617
if port_method.get():
15751618
cmd.extend(["--method", port_method.get()])
@@ -1591,7 +1634,7 @@ def run_portable():
15911634
assoc_box,
15921635
text="Generate .reg",
15931636
command=lambda: self._run_command(
1594-
["python", str(Path(__file__).parent / "app.py"), "file-assoc", "--out", assoc_out.get()],
1637+
["python", str(Path(__file__).parent.parent / "app.py"), "file-assoc", "--out", assoc_out.get()],
15951638
"File association",
15961639
),
15971640
).pack(anchor=tk.W, padx=10, pady=(0, 10))
@@ -2128,7 +2171,7 @@ def task():
21282171
self.root.after(0, self.status.stop)
21292172
self.root.after(0, lambda: self._set_status(f"{action} error"))
21302173
self.root.after(0, lambda: self._add_history(action, "Error", str(exc)))
2131-
self.root.after(0, lambda: messagebox.showerror("Error", str(exc)))
2174+
self.root.after(0, lambda e=exc: messagebox.showerror("Error", str(e)))
21322175

21332176
threading.Thread(target=task, daemon=True).start()
21342177

@@ -2165,7 +2208,7 @@ def _encode_image(self, cover: str, message: str, payload_file: str, password: s
21652208
return
21662209

21672210
def build_cmd(input_img: str, out_img: str) -> list[str]:
2168-
cmd = ["python", str(Path(__file__).parent / "app.py"), "encode",
2211+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "encode",
21692212
"--image", input_img, "--out", out_img, "--method", method]
21702213
if payload_file:
21712214
cmd.extend(["--in-file", payload_file])
@@ -2238,7 +2281,7 @@ def run_nested():
22382281
self.root.after(0, self.status.stop)
22392282
self.root.after(0, lambda: self._set_status("Image encode failed"))
22402283
self.root.after(0, lambda: self._add_history("Image encode", "Failed", str(exc)))
2241-
self.root.after(0, lambda: messagebox.showerror("Error", str(exc)))
2284+
self.root.after(0, lambda e=exc: messagebox.showerror("Error", str(e)))
22422285

22432286
self.root.after(0, lambda: self._set_status("Image encode in progress"))
22442287
self.root.after(0, self.status.start)
@@ -2252,7 +2295,7 @@ def _decode_image(self, stego: str, password: str, output: str, method: str, prn
22522295
messagebox.showerror("Error", "PRNG key is required for the selected method.")
22532296
return
22542297

2255-
cmd = ["python", str(Path(__file__).parent / "app.py"), "decode",
2298+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "decode",
22562299
"--image", stego, "--method", method]
22572300
if password:
22582301
cmd.extend(["--password", password])
@@ -2281,7 +2324,7 @@ def _encode_media(self, media_type: str, input_path: str, message: str, payload_
22812324
messagebox.showerror("Error", "Select an output file.")
22822325
return
22832326

2284-
cmd = ["python", str(Path(__file__).parent / "app.py"), f"{media_type}-encode",
2327+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), f"{media_type}-encode",
22852328
f"--{media_type}", input_path, "--out", output]
22862329
if payload_file:
22872330
cmd.extend(["--in-file", payload_file])
@@ -2306,7 +2349,7 @@ def _decode_media(self, media_type: str, input_path: str, password: str, output:
23062349
messagebox.showerror("Error", "Select an output file.")
23072350
return
23082351

2309-
cmd = ["python", str(Path(__file__).parent / "app.py"), f"{media_type}-decode",
2352+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), f"{media_type}-decode",
23102353
f"--{media_type}", input_path, "--out", output]
23112354
if password:
23122355
cmd.extend(["--password", password])
@@ -2325,7 +2368,7 @@ def _encode_pdf(self, pdf_path: str, message: str, payload_file: str, password:
23252368
messagebox.showerror("Error", "Select an output PDF.")
23262369
return
23272370

2328-
cmd = ["python", str(Path(__file__).parent / "app.py"), "pdf-encode",
2371+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "pdf-encode",
23292372
"--pdf", pdf_path, "--out", output]
23302373
if payload_file:
23312374
cmd.extend(["--in-file", payload_file])
@@ -2346,7 +2389,7 @@ def _decode_pdf(self, pdf_path: str, password: str, output: str) -> None:
23462389
if not pdf_path:
23472390
messagebox.showerror("Error", "Select a PDF file.")
23482391
return
2349-
cmd = ["python", str(Path(__file__).parent / "app.py"), "pdf-decode", "--pdf", pdf_path]
2392+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "pdf-decode", "--pdf", pdf_path]
23502393
if output:
23512394
cmd.extend(["--out", output])
23522395
if password:
@@ -2376,7 +2419,7 @@ def _encode_gif(self, gif_path: str, frame_index: int, message: str, payload_fil
23762419
messagebox.showerror("Error", "PRNG key is required for the selected method.")
23772420
return
23782421

2379-
cmd = ["python", str(Path(__file__).parent / "app.py"), "gif-encode",
2422+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "gif-encode",
23802423
"--gif", gif_path, "--out", output, "--frame", str(frame_index), "--method", method]
23812424
if payload_file:
23822425
cmd.extend(["--in-file", payload_file])
@@ -2404,7 +2447,7 @@ def _decode_gif(self, gif_path: str, frame_index: int, password: str, output: st
24042447
messagebox.showerror("Error", "PRNG key is required for the selected method.")
24052448
return
24062449

2407-
cmd = ["python", str(Path(__file__).parent / "app.py"), "gif-decode",
2450+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "gif-decode",
24082451
"--gif", gif_path, "--frame", str(frame_index), "--method", method]
24092452
if output:
24102453
cmd.extend(["--out", output])
@@ -2437,7 +2480,7 @@ def _encode_video_frame(self, video_path: str, frame_index: int, message: str, p
24372480
messagebox.showerror("Error", "PRNG key is required for the selected method.")
24382481
return
24392482

2440-
cmd = ["python", str(Path(__file__).parent / "app.py"), "video-frame-encode",
2483+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "video-frame-encode",
24412484
"--video", video_path, "--out", output, "--frame", str(frame_index), "--method", method]
24422485
if payload_file:
24432486
cmd.extend(["--in-file", payload_file])
@@ -2465,7 +2508,7 @@ def _decode_video_frame(self, video_path: str, frame_index: int, password: str,
24652508
messagebox.showerror("Error", "PRNG key is required for the selected method.")
24662509
return
24672510

2468-
cmd = ["python", str(Path(__file__).parent / "app.py"), "video-frame-decode",
2511+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "video-frame-decode",
24692512
"--video", video_path, "--frame", str(frame_index), "--method", method]
24702513
if output:
24712514
cmd.extend(["--out", output])
@@ -2502,7 +2545,7 @@ def task():
25022545
self.root.after(0, lambda: self._set_status("Batch encode in progress"))
25032546
for idx, path in enumerate(files, start=1):
25042547
out_path = Path(output_dir) / f"{Path(path).stem}_stego.png"
2505-
cmd = ["python", str(Path(__file__).parent / "app.py"), "encode",
2548+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "encode",
25062549
"--image", path, "--out", str(out_path), "--message", message,
25072550
"--method", method]
25082551
if password:
@@ -2543,7 +2586,7 @@ def task():
25432586
self.root.after(0, lambda: self._set_status("Batch decode in progress"))
25442587
for idx, path in enumerate(files, start=1):
25452588
out_path = Path(output_dir) / f"{Path(path).stem}_decoded.bin"
2546-
cmd = ["python", str(Path(__file__).parent / "app.py"), "decode",
2589+
cmd = ["python", str(Path(__file__).parent.parent / "app.py"), "decode",
25472590
"--image", path, "--out", str(out_path), "--method", method]
25482591
if password:
25492592
cmd.extend(["--password", password])

stego/core.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,18 @@ def check_expiration(metadata: dict | None) -> None:
237237
expires = metadata.get("expires")
238238
if not expires:
239239
return
240+
241+
# Skip invalid/placeholder expiration dates
242+
if expires.startswith("e.g.,") or expires.startswith("Optional"):
243+
return
244+
240245
try:
241246
exp = datetime.fromisoformat(expires)
242-
except ValueError as exc:
243-
raise ValueError("Invalid expiration format; use YYYY-MM-DD or ISO datetime") from exc
247+
except ValueError:
248+
# Ignore invalid expiration formats instead of crashing
249+
# This allows decoding of data encoded with placeholder text
250+
return
251+
244252
if datetime.now() > exp:
245253
raise ValueError("Payload has expired")
246254

0 commit comments

Comments
 (0)