tunnel / utils /utils.py
theshresthshukla's picture
tool to download logos from internet
2c01a8f verified
"""
Utility functions for the Logo Downloader application
"""
import os
import re
import json
import time
from pathlib import Path
from typing import List, Optional
from urllib.parse import urlparse
import logging
from services.appconfig import IMAGE_SIGNATURES, MIN_FILE_SIZE, MAX_FILE_SIZE
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def create_safe_filename(name: str) -> str:
"""
Create a safe filename from entity name
Args:
name (str): Entity name
Returns:
str: Safe filename
"""
safe_name = re.sub(r'[^\w\s-]', '', name).strip()
safe_name = re.sub(r'[-\s]+', '_', safe_name)
return safe_name
def get_file_extension(url: str) -> str:
"""
Extract file extension from URL
Args:
url (str): Image URL
Returns:
str: File extension
"""
parsed_url = urlparse(url)
extension = os.path.splitext(parsed_url.path)[1]
if not extension or extension.lower() not in ['.png', '.jpg', '.jpeg', '.svg', '.webp']:
extension = '.png'
return extension
def is_valid_image_file(filepath: str) -> bool:
"""
Validate if file is a proper image
Args:
filepath (str): Path to image file
Returns:
bool: True if valid image
"""
try:
# Check file exists and size
if not os.path.exists(filepath):
return False
file_size = os.path.getsize(filepath)
if file_size < MIN_FILE_SIZE or file_size > MAX_FILE_SIZE:
logger.warning(f"Invalid file size: {file_size}")
return False
# Check image signature
with open(filepath, 'rb') as f:
header = f.read(12)
for signature in IMAGE_SIGNATURES:
if header.startswith(signature):
return True
return False
except Exception as e:
logger.error(f"Error validating image: {e}")
return False
def create_directory(path: Path) -> bool:
"""
Create directory if it doesn't exist
Args:
path (Path): Directory path
Returns:
bool: True if successful
"""
try:
path.mkdir(parents=True, exist_ok=True)
return True
except Exception as e:
logger.error(f"Error creating directory {path}: {e}")
return False
def clean_up_file(filepath: str) -> None:
"""
Remove file if it exists
Args:
filepath (str): Path to file to remove
"""
try:
if os.path.exists(filepath):
os.remove(filepath)
except Exception as e:
logger.error(f"Error removing file {filepath}: {e}")
def parse_json_safely(json_string: str) -> Optional[dict]:
"""
Safely parse JSON string
Args:
json_string (str): JSON string to parse
Returns:
dict or None: Parsed JSON or None if failed
"""
try:
return json.loads(json_string)
except json.JSONDecodeError:
return None
def rate_limit_delay(delay: float = 1.0) -> None:
"""
Add delay between requests to be respectful to servers
Args:
delay (float): Delay in seconds
"""
time.sleep(delay)
def format_file_size(size_bytes: int) -> str:
"""
Format file size in human readable format
Args:
size_bytes (int): Size in bytes
Returns:
str: Formatted size string
"""
if size_bytes < 1024:
return f"{size_bytes} B"
elif size_bytes < 1024 * 1024:
return f"{size_bytes / 1024:.1f} KB"
else:
return f"{size_bytes / (1024 * 1024):.1f} MB"
def truncate_text(text: str, max_length: int = 100) -> str:
"""
Truncate text to specified length
Args:
text (str): Text to truncate
max_length (int): Maximum length
Returns:
str: Truncated text
"""
if len(text) <= max_length:
return text
return text[:max_length - 3] + "..."