From cc350669c971068b419a0c7ced35a616519e3db7 Mon Sep 17 00:00:00 2001 From: abdulhakkeempa Date: Tue, 27 Aug 2024 16:20:37 +0530 Subject: [PATCH 1/3] feature: enabled fallback feature for invalid src --- reflex/components/next/image.py | 58 ++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/reflex/components/next/image.py b/reflex/components/next/image.py index 817bf590a..ebc499adf 100644 --- a/reflex/components/next/image.py +++ b/reflex/components/next/image.py @@ -6,9 +6,15 @@ from reflex.event import EventHandler from reflex.utils import types from reflex.vars import Var +from pathlib import Path +from constants.base import Dirs + +import requests +import os + from .base import NextComponent - +# implementing image call back technique here class Image(NextComponent): """Display an image.""" @@ -61,6 +67,9 @@ class Image(NextComponent): # Fires when the image has an error. on_error: EventHandler[lambda: []] + # Fires when the src image is not provided. + fallback: Var[str] + @classmethod def create( cls, @@ -83,6 +92,42 @@ class Image(NextComponent): style = props.get("style", {}) DEFAULT_W_H = "100%" + def validate_src_image(src): + """ + Validates the 'src' parameter for the Image component. + Args: + src: The source parameter (local file path, web URL, or Pillow Image). + Returns: + Valid source (src) or raises an error. + """ + try: + if isinstance(src, str): + if src.startswith("/"): + full_path = Path.cwd() / Dirs.APP_ASSETS / src.strip("/") + if os.path.exists(full_path): + return True + else: + raise FileNotFoundError(f"Local image not found: {full_path}") + elif src.startswith("http"): + try: + response = requests.head(src) + if response.status_code == 200: + return True + else: + raise ValueError(f"Invalid web URL: {src}") + except requests.RequestException: + raise ValueError(f"Failed to validate web URL: {src}") + else: + raise ValueError(f"Unsupported src format: {src}") + elif isinstance(src, Image.Image): + return True + else: + raise ValueError(f"Invalid src type: {type(src)}") + except Exception as e: + print(f"Error: {e}") + return False + + def check_prop_type(prop_name, prop_value): if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]): props[prop_name] = prop_value @@ -94,6 +139,17 @@ class Image(NextComponent): props[prop_name] = 0 style[prop_name] = DEFAULT_W_H + + src = props.get("src", "") + if not validate_src_image(src): + if props.get("fallback"): + if validate_src_image(props.get("fallback")): + props["src"] = props.get("fallback") + else: + raise ValueError(f"Invalid fallback image: {props.get('fallback')}") + else: + raise ValueError(f"Invalid src image: {src}") + check_prop_type("width", width) check_prop_type("height", height) From 4ecb811fa31f4dbf88d23b2a398af467abad859f Mon Sep 17 00:00:00 2001 From: abdulhakkeempa Date: Tue, 27 Aug 2024 18:03:04 +0530 Subject: [PATCH 2/3] feature: fallback enabled for images when an invalid arguement is passed to src --- reflex/components/el/elements/media.py | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/reflex/components/el/elements/media.py b/reflex/components/el/elements/media.py index b2bdc9e6f..3e6f04f8c 100644 --- a/reflex/components/el/elements/media.py +++ b/reflex/components/el/elements/media.py @@ -1,8 +1,14 @@ """Element classes. This is an auto-generated file. Do not edit. See ../generate.py.""" +import os +import pathlib from typing import Any, Union +import requests +from PIL import Image + from reflex import Component, ComponentNamespace +from reflex.constants.base import Dirs from reflex.constants.colors import Color from reflex.utils import console from reflex.vars import Var as Var @@ -132,6 +138,60 @@ class Img(BaseHTML): The component. """ + + def validate_image(src): + """Validates the 'src' parameter for the Image component. + + Args: + src: The source parameter (local file path, web URL, or Pillow Image). + + Returns: + Valid source (src) or raises an error. + """ + try: + if isinstance(src, str): + if src.startswith("/"): + full_path = ( + pathlib.Path.cwd() / Dirs.APP_ASSETS / src.strip("/") + ) + if os.path.exists(full_path): + return True + else: + raise FileNotFoundError( + f"Local image not found: {full_path}" + ) + elif src.startswith("http"): + try: + response = requests.head(src) + if response.status_code == 200: + return True + else: + raise ValueError(f"Invalid web URL: {src}") + except requests.RequestException: + raise ValueError( + f"Failed to validate web URL: {src}" + ) from requests.RequestException + else: + raise ValueError(f"Unsupported src format: {src}") + elif isinstance(src, Image.Image): + return True + else: + raise ValueError(f"Invalid src type: {type(src)}") + except Exception as e: + print(f"Error: {e}") + return False + + src = props.get("src", "") + if not validate_image(src): + fallback = props.get("fallback", "") + if fallback: + if validate_image(fallback): + props["src"] = fallback + else: + print(f"Invalid fallback image: {fallback}") + else: + print(f"Invalid src image: {src}") + return ( super().create(src=children[0], **props) if children From 856a084cc21e307ab371fb56cc0c62dd3f269c3e Mon Sep 17 00:00:00 2001 From: abdulhakkeempa Date: Tue, 27 Aug 2024 18:03:27 +0530 Subject: [PATCH 3/3] fix: file reverted to initial version --- reflex/components/next/image.py | 57 +-------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/reflex/components/next/image.py b/reflex/components/next/image.py index ebc499adf..b7acea410 100644 --- a/reflex/components/next/image.py +++ b/reflex/components/next/image.py @@ -6,14 +6,9 @@ from reflex.event import EventHandler from reflex.utils import types from reflex.vars import Var -from pathlib import Path -from constants.base import Dirs - -import requests -import os - from .base import NextComponent + # implementing image call back technique here class Image(NextComponent): """Display an image.""" @@ -67,9 +62,6 @@ class Image(NextComponent): # Fires when the image has an error. on_error: EventHandler[lambda: []] - # Fires when the src image is not provided. - fallback: Var[str] - @classmethod def create( cls, @@ -92,42 +84,6 @@ class Image(NextComponent): style = props.get("style", {}) DEFAULT_W_H = "100%" - def validate_src_image(src): - """ - Validates the 'src' parameter for the Image component. - Args: - src: The source parameter (local file path, web URL, or Pillow Image). - Returns: - Valid source (src) or raises an error. - """ - try: - if isinstance(src, str): - if src.startswith("/"): - full_path = Path.cwd() / Dirs.APP_ASSETS / src.strip("/") - if os.path.exists(full_path): - return True - else: - raise FileNotFoundError(f"Local image not found: {full_path}") - elif src.startswith("http"): - try: - response = requests.head(src) - if response.status_code == 200: - return True - else: - raise ValueError(f"Invalid web URL: {src}") - except requests.RequestException: - raise ValueError(f"Failed to validate web URL: {src}") - else: - raise ValueError(f"Unsupported src format: {src}") - elif isinstance(src, Image.Image): - return True - else: - raise ValueError(f"Invalid src type: {type(src)}") - except Exception as e: - print(f"Error: {e}") - return False - - def check_prop_type(prop_name, prop_value): if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]): props[prop_name] = prop_value @@ -139,17 +95,6 @@ class Image(NextComponent): props[prop_name] = 0 style[prop_name] = DEFAULT_W_H - - src = props.get("src", "") - if not validate_src_image(src): - if props.get("fallback"): - if validate_src_image(props.get("fallback")): - props["src"] = props.get("fallback") - else: - raise ValueError(f"Invalid fallback image: {props.get('fallback')}") - else: - raise ValueError(f"Invalid src image: {src}") - check_prop_type("width", width) check_prop_type("height", height)