diff --git a/backend/ads/tasks.py b/backend/ads/tasks.py index 586907a..97a4b41 100644 --- a/backend/ads/tasks.py +++ b/backend/ads/tasks.py @@ -2,6 +2,7 @@ import os import re import json import html +import logging import requests from openai import OpenAI, AuthenticationError from pydantic import BaseModel, Field @@ -9,6 +10,8 @@ from celery import shared_task from django.utils import timezone from ads.models import Ad, AdEvaluation, NotificationLog +logger = logging.getLogger(__name__) + # Pydantic model for strict OpenAI structured output format class AdEvaluationResult(BaseModel): is_flagged: bool = Field(description="True if the ad matches the criteria in the prompt, otherwise False") diff --git a/backend/config/settings.py b/backend/config/settings.py index 97ab6c7..7accda6 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -27,10 +27,27 @@ load_dotenv(BASE_DIR.parent / '.env') # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', 'django-insecure-@8*97xo5!gdi!x*94-%n8$b63%ljy#@&^#7$h!9v-4a2#r+98t') -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = os.getenv('DJANGO_DEBUG', 'True').lower() in ('true', '1', 't') +# Environment setup (development / production) +# Reads DEV=True/False or ENVIRONMENT='development'/'production' +ENVIRONMENT = os.getenv('ENVIRONMENT', os.getenv('DJANGO_ENV', 'development')).lower() +IS_DEV = os.getenv('DEV', 'True' if ENVIRONMENT in ('development', 'dev') else 'False').lower() in ('true', '1', 't') + +if IS_DEV: + DEBUG = True + ALLOWED_HOSTS = ['*'] + CORS_ALLOW_ALL_ORIGINS = True + CSRF_TRUSTED_ORIGINS = [ + 'http://localhost:5173', 'http://localhost:8000', 'http://127.0.0.1:8000', 'http://localhost', 'http://127.0.0.1' + ] +else: + DEBUG = os.getenv('DJANGO_DEBUG', 'False').lower() in ('true', '1', 't') + ALLOWED_HOSTS = [host.strip() for host in os.getenv('ALLOWED_HOSTS', '*').split(',') if host.strip()] + CORS_ALLOW_ALL_ORIGINS = os.getenv('CORS_ALLOW_ALL_ORIGINS', 'False').lower() in ('true', '1', 't') + if not CORS_ALLOW_ALL_ORIGINS: + CORS_ALLOWED_ORIGINS = [origin.strip() for origin in os.getenv('CORS_ALLOWED_ORIGINS', '').split(',') if origin.strip()] + csrf_origins = os.getenv('CSRF_TRUSTED_ORIGINS', 'http://localhost,http://127.0.0.1') + CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in csrf_origins.split(',') if origin.strip()] -ALLOWED_HOSTS = [host.strip() for host in os.getenv('ALLOWED_HOSTS', '*').split(',') if host.strip()] # Application definition @@ -201,3 +218,50 @@ CELERY_BEAT_SCHEDULE = { }, } +# Standard Logging System Configuration +LOG_LEVEL = os.getenv('LOG_LEVEL', 'DEBUG' if IS_DEV else 'INFO') + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'verbose': { + 'format': '[{asctime}] [{levelname}] [{name}:{lineno}] {message}', + 'style': '{', + 'datefmt': '%Y-%m-%d %H:%M:%S', + }, + 'simple': { + 'format': '{levelname} {message}', + 'style': '{', + }, + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'formatter': 'verbose', + }, + }, + 'root': { + 'handlers': ['console'], + 'level': LOG_LEVEL, + }, + 'loggers': { + 'django': { + 'handlers': ['console'], + 'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'), + 'propagate': False, + }, + 'crawler': { + 'handlers': ['console'], + 'level': LOG_LEVEL, + 'propagate': False, + }, + 'ads': { + 'handlers': ['console'], + 'level': LOG_LEVEL, + 'propagate': False, + }, + }, +} + + diff --git a/backend/crawler/tasks.py b/backend/crawler/tasks.py index 240156a..445db27 100644 --- a/backend/crawler/tasks.py +++ b/backend/crawler/tasks.py @@ -1,5 +1,6 @@ import re import json +import logging import requests import urllib.parse from urllib.parse import urlparse @@ -8,6 +9,8 @@ from celery import shared_task from crawler.models import CrawlRun, CrawlTask from ads.models import Ad, AdEvaluation +logger = logging.getLogger(__name__) + def parse_divar_url(divar_url): """ Parses a public Divar search link to extract city, category path, diff --git a/backend/crawler/views.py b/backend/crawler/views.py index 0362cfe..1aa4c7f 100644 --- a/backend/crawler/views.py +++ b/backend/crawler/views.py @@ -1,9 +1,12 @@ +import logging from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from .models import CrawlTask, CrawlRun from .serializers import CrawlTaskSerializer, CrawlRunSerializer +logger = logging.getLogger(__name__) + class CrawlTaskViewSet(viewsets.ModelViewSet): """ ViewSet for CrawlTask models. Supports CRUD and custom trigger/runs actions.