""" Forms for OSINT app. """ import json from django import forms from django.core.exceptions import ValidationError from .models import SeedWebsite, OSINTKeyword class SeedWebsiteForm(forms.ModelForm): """Form for creating/editing seed websites.""" allowed_domains_text = forms.CharField( required=False, widget=forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': 'Enter domains separated by commas or as JSON array, e.g. example.com, subdomain.example.com\nOr: ["example.com", "subdomain.example.com"]' }), help_text='Enter domains separated by commas or as JSON array. Leave empty for same domain only.' ) class Meta: model = SeedWebsite fields = [ 'name', 'url', 'description', 'is_active', 'priority', 'crawl_depth', 'crawl_interval_hours', 'user_agent' ] widgets = { 'name': forms.TextInput(attrs={'class': 'form-control'}), 'url': forms.URLInput(attrs={'class': 'form-control'}), 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'priority': forms.Select(attrs={'class': 'form-control'}), 'crawl_depth': forms.NumberInput(attrs={'class': 'form-control', 'min': 0, 'max': 5}), 'crawl_interval_hours': forms.NumberInput(attrs={'class': 'form-control', 'min': 1}), 'user_agent': forms.TextInput(attrs={'class': 'form-control'}), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.instance and self.instance.pk and self.instance.allowed_domains: # Convert list to text representation if isinstance(self.instance.allowed_domains, list): self.fields['allowed_domains_text'].initial = ', '.join(self.instance.allowed_domains) else: self.fields['allowed_domains_text'].initial = str(self.instance.allowed_domains) def clean_allowed_domains_text(self): text = self.cleaned_data.get('allowed_domains_text', '').strip() if not text: return [] # Try to parse as JSON first try: domains = json.loads(text) if isinstance(domains, list): return [str(d).strip() for d in domains if d] except (json.JSONDecodeError, ValueError): pass # Otherwise, treat as comma-separated domains = [d.strip() for d in text.split(',') if d.strip()] return domains def save(self, commit=True): instance = super().save(commit=False) instance.allowed_domains = self.cleaned_data.get('allowed_domains_text', []) if commit: instance.save() return instance class OSINTKeywordForm(forms.ModelForm): """Form for creating/editing OSINT keywords.""" class Meta: model = OSINTKeyword fields = [ 'name', 'keyword', 'description', 'keyword_type', 'is_active', 'case_sensitive', 'confidence_score', 'auto_approve' ] widgets = { 'name': forms.TextInput(attrs={'class': 'form-control'}), 'keyword': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}), 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}), 'keyword_type': forms.Select(attrs={'class': 'form-control'}), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'case_sensitive': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'confidence_score': forms.NumberInput(attrs={ 'class': 'form-control', 'min': 0, 'max': 100, 'step': 1 }), 'auto_approve': forms.CheckboxInput(attrs={'class': 'form-check-input'}), }