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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2024"
name = "quantum-pixel"
version = "2.2.0"
version = "2.2.1"
description = "When both YES and NO are existed. Only human with emotions can comprehend."
readme = "quantum_pixel/README_PYPI.md"
license = "GNU General Public License v3 (GPLv3)"
Expand Down
10 changes: 5 additions & 5 deletions quantum_pixel/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def _join_uid(uid: str, filename: str) -> str:
@app.get("/", response_class=HTMLResponse)
async def start(request: Request):
"""A default start on app."""
return templates.TemplateResponse("index.html", {"request": request})
return templates.TemplateResponse(request, "index.html")

@app.post("/", response_class=JSONResponse)
async def upload(request: Request):
Expand Down Expand Up @@ -126,10 +126,10 @@ async def upload(request: Request):
async def start_encode(request: Request, uid: str):
"""Start the encode html."""
if not os.path.exists(_join_uid(uid, "encode_input.png")):
return templates.TemplateResponse("encode.html", {"request": request,
return templates.TemplateResponse(request, "encode.html", {
"error": ("The image file cannot be found, you might just exit and got auto cleanup! "
"Otherwise, there might be an attack/error, please issue me if that's so.")})
return templates.TemplateResponse("encode.html", {"request": request, "uid": uid})
return templates.TemplateResponse(request, "encode.html", {"uid": uid})

@app.post("/encode/{uid}")
async def end_encode(request: Request, uid: str):
Expand Down Expand Up @@ -240,10 +240,10 @@ def _encode() -> str:
async def start_decode(request: Request, uid: str):
"""Start the decode html."""
if not os.path.exists(_join_uid(uid, "decode_input.png")):
return templates.TemplateResponse("decode.html", {"request": request,
return templates.TemplateResponse(request, "decode.html", {
"error": ("The image file cannot be found, you might just exit and got auto cleanup! "
"Otherwise, there might be an attack/error, please issue me if that's so.")})
return templates.TemplateResponse("decode.html", {"request": request})
return templates.TemplateResponse(request, "decode.html")

@app.post("/decode/{uid}", response_class=JSONResponse)
async def end_decode(request: Request, uid: str):
Expand Down
13 changes: 7 additions & 6 deletions tests/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from quantum_pixel import Generator

PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ASSET_PATH = os.path.join(PROJECT_ROOT, "assets")
TEST_ASSET_PATH = os.path.join(PROJECT_ROOT, "tests", "assets")

def test_unreadable_file():
"""Test raising error when passing an unreadable file."""
Expand All @@ -18,7 +20,7 @@ def test_unreadable_file():

def test_init():
"""Test the __init__ function"""
generator = Generator(os.path.join(PROJECT_ROOT, "assets", "material.png"))
generator = Generator(os.path.join(ASSET_PATH, "material.png"))

assert isinstance(generator.img_data, np.ndarray)

Expand All @@ -28,9 +30,8 @@ def test_init():

def test_preview():
"""Test the `preview` function"""
generator = Generator(os.path.join(PROJECT_ROOT, "assets", "material.png"))
generator = Generator(os.path.join(ASSET_PATH, "material.png"))
generator.preview(0.2, os.path.join(TEST_ASSET_PATH, "preview.png"))

for _ in generator.preview(0.2, os.path.join(PROJECT_ROOT, "tests", "assets", "preview.png")):
pass
assert Image.open(os.path.join(PROJECT_ROOT, "tests", "assets", "preview.png"))
shutil.rmtree(os.path.join(PROJECT_ROOT, "tests", "assets"))
assert Image.open(os.path.join(TEST_ASSET_PATH, "preview.png"))
shutil.rmtree(TEST_ASSET_PATH)
48 changes: 25 additions & 23 deletions tests/test_steganography.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from quantum_pixel import Steganography

PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ASSET_PATH = os.path.join(PROJECT_ROOT, "assets")
TEST_ASSET_PATH = os.path.join(PROJECT_ROOT, "tests", "assets")

def _same_image(img1: Image.Image, img2: Image.Image):
return ImageChops.difference(img1, img2).getbbox() is None
Expand All @@ -18,76 +20,76 @@ def test_encode_overload():
"""Test encoding with unfit disguised image. (too small)"""
assert Steganography.encode(
password="",
input_file_path=os.path.join(PROJECT_ROOT, "assets", "material.png"),
output_file_path=os.path.join(PROJECT_ROOT, "tests", "assets", "overload.png"),
disguised_file_path=os.path.join(PROJECT_ROOT, "assets", "intro.png"),
input_file_path=os.path.join(ASSET_PATH, "material.png"),
output_file_path=os.path.join(TEST_ASSET_PATH, "overload.png"),
disguised_file_path=os.path.join(ASSET_PATH, "intro.png"),
).startswith("Capacity Error")

def test_decode_wrong_path():
"""Test decoding wrong path."""
assert Steganography.decode(
password="",
disguise_image=os.path.join("Not", "a", "path.png"),
output_folder=os.path.join(PROJECT_ROOT, "tests", "assets", "output")
output_folder=os.path.join(TEST_ASSET_PATH, "output")
) == "Image media is invalid"

def test_decode_normal_file():
"""Test decoding normal file which has no file embedded within."""
with pytest.raises(BaseException): # Rust Panic.
Steganography.decode(
password="",
disguise_image=os.path.join(PROJECT_ROOT, "assets", "intro.png"),
output_folder=os.path.join(PROJECT_ROOT, "tests", "assets", "output")
disguise_image=os.path.join(ASSET_PATH, "intro.png"),
output_folder=os.path.join(TEST_ASSET_PATH, "output")
)

def test_encode_no_password():
"""Test encoding without password."""
assert Steganography.encode(
password="",
input_file_path=os.path.join(PROJECT_ROOT, "assets", "intro.png"),
output_file_path=os.path.join(PROJECT_ROOT, "tests", "assets", "no_password.png"),
disguised_file_path=os.path.join(PROJECT_ROOT, "assets", "material.png"),
input_file_path=os.path.join(ASSET_PATH, "intro.png"),
output_file_path=os.path.join(TEST_ASSET_PATH, "no_password.png"),
disguised_file_path=os.path.join(ASSET_PATH, "material.png"),
) == ""

def test_decode_no_password():
"""Test decoding without password."""
assert Steganography.decode(
password="",
disguise_image=os.path.join(PROJECT_ROOT, "tests", "assets", "no_password.png"),
output_folder=os.path.join(PROJECT_ROOT, "tests", "assets", "output")
disguise_image=os.path.join(TEST_ASSET_PATH, "no_password.png"),
output_folder=os.path.join(TEST_ASSET_PATH, "output")
) == ""
assert _same_image(
img1=Image.open(os.path.join(PROJECT_ROOT, "assets", "intro.png")),
img2=Image.open(os.path.join(PROJECT_ROOT, "tests", "assets", "output", "intro.png"))
img1=Image.open(os.path.join(ASSET_PATH, "intro.png")),
img2=Image.open(os.path.join(TEST_ASSET_PATH, "output", "intro.png"))
)
shutil.rmtree("tests/assets")

def test_encode_with_password():
"""Test encoding with password."""
assert Steganography.encode(
password="supercalifragilisticexpialidocious",
input_file_path=os.path.join(PROJECT_ROOT, "assets", "intro.png"),
output_file_path=os.path.join(PROJECT_ROOT, "tests", "assets", "with_password.png"),
disguised_file_path=os.path.join(PROJECT_ROOT, "assets", "material.png"),
input_file_path=os.path.join(ASSET_PATH, "intro.png"),
output_file_path=os.path.join(TEST_ASSET_PATH, "with_password.png"),
disguised_file_path=os.path.join(ASSET_PATH, "material.png"),
) == ""

def test_decode_wrong_password():
"""Test decoding with wrong password."""
assert Steganography.decode(
password="serendipitous",
disguise_image=os.path.join(PROJECT_ROOT, "tests", "assets", "with_password.png"),
output_folder=os.path.join(PROJECT_ROOT, "tests", "assets", "output")
disguise_image=os.path.join(TEST_ASSET_PATH, "with_password.png"),
output_folder=os.path.join(TEST_ASSET_PATH, "output")
) == "Decryption error"

def test_decode_with_password():
"""Test decoding with password."""
assert Steganography.decode(
password="supercalifragilisticexpialidocious",
disguise_image=os.path.join(PROJECT_ROOT, "tests", "assets", "with_password.png"),
output_folder=os.path.join(PROJECT_ROOT, "tests", "assets", "output")
disguise_image=os.path.join(TEST_ASSET_PATH, "with_password.png"),
output_folder=os.path.join(TEST_ASSET_PATH, "output")
) == ""
assert _same_image(
img1=Image.open(os.path.join(PROJECT_ROOT, "assets", "intro.png")),
img2=Image.open(os.path.join(PROJECT_ROOT, "tests", "assets", "output", "intro.png"))
img1=Image.open(os.path.join(ASSET_PATH, "intro.png")),
img2=Image.open(os.path.join(TEST_ASSET_PATH, "output", "intro.png"))
)
shutil.rmtree(os.path.join(PROJECT_ROOT, "tests", "assets"))
shutil.rmtree(TEST_ASSET_PATH)
6 changes: 3 additions & 3 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.