36173-vm/core/views.py
Flatlogic Bot 33d53234ea 1.0
2025-11-24 07:57:57 +00:00

187 lines
7.1 KiB
Python

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')