bulk commit changes!

This commit is contained in:
2026-02-13 02:32:06 -05:00
parent c8f98c54c9
commit bf4a40f533
152 changed files with 2210 additions and 19 deletions

View File

@@ -5,6 +5,7 @@ import logging
import os
import re
import time
from collections.abc import Awaitable, Callable
from io import BytesIO
from urllib.parse import quote_plus
@@ -23,6 +24,7 @@ from backend.repository import (
logger = logging.getLogger(__name__)
PLACEHOLDER_IMAGE_PATH = "/static/images/placeholder.png"
GENERIC_AI_FALLBACK_URL = "https://placehold.co/1200x630/0f172a/e2e8f0/png?text=AI+News"
async def call_perplexity_api(query: str) -> dict | None:
@@ -419,7 +421,7 @@ def extract_image_keywords(headline: str) -> str:
- Handles edge cases (empty, only stop words, special characters)
"""
if not headline or not headline.strip():
return "news technology"
return "ai machine learning deep learning"
# Normalize: remove special characters, keep alphanumeric and spaces
cleaned = re.sub(r"[^\w\s]", " ", headline)
@@ -433,7 +435,7 @@ def extract_image_keywords(headline: str) -> str:
keywords = keywords[:5]
if not keywords:
return "news technology"
return "ai machine learning deep learning"
return " ".join(keywords)
@@ -465,7 +467,7 @@ async def fetch_pixabay_image(query: str) -> tuple[str | None, str | None]:
except Exception:
logger.exception("Pixabay image retrieval failed")
return None, None
return GENERIC_AI_FALLBACK_URL, "Generic AI fallback"
async def fetch_unsplash_image(query: str) -> tuple[str | None, str | None]:
@@ -569,7 +571,9 @@ _PROVIDER_REGISTRY: dict[str, tuple] = {
}
def get_enabled_providers() -> list[tuple[str, callable]]:
def get_enabled_providers() -> list[
tuple[str, Callable[[str], Awaitable[tuple[str | None, str | None]]]]
]:
"""Get ordered list of enabled providers based on config and available API keys."""
provider_names = [
p.strip().lower() for p in config.ROYALTY_IMAGE_PROVIDERS.split(",") if p.strip()
@@ -663,8 +667,16 @@ async def download_and_optimize_image(image_url: str) -> str | None:
return None
async def fetch_news_with_retry(max_attempts: int = 3) -> list[dict]:
async def fetch_news_with_retry(
max_attempts: int = 3, article_count: int | None = None
) -> list[dict]:
query = "What are the latest AI news from the last hour? Include source URLs and image URLs."
if article_count is not None:
bounded = max(1, min(50, int(article_count)))
query = (
f"What are the latest AI news from the last hour? Return exactly {bounded} items. "
"Include source URLs and image URLs."
)
for attempt in range(max_attempts):
try:
@@ -687,8 +699,8 @@ async def fetch_news_with_retry(max_attempts: int = 3) -> list[dict]:
return []
async def process_and_store_news() -> int:
items = await fetch_news_with_retry()
async def process_and_store_news(article_count: int | None = None) -> int:
items = await fetch_news_with_retry(article_count=article_count)
if not items:
logger.warning("No news items fetched this cycle")
return 0