diff --git a/Cargo.lock b/Cargo.lock index ba7f2a9..0d37fc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -773,7 +773,7 @@ dependencies = [ [[package]] name = "quantum-pixel" -version = "2.2.0" +version = "2.2.1" dependencies = [ "pyo3", "stegano-core", diff --git a/Cargo.toml b/Cargo.toml index 537feaa..8c6a718 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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)" diff --git a/quantum_pixel/web.py b/quantum_pixel/web.py index 0d4ba2d..a65d0a9 100644 --- a/quantum_pixel/web.py +++ b/quantum_pixel/web.py @@ -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): @@ -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): @@ -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): diff --git a/tests/test_generator.py b/tests/test_generator.py index e9bbbf4..f7fd22c 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -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.""" @@ -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) @@ -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) diff --git a/tests/test_steganography.py b/tests/test_steganography.py index 19614b8..01c228a 100644 --- a/tests/test_steganography.py +++ b/tests/test_steganography.py @@ -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 @@ -18,9 +20,9 @@ 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(): @@ -28,7 +30,7 @@ def test_decode_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(): @@ -36,29 +38,29 @@ def test_decode_normal_file(): 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") @@ -66,28 +68,28 @@ 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) diff --git a/uv.lock b/uv.lock index 95cdb6d..4de5188 100644 --- a/uv.lock +++ b/uv.lock @@ -125,7 +125,7 @@ wheels = [ [[package]] name = "fastapi" -version = "0.133.1" +version = "0.134.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -134,9 +134,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/22/6f/0eafed8349eea1fa462238b54a624c8b408cd1ba2795c8e64aa6c34f8ab7/fastapi-0.133.1.tar.gz", hash = "sha256:ed152a45912f102592976fde6cbce7dae1a8a1053da94202e51dd35d184fadd6", size = 378741, upload-time = "2026-02-25T18:18:17.398Z" } +sdist = { url = "https://files.pythonhosted.org/packages/96/15/647ea81cb73b55b48fb095158a9cd64e42e9e4f1d34dbb5cc4a4939779d6/fastapi-0.134.0.tar.gz", hash = "sha256:3122b1ea0dbeaab48b5976e80b99ca7eda02be154bf03e126a33220e73255a9a", size = 385667, upload-time = "2026-02-27T21:18:12.931Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/c9/a175a7779f3599dfa4adfc97a6ce0e157237b3d7941538604aadaf97bfb6/fastapi-0.133.1-py3-none-any.whl", hash = "sha256:658f34ba334605b1617a65adf2ea6461901bdb9af3a3080d63ff791ecf7dc2e2", size = 109029, upload-time = "2026-02-25T18:18:18.578Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e6/fd49c28a54b7d6f5c64045155e40f6cff9ed4920055043fb5ac7969f7f2f/fastapi-0.134.0-py3-none-any.whl", hash = "sha256:f4e7214f24b2262258492e05c48cf21125e4ffc427e30dd32fb4f74049a3d56a", size = 110404, upload-time = "2026-02-27T21:18:10.809Z" }, ] [package.optional-dependencies]