from concurrent.futures import ThreadPoolExecutor from django.shortcuts import render, redirect from django.urls import reverse from plants.models import Species from plants.services.perenual import search_species as perenual_search, PerenualError from plants.services import vpc as vpc_service from plants.services.vpc import VPCError _MONTH_MAP = { 'January': 1, 'February': 2, 'March': 3, 'April': 4, 'May': 5, 'June': 6, 'July': 7, 'August': 8, 'September': 9, 'October': 10, 'November': 11, 'December': 12, } def species_search(request): q = request.GET.get('q', '').strip() perenual_results = [] vpc_results = [] error = None if len(q) >= 2: def _run_perenual(): try: return perenual_search(q), None except PerenualError as e: return [], str(e) def _run_vpc(): try: return vpc_service.search_species(q) except VPCError: return [] with ThreadPoolExecutor(max_workers=2) as ex: f_p = ex.submit(_run_perenual) f_v = ex.submit(_run_vpc) perenual_results, error = f_p.result() vpc_results = f_v.result() return render(request, 'plants/partials/species_results.html', { 'perenual_results': perenual_results, 'vpc_results': vpc_results, 'q': q, 'error': error, }) def species_select(request): perenual_id = int(request.POST['perenual_id']) if not Species.objects.filter(perenual_id=perenual_id).exists(): pruning_str = request.POST.get('pruning_months', '') pruning_months = [ _MONTH_MAP[m.strip()] for m in pruning_str.split(',') if m.strip() in _MONTH_MAP ] Species.objects.create( perenual_id=perenual_id, common_name=request.POST.get('common_name', ''), scientific_name=request.POST.get('scientific_name', ''), watering=request.POST.get('watering', ''), sunlight=request.POST.get('sunlight', ''), pruning_months=pruning_months, api_image_url=request.POST.get('api_image_url', ''), ) species = Species.objects.get(perenual_id=perenual_id) return redirect(f"{reverse('plant_add')}?species_id={species.pk}") def vpc_select(request): slug = request.POST.get('vpc_slug', '').strip() if not slug: return redirect(reverse('plant_add')) existing = Species.objects.filter(vpc_slug=slug).first() if existing: return redirect(f"{reverse('plant_add')}?species_id={existing.pk}") try: data = vpc_service.scrape_plant(slug) except VPCError: # Fall back to plant_add without species pre-fill return redirect(f"{reverse('plant_add')}?species_id=skip") species = Species.objects.create( common_name=data['common_name'], scientific_name=data['scientific_name'], bloom_months=data['bloom_months'], max_height_cm=data['max_height_cm'], sunlight=data['sunlight'], growth_rate=data['growth_rate'], description=data['description'], api_image_url=data['api_image_url'], vpc_slug=slug, ) return redirect(f"{reverse('plant_add')}?species_id={species.pk}")