Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend
@ -815,8 +815,8 @@ class Car(Base):
|
|||||||
color = ""
|
color = ""
|
||||||
try:
|
try:
|
||||||
color = self.colors.exterior.name if self.colors else ""
|
color = self.colors.exterior.name if self.colors else ""
|
||||||
except Exception:
|
except Exception as e:
|
||||||
pass
|
logger.error(f"Error getting color for car {self.vin} error: {e}")
|
||||||
make = self.id_car_make.name if self.id_car_make else ""
|
make = self.id_car_make.name if self.id_car_make else ""
|
||||||
model = self.id_car_model.name if self.id_car_model else ""
|
model = self.id_car_model.name if self.id_car_model else ""
|
||||||
year = self.year if self.year else 0
|
year = self.year if self.year else 0
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -1291,30 +1292,39 @@ def handle_car_image(sender, instance, created, **kwargs):
|
|||||||
try:
|
try:
|
||||||
# Create or get car image record
|
# Create or get car image record
|
||||||
car = instance.car
|
car = instance.car
|
||||||
car_image, created = models.CarImage.objects.get_or_create(
|
car.hash = car.get_hash
|
||||||
car=car, defaults={"image_hash": car.get_hash}
|
car.save()
|
||||||
)
|
# car_image, created = models.CarImage.objects.get_or_create(
|
||||||
|
# car=car, defaults={"image_hash": car.get_hash}
|
||||||
|
# )
|
||||||
|
|
||||||
# Check for existing image with same hash
|
# Check for existing image with same hash
|
||||||
existing = (
|
existing = os.path.exists(os.path.join(settings.MEDIA_ROOT, "car_images",car.get_hash + ".png"))
|
||||||
models.CarImage.objects.filter(
|
# existing = (
|
||||||
image_hash=car_image.image_hash, image__isnull=False
|
# models.CarImage.objects.filter(
|
||||||
)
|
# image_hash=car.get_hash, image__isnull=False
|
||||||
.exclude(car=car)
|
# )
|
||||||
.first()
|
# .first()
|
||||||
)
|
# )
|
||||||
|
|
||||||
if existing:
|
if existing:
|
||||||
|
logger.info(f"Found existing image for car {car.vin}")
|
||||||
# Copy existing image
|
# Copy existing image
|
||||||
car_image.image.save(existing.image.name, existing.image.file, save=True)
|
# car_image.image.save(existing.image.name, existing.image.file, save=True)
|
||||||
logger.info(f"Reused image for car {car.vin}")
|
logger.info(f"Reused image for car {car.vin}")
|
||||||
else:
|
else:
|
||||||
|
logger.info(f"Generating image for car {car.vin}")
|
||||||
# Schedule async generation
|
# Schedule async generation
|
||||||
async_task(
|
async_task(
|
||||||
"inventory.tasks.generate_car_image_task",
|
"inventory.tasks.generate_car_image_task",
|
||||||
car_image.id,
|
car.pk,
|
||||||
task_name=f"generate_car_image_{car.vin}",
|
task_name=f"generate_car_image_{car.vin}",
|
||||||
)
|
)
|
||||||
|
# async_task(
|
||||||
|
# "inventory.tasks.generate_car_image_task",
|
||||||
|
# car_image.id,
|
||||||
|
# task_name=f"generate_car_image_{car.vin}",
|
||||||
|
# )
|
||||||
logger.info(f"Scheduled image generation for car {car.vin}")
|
logger.info(f"Scheduled image generation for car {car.vin}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -29,6 +29,7 @@ from inventory.models import (
|
|||||||
CarReservation,
|
CarReservation,
|
||||||
CarStatusChoices,
|
CarStatusChoices,
|
||||||
CarImage,
|
CarImage,
|
||||||
|
Car
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -981,8 +982,9 @@ def generate_car_image_task(car_image_id):
|
|||||||
from inventory.utils import generate_car_image_simple
|
from inventory.utils import generate_car_image_simple
|
||||||
|
|
||||||
try:
|
try:
|
||||||
car_image = CarImage.objects.get(id=car_image_id)
|
# car_image = CarImage.objects.get(id=car_image_id)
|
||||||
result = generate_car_image_simple(car_image)
|
car = Car.objects.get(pk=car_image_id)
|
||||||
|
result = generate_car_image_simple(car)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": result.get("success", False),
|
"success": result.get("success", False),
|
||||||
@ -992,11 +994,6 @@ def generate_car_image_task(car_image_id):
|
|||||||
if result.get("success")
|
if result.get("success")
|
||||||
else "Generation failed",
|
else "Generation failed",
|
||||||
}
|
}
|
||||||
|
|
||||||
except CarImage.DoesNotExist:
|
|
||||||
error_msg = f"CarImage with id {car_image_id} not found"
|
|
||||||
logger.error(error_msg)
|
|
||||||
return {"success": False, "error": error_msg}
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_msg = f"Unexpected error: {e}"
|
error_msg = f"Unexpected error: {e}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
import json
|
import json
|
||||||
import secrets
|
import secrets
|
||||||
import logging
|
import logging
|
||||||
@ -2519,7 +2520,7 @@ class CarImageAPIClient:
|
|||||||
"X-CSRFToken": self.csrf_token,
|
"X-CSRFToken": self.csrf_token,
|
||||||
"Referer": self.BASE_URL,
|
"Referer": self.BASE_URL,
|
||||||
}
|
}
|
||||||
print(payload)
|
logger.info(f"Generating image with payload: {payload}")
|
||||||
generate_data = {
|
generate_data = {
|
||||||
"year": payload["year"],
|
"year": payload["year"],
|
||||||
"make": payload["make"],
|
"make": payload["make"],
|
||||||
@ -2541,6 +2542,7 @@ class CarImageAPIClient:
|
|||||||
# Parse response
|
# Parse response
|
||||||
result = response.json()
|
result = response.json()
|
||||||
image_url = result.get("url")
|
image_url = result.get("url")
|
||||||
|
logger.info(f"Generated image URL: {image_url}")
|
||||||
|
|
||||||
if not image_url:
|
if not image_url:
|
||||||
raise Exception("No image URL in response")
|
raise Exception("No image URL in response")
|
||||||
@ -2617,11 +2619,10 @@ def resize_image(image_data, max_size=(800, 600)):
|
|||||||
return None, error_msg
|
return None, error_msg
|
||||||
|
|
||||||
|
|
||||||
def generate_car_image_simple(car_image):
|
def generate_car_image_simple(car):
|
||||||
"""
|
"""
|
||||||
Simple function to generate car image with authentication and resizing
|
Simple function to generate car image with authentication and resizing
|
||||||
"""
|
"""
|
||||||
car = car_image.car
|
|
||||||
|
|
||||||
# Prepare payload
|
# Prepare payload
|
||||||
payload = {
|
payload = {
|
||||||
@ -2659,12 +2660,15 @@ def generate_car_image_simple(car_image):
|
|||||||
file_extension = "jpg"
|
file_extension = "jpg"
|
||||||
|
|
||||||
# Save the resized image
|
# Save the resized image
|
||||||
car_image.image.save(
|
logger.info(f" {car.vin}")
|
||||||
f"{car_image.image_hash}.{file_extension}",
|
with open(
|
||||||
ContentFile(resized_data),
|
os.path.join(settings.MEDIA_ROOT, f"car_images/{car.get_hash}.{file_extension}"),
|
||||||
save=False,
|
"wb",
|
||||||
)
|
) as f:
|
||||||
|
f.write(resized_data)
|
||||||
|
logger.info(f"Saved image for car {car.vin}")
|
||||||
|
|
||||||
|
# Update CarImage record
|
||||||
logger.info(f"Successfully generated and resized image for car {car.vin}")
|
logger.info(f"Successfully generated and resized image for car {car.vin}")
|
||||||
return {"success": True}
|
return {"success": True}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 418 KiB |
|
After Width: | Height: | Size: 390 KiB |
|
Before Width: | Height: | Size: 432 KiB |
|
Before Width: | Height: | Size: 401 KiB |
|
Before Width: | Height: | Size: 422 KiB |
|
Before Width: | Height: | Size: 448 KiB |
|
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 364 KiB |
|
Before Width: | Height: | Size: 327 KiB |
|
Before Width: | Height: | Size: 431 KiB |
|
Before Width: | Height: | Size: 401 KiB |
|
Before Width: | Height: | Size: 412 KiB |
|
Before Width: | Height: | Size: 422 KiB |
|
Before Width: | Height: | Size: 398 KiB |
|
Before Width: | Height: | Size: 438 KiB |
@ -17,6 +17,12 @@
|
|||||||
{% if form.name.help_text %}<small class="form-text text-muted">{{ form.name.help_text }}</small>{% endif %}
|
{% if form.name.help_text %}<small class="form-text text-muted">{{ form.name.help_text }}</small>{% endif %}
|
||||||
{% for error in form.name.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
{% for error in form.name.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ form.active.label_tag }}
|
||||||
|
{{ form.active }}
|
||||||
|
{% if form.active.help_text %}<small class="form-text text-muted">{{ form.active.help_text }}</small>{% endif %}
|
||||||
|
{% for error in form.active.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||||
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
{{ form.description.label_tag }}
|
{{ form.description.label_tag }}
|
||||||
{{ form.description|add_class:"form-control" }}
|
{{ form.description|add_class:"form-control" }}
|
||||||
|
|||||||