FCT / services /domain_plugins /creative_plugin.py
Parthnuwal7
Adding analytical content
3d015cd
"""Creative/Design Domain Plugin
Scores creative competency based on:
- Portfolio links (Behance, Dribbble, personal site)
- Project diversity and quality
- Design tool proficiency
- Visual content analysis
"""
import re
import time
import logging
import requests
from typing import Dict, List
from .base_plugin import BaseDomainPlugin, DomainScore
from .plugin_factory import register_plugin
logger = logging.getLogger(__name__)
@register_plugin('creative')
class CreativePlugin(BaseDomainPlugin):
"""Creative/Design domain scoring plugin"""
def __init__(self):
super().__init__()
# Design tools and platforms
self.design_tools = [
'figma', 'sketch', 'adobe xd', 'photoshop', 'illustrator',
'after effects', 'premiere pro', 'blender', 'cinema 4d'
]
self.portfolio_platforms = ['behance', 'dribbble', 'artstation', 'deviantart']
def _get_domain_type(self) -> str:
return 'creative'
def _get_feature_weights(self) -> Dict[str, float]:
return {
'portfolio_quality': 0.35,
'project_diversity': 0.25,
'tool_proficiency': 0.20,
'platform_presence': 0.15,
'description_depth': 0.05
}
def get_required_fields(self) -> List[str]:
return ['portfolio_url']
def get_optional_fields(self) -> List[str]:
return ['behance_url', 'dribbble_url', 'design_tools_text', 'project_description']
def score(self, evidence_data: Dict) -> DomainScore:
"""Calculate creative domain score"""
start_time = time.time()
features = {}
# Portfolio analysis
portfolio_url = evidence_data.get('portfolio_url', '')
if portfolio_url:
features['portfolio_quality'] = self._analyze_portfolio_quality(portfolio_url)
else:
features['portfolio_quality'] = 0.0
# Platform presence
behance_url = evidence_data.get('behance_url', '')
dribbble_url = evidence_data.get('dribbble_url', '')
features['platform_presence'] = self._check_platform_presence(behance_url, dribbble_url)
# Tool proficiency
tools_text = evidence_data.get('design_tools_text', '')
features['tool_proficiency'] = self._assess_tool_proficiency(tools_text)
# Project diversity and description
project_desc = evidence_data.get('project_description', '')
features['project_diversity'] = self._assess_project_diversity(project_desc)
features['description_depth'] = self._assess_description_depth(project_desc)
# Calculate weighted score
score = sum(features[k] * self.feature_weights[k] for k in features.keys())
# Calculate confidence
confidence = self.calculate_confidence(evidence_data)
processing_time = (time.time() - start_time) * 1000
return DomainScore(
domain_type='creative',
score=min(score, 1.0),
confidence=confidence,
raw_features=features,
processing_time_ms=processing_time
)
def _analyze_portfolio_quality(self, portfolio_url: str) -> float:
"""
Analyze portfolio website quality
Returns: 0-1 score based on accessibility and professionalism
"""
try:
if not portfolio_url.startswith(('http://', 'https://')):
portfolio_url = 'https://' + portfolio_url
response = requests.head(portfolio_url, timeout=5, allow_redirects=True)
if response.status_code == 200:
score = 0.6 # Base score for accessible portfolio
# Bonus for professional platforms
if any(platform in portfolio_url for platform in self.portfolio_platforms):
score += 0.2
# Bonus for custom domain
if not any(free in portfolio_url for free in ['github.io', 'wixsite', 'wordpress.com']):
score += 0.2
logger.info(f"Portfolio quality: {score:.2f}")
return min(score, 1.0)
else:
return 0.2
except Exception as e:
logger.error(f"Error analyzing portfolio: {e}")
return 0.2
def _check_platform_presence(self, behance_url: str, dribbble_url: str) -> float:
"""
Check presence on design platforms
Returns: 0-1 score based on platform profiles
"""
score = 0.0
# Behance presence
if behance_url and 'behance.net' in behance_url:
try:
response = requests.head(behance_url, timeout=5, allow_redirects=True)
if response.status_code == 200:
score += 0.5
except:
score += 0.2 # Partial credit for providing URL
# Dribbble presence
if dribbble_url and 'dribbble.com' in dribbble_url:
try:
response = requests.head(dribbble_url, timeout=5, allow_redirects=True)
if response.status_code == 200:
score += 0.5
except:
score += 0.2
logger.info(f"Platform presence: {score:.2f}")
return min(score, 1.0)
def _assess_tool_proficiency(self, tools_text: str) -> float:
"""
Assess design tool proficiency
Returns: 0-1 score based on tool mentions
"""
if not tools_text:
return 0.0
text_lower = tools_text.lower()
# Count tool mentions
tool_count = sum(1 for tool in self.design_tools if tool in text_lower)
# Score based on tool diversity
score = min(tool_count / 5, 1.0) # 5+ tools = max
# Bonus for professional tools (Adobe, Figma)
pro_tools = ['figma', 'adobe', 'sketch']
if any(tool in text_lower for tool in pro_tools):
score = min(score + 0.2, 1.0)
logger.info(f"Tool proficiency: {score:.2f} ({tool_count} tools)")
return score
def _assess_project_diversity(self, project_desc: str) -> float:
"""
Assess project type diversity
Returns: 0-1 score based on project variety
"""
if not project_desc:
return 0.0
text_lower = project_desc.lower()
# Project type categories
project_types = [
'ui design', 'ux design', 'branding', 'logo', 'illustration',
'animation', '3d', 'web design', 'mobile app', 'poster',
'packaging', 'typography', 'infographic', 'video editing'
]
type_count = sum(1 for ptype in project_types if ptype in text_lower)
score = min(type_count / 6, 1.0) # 6+ types = max
logger.info(f"Project diversity: {score:.2f} ({type_count} types)")
return score
def _assess_description_depth(self, project_desc: str) -> float:
"""
Assess depth of project descriptions
Returns: 0-1 score based on detail level
"""
if not project_desc or len(project_desc) < 50:
return 0.0
score = min(len(project_desc) / 1000, 1.0) # 1000+ chars = max
logger.info(f"Description depth: {score:.2f}")
return score