from django.shortcuts import render, get_object_or_404, redirect from .models import Incident, Brand from .forms import IncidentForm from ai.local_ai_api import LocalAIApi import json import requests from bs4 import BeautifulSoup from django.contrib.auth.decorators import login_required, user_passes_test from django.views.generic import ListView, CreateView, UpdateView, DeleteView from django.utils.decorators import method_decorator from django.urls import reverse_lazy, reverse @login_required def home(request): # Get the brands associated with the current user user_brands = request.user.brands.all() # Filter incidents to only those associated with the user's brands incidents = Incident.objects.filter(brand__in=user_brands) # Calculate stats total_incidents = incidents.count() new_incidents = incidents.filter(status='new').count() in_review_incidents = incidents.filter(status='in_review').count() resolved_incidents = incidents.filter(status='resolved').count() dismissed_incidents = incidents.filter(status='dismissed').count() context = { 'incidents': incidents, 'total_incidents': total_incidents, 'new_incidents': new_incidents, 'in_review_incidents': in_review_incidents, 'resolved_incidents': resolved_incidents, 'dismissed_incidents': dismissed_incidents, } return render(request, "core/index.html", context) @login_required def article_detail(request, id): # Fetch the specific incident from the database incident = get_object_or_404(Incident, pk=id) prompt = f"""Analyze the following incident and provide a summary, a sentiment analysis (Positive, Negative, or Neutral), and a list of suggested remediation steps. Incident: {incident.content} Return the analysis in JSON format with three keys: 'summary', 'sentiment', and 'suggested_steps' (which should be a list of strings). """ ai_response = LocalAIApi.create_response( { "input": [ {"role": "system", "content": "You are a brand protection assistant."}, {"role": "user", "content": prompt}, ], } ) ai_analysis = {"summary": "AI analysis is currently unavailable.", "sentiment": "Unknown", "suggested_steps": []} if ai_response.get("success"): text = LocalAIApi.extract_text(ai_response) try: # Ensure the extracted text is valid JSON ai_analysis = json.loads(text) # Ensure all keys are present if 'summary' not in ai_analysis: ai_analysis['summary'] = "No summary provided." if 'sentiment' not in ai_analysis: ai_analysis['sentiment'] = "Unknown" if 'suggested_steps' not in ai_analysis: ai_analysis['suggested_steps'] = [] except (json.JSONDecodeError, TypeError): # If the AI response is not valid JSON, use it as the summary ai_analysis["summary"] = text if text else "Could not retrieve AI analysis." return render(request, "core/article_detail.html", {"incident": incident, "ai_analysis": ai_analysis}) # A check to see if the user is a staff member def is_staff(user): return user.is_staff @method_decorator(login_required, name='dispatch') class BrandListView(ListView): model = Brand template_name = 'core/brand_list.html' context_object_name = 'brands' def get_queryset(self): return self.request.user.brands.all() @method_decorator(login_required, name='dispatch') class BrandCreateView(CreateView): model = Brand template_name = 'core/brand_form.html' fields = ['name', 'website', 'logo_url'] success_url = reverse_lazy('brand-list') def form_valid(self, form): self.object = form.save() self.object.users.add(self.request.user) return super().form_valid(form) @method_decorator(login_required, name='dispatch') class BrandUpdateView(UpdateView): model = Brand template_name = 'core/brand_form.html' fields = ['name', 'website', 'logo_url'] success_url = reverse_lazy('brand-list') def get_queryset(self): return self.request.user.brands.all() @method_decorator(login_required, name='dispatch') class BrandDeleteView(DeleteView): model = Brand template_name = 'core/brand_confirm_delete.html' success_url = reverse_lazy('brand-list') def get_queryset(self): return self.request.user.brands.all() @login_required def dismiss_incident(request, incident_id): incident = get_object_or_404(Incident, pk=incident_id) # Check if the user has permission to dismiss this incident if incident.brand in request.user.brands.all(): incident.status = 'dismissed' incident.save() return redirect('home') @method_decorator(login_required, name='dispatch') class IncidentCreateView(CreateView): model = Incident form_class = IncidentForm template_name = 'core/incident_form.html' success_url = reverse_lazy('home') def get_form_kwargs(self): kwargs = super(IncidentCreateView, self).get_form_kwargs() kwargs['user'] = self.request.user return kwargs @login_required def autofill_incident_from_url(request): if request.method == 'POST': url = request.POST.get('url') try: response = requests.get(url, timeout=10) response.raise_for_status() # Raise an exception for bad status codes soup = BeautifulSoup(response.content, 'html.parser') page_text = soup.get_text() prompt = f"""Analyze the following text from a webpage and extract information to create a brand protection incident report. Identify the type of incident, and a summary of the content. Webpage content: {page_text[:4000]} Return the analysis in JSON format with two keys: 'incident_type' (choose from {Incident.INCIDENT_TYPE_CHOICES}) and 'content'. """ ai_response = LocalAIApi.create_response( { "input": [ {"role": "system", "content": "You are a brand protection assistant that extracts information from webpages."}, {"role": "user", "content": prompt}, ], } ) if ai_response.get("success"): text = LocalAIApi.extract_text(ai_response) try: ai_data = json.loads(text) initial_data = { 'source_url': url, 'incident_type': ai_data.get('incident_type'), 'content': ai_data.get('content'), } form = IncidentForm(initial=initial_data, user=request.user) return render(request, 'core/incident_form.html', {'form': form}) except (json.JSONDecodeError, TypeError): # Handle cases where AI response is not as expected pass # You might want to add a message to the user except requests.RequestException as e: # Handle network errors pass # You might want to add a message to the user return render(request, 'core/autofill_incident_form.html')