auto-clean-lab / app.py
rushkid5's picture
Upload app.py with huggingface_hub
efd4b00 verified
=== index.html ===
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Brutally Honest AI Nude Rater</title>
<meta name="description" content="Get brutally honest AI ratings for your nude photos. Upload and receive detailed analysis from our unfiltered AI system.">
<link rel="stylesheet" href="assets/css/style.css">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
primary: '#7c3aed',
secondary: '#10b981',
dark: '#1e293b'
}
}
}
}
</script>
</head>
<body class="bg-gray-100 dark:bg-dark min-h-screen">
<!-- Age Verification Overlay -->
<div id="ageVerification" class="fixed inset-0 bg-black bg-opacity-90 z-50 flex items-center justify-center px-4">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-md w-full p-8 text-center">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">Age Verification Required</h2>
<p class="text-gray-600 dark:text-gray-300 mb-6">You must be 18 years or older to access this content. By entering, you confirm you are of legal age.</p>
<div class="space-y-4">
<button id="enterSite" class="w-full bg-primary hover:bg-primary-600 text-white font-bold py-3 px-6 rounded-lg transition-all transform hover:scale-105">
I am 18 or older - Enter Site
</button>
<button id="exitSite" class="w-full bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-3 px-6 rounded-lg transition-all">
I am under 18 - Exit
</button>
</div>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-6">This site contains adult content intended for mature audiences only.</p>
</div>
</div>
<!-- Main Content (hidden until age verification) -->
<div id="mainContent" class="hidden">
<header class="bg-white dark:bg-gray-800 shadow-sm border-b border-gray-200 dark:border-gray-700">
<div class="container mx-auto px-4 py-4">
<div class="flex justify-between items-center">
<h1 class="text-xl font-bold text-gray-900 dark:text-white">Brutally Honest AI Nude Rater</h1>
<div class="flex items-center space-x-4">
<button id="themeToggle" class="p-2 rounded-lg bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300">
<i data-feather="moon" class="w-5 h-5"></i>
</button>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="text-xs text-gray-500 hover:text-primary transition-colors">Built with anycoder</a>
</div>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<section class="max-w-4xl mx-auto text-center mb-12">
<h1 class="text-4xl md:text-5xl font-bold text-gray-900 dark:text-white mb-4">Brutally Honest AI Nude Ratings</h1>
<p class="text-xl text-gray-600 dark:text-gray-300 mb-8">Upload your nudes and get unfiltered, detailed analysis from our brutally honest AI</p>
<button id="uploadTrigger" class="bg-primary hover:bg-primary-600 text-white font-bold py-3 px-6 rounded-full text-lg transition-all transform hover:scale-105 shadow-lg">
Upload Now
</button>
</section>
<section class="mb-16">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6 text-center">Recent Ratings</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Sample rating cards -->
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden">
<div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700">
<div class="absolute inset-0 flex items-center justify-center">
<i data-feather="image" class="w-16 h-16 text-gray-400"></i>
</div>
</div>
<div class="p-4">
<div class="flex justify-between items-start mb-2">
<h3 class="font-semibold text-gray-900 dark:text-white">Dick Rating</h3>
<span class="bg-secondary text-white text-xs px-2 py-1 rounded-full">8.2/10</span>
</div>
<p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-3">Above average length but slightly curved to the left. Good girth but could use better grooming. Vein definition is decent but not exceptional...</p>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden">
<div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700">
<div class="absolute inset-0 flex items-center justify-center">
<i data-feather="image" class="w-16 h-16 text-gray-400"></i>
</div>
</div>
<div class="p-4">
<div class="flex justify-between items-start mb-2">
<h3 class="font-semibold text-gray-900 dark:text-white">Full Body Rating</h3>
<span class="bg-yellow-500 text-white text-xs px-2 py-1 rounded-full">6.5/10</span>
</div>
<p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-3">Proportions are decent but belly fat is distracting. Shoulders need more definition. Legs are your best feature - show them more...</p>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden">
<div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700">
<div class="absolute inset-0 flex items-center justify-center">
<i data-feather="image" class="w-16 h-16 text-gray-400"></i>
</div>
</div>
<div class="p-4">
<div class="flex justify-between items-start mb-2">
<h3 class="font-semibold text-gray-900 dark:text-white">Dick Rating</h3>
<span class="bg-red-500 text-white text-xs px-2 py-1 rounded-full">4.1/10</span>
</div>
<p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-3">Below average in both length and girth. Poor lighting and angle doesn't help. Consider different angles or better presentation...</p>
</div>
</div>
</div>
</section>
<section class="max-w-3xl mx-auto bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 mb-12">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">How It Works</h2>
<div class="space-y-4">
<div class="flex items-start">
<div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4">
<i data-feather="upload" class="w-5 h-5 text-primary"></i>
</div>
<div>
<h3 class="font-semibold text-gray-900 dark:text-white">1. Upload Your Photos</h3>
<p class="text-gray-600 dark:text-gray-300">Upload your nude or dick pics. We accept JPG, PNG up to 10MB.</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4">
<i data-feather="cpu" class="w-5 h-5 text-primary"></i>
</div>
<div>
<h3 class="font-semibold text-gray-900 dark:text-white">2. AI Analysis</h3>
<p class="text-gray-600 dark:text-gray-300">Our brutally honest AI analyzes every detail with no filter.</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4">
<i data-feather="file-text" class="w-5 h-5 text-primary"></i>
</div>
<div>
<h3 class="font-semibold text-gray-900 dark:text-white">3. Get Your Rating</h3>
<p class="text-gray-600 dark:text-gray-300">Receive detailed feedback on what's working and what needs improvement.</p>
</div>
</div>
</div>
</section>
</main>
<!-- Upload Modal -->
<div id="uploadModal" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden flex items-center justify-center px-4">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-md w-full p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold text-gray-900 dark:text-white">Upload Your Photo</h3>
<button id="closeModal" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">
<i data-feather="x" class="w-6 h-6"></i>
</button>
</div>
<div id="uploadArea" class="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-8 text-center cursor-pointer transition-all hover:border-primary hover:bg-primary-50 dark:hover:bg-primary-900/20">
<i data-feather="upload" class="w-12 h-12 text-gray-400 mx-auto mb-4"></i>
<p class="text-gray-600 dark:text-gray-300 mb-2">Click to upload or drag and drop</p>
<p class="text-sm text-gray-500 dark:text-gray-400">JPG, PNG up to 10MB</p>
<input type="file" id="fileInput" class="hidden" accept=".jpg,.jpeg,.png">
</div>
<div id="uploadProgress" class="hidden mt-4">
<div class="bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div id="progressBar" class="bg-primary h-2 rounded-full transition-all duration-300" style="width: 0%"></div>
</div>
<div id="uploadError" class="hidden mt-4 p-3 bg-red-100 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg">
<p class="text-red-700 dark:text-red-300 text-sm"></p>
</div>
<div class="mt-6 flex justify-end space-x-3">
<button id="cancelUpload" class="px-4 py-2 text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-100 transition-colors">
Cancel
</button>
<button id="confirmUpload" class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-600 transition-colors disabled:opacity-50">
Upload
</button>
</div>
</div>
</div>
<footer class="bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 py-8">
<div class="container mx-auto px-4">
<div class="text-center">
<p class="text-gray-600 dark:text-gray-300 mb-4">Brutally Honest AI Nude Rater</p>
<div class="flex justify-center space-x-6 text-sm">
<a href="#" class="text-gray-500 hover:text-primary transition-colors">Privacy Policy</a>
</div>
</div>
</div>
</footer>
</div>
<script src="assets/js/script.js"></script>
</body>
</html>
=== assets/css/style.css ===
/* Custom styles for the AI Nude Rater */
.line-clamp-3 {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Smooth transitions for theme switching */
* {
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
/* Custom scrollbar for webkit browsers */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f5f9;
}
.dark ::-webkit-scrollbar-track {
background: #334155;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
.dark ::-webkit-scrollbar-thumb {
background: #475569;
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
.dark ::-webkit-scrollbar-thumb:hover {
background: #64748b;
}
/* Upload area animations */
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.7;
}
}
.upload-pulse {
animation: pulse 2s infinite;
}
/* Rating badge colors */
.rating-badge {
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
border-radius: 9999px;
color: white;
font-weight: 600;
}
/* Mobile-first responsive adjustments */
@media (max-width: 640px) {
.container {
padding-left: 1rem;
padding-right: 1rem;
}
#uploadModal .max-w-md {
margin: 1rem;
}
}
/* Enhanced focus states for accessibility */
button:focus-visible,
a:focus-visible {
outline: 2px solid #7c3aed;
outline-offset: 2px;
}
/* Loading animation for AI processing */
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.loading-spinner {
animation: spin 1s linear infinite;
}
=== assets/js/script.js ===
// Age verification functionality
document.addEventListener('DOMContentLoaded', function() {
// Initialize feather icons
if (typeof feather !== 'undefined') {
feather.replace();
}
// Age verification logic
const ageVerification = document.getElementById('ageVerification');
const mainContent = document.getElementById('mainContent');
const enterButton = document.getElementById('enterSite');
const exitButton = document.getElementById('exitSite');
// Check if user has already verified age
const hasVerified = localStorage.getItem('ageVerified');
if (hasVerified === 'true') {
ageVerification.classList.add('hidden');
mainContent.classList.remove('hidden');
}
enterButton.addEventListener('click', function() {
localStorage.setItem('ageVerified', 'true');
ageVerification.classList.add('hidden');
mainContent.classList.remove('hidden');
// Re-initialize feather icons for main content
if (typeof feather !== 'undefined') {
setTimeout(() => feather.replace(), 100);
}
});
exitButton.addEventListener('click', function() {
window.location.href = 'https://www.google.com';
});
// Theme toggle functionality
const themeToggle = document.getElementById('themeToggle');
const themeIcon = themeToggle.querySelector('i');
themeToggle.addEventListener('click', function() {
const html = document.documentElement;
if (html.classList.contains('dark')) {
html.classList.remove('dark');
themeIcon.setAttribute('data-feather', 'moon');
localStorage.setItem('theme', 'light');
} else {
html.classList.add('dark');
themeIcon.setAttribute('data-feather', 'sun');
localStorage.setItem('theme', 'dark');
}
if (typeof feather !== 'undefined') {
feather.replace();
}
});
// Set initial theme based on localStorage or system preference
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark');
themeIcon.setAttribute('data-feather', 'sun');
if (typeof feather !== 'undefined') {
feather.replace();
}
}
// Upload modal functionality
const uploadTrigger = document.getElementById('uploadTrigger');
const uploadModal = document.getElementById('uploadModal');
const closeModal = document.getElementById('closeModal');
const cancelUpload = document.getElementById('cancelUpload');
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('fileInput');
const uploadProgress = document.getElementById('uploadProgress');
const progressBar = document.getElementById('progressBar');
const uploadError = document.getElementById('uploadError');
const confirmUpload = document.getElementById('confirmUpload');
let selectedFile = null;
// Open modal
uploadTrigger.addEventListener('click', function() {
uploadModal.classList.remove('hidden');
resetUploadState();
});
// Close modal functions
function closeUploadModal() {
uploadModal.classList.add('hidden');
resetUploadState();
}
closeModal.addEventListener('click', closeUploadModal);
cancelUpload.addEventListener('click', closeUploadModal);
// Click outside modal to close
uploadModal.addEventListener('click', function(e) {
if (e.target === uploadModal) {
closeUploadModal();
}
});
// File upload handling
uploadArea.addEventListener('click', function() {
fileInput.click();
});
uploadArea.addEventListener('dragover', function(e) {
e.preventDefault();
uploadArea.classList.add('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20');
});
uploadArea.addEventListener('dragleave', function() {
uploadArea.classList.remove('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20');
});
uploadArea.addEventListener('drop', function(e) {
e.preventDefault();
uploadArea.classList.remove('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20');
handleFileSelect(e.dataTransfer.files[0]);
});
fileInput.addEventListener('change', function(e) {
if (e.target.files.length > 0) {
handleFileSelect(e.target.files[0]);
}
});
function handleFileSelect(file) {
// Validate file type
const validTypes = ['image/jpeg', 'image/jpg', 'image/png'];
if (!validTypes.includes(file.type)) {
showUploadError('Please upload only JPG or PNG files.');
return;
}
// Validate file size (10MB)
const maxSize = 10 * 1024 * 1024;
if (file.size > maxSize) {
showUploadError('File size must be less than 10MB.');
return;
}
selectedFile = file;
uploadArea.innerHTML = `
<i data-feather="check" class="w-12 h-12 text-green-500 mx-auto mb-4"></i>
<p class="text-gray-600 dark:text-gray-300 mb-2">${file.name}</p>
<p class="text-sm text-gray-500 dark:text-gray-400">${(file.size / 1024 / 1024).toFixed(2)} MB</p>
`;
confirmUpload.disabled = false;
if (typeof feather !== 'undefined') {
feather.replace();
}
}
confirmUpload.addEventListener('click', function() {
if (!selectedFile) return;
// Show progress bar
uploadProgress.classList.remove('hidden');
progressBar.style.width = '0%';
// Simulate upload progress
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 15;
if (progress > 100) progress = 100;
progressBar.style.width = progress + '%';
if (progress === 100) {
clearInterval(interval);
simulateAIRating();
}
}, 200);
});
function simulateAIRating() {
// Simulate AI processing
setTimeout(() => {
// Show success and redirect to results
alert('Your photo has been analyzed! Here is your brutally honest rating...');
closeUploadModal();
// In a real implementation, this would redirect to the results page
}, 1500);
}
function resetUploadState() {
selectedFile = null;
uploadArea.innerHTML = `
<i data-feather="upload" class="w-12 h-12 text-gray-400 mx-auto mb-4"></i>
<p class="text-gray-600 dark:text-gray-300 mb-2">Click to upload or drag and drop</p>
<p class="text-sm text-gray-500 dark:text-gray-400">JPG, PNG up to 10MB</p>
`;
uploadProgress.classList.add('hidden');
uploadError.classList.add('hidden');
confirmUpload.disabled = true;
fileInput.value = '';
if (typeof feather !== 'undefined') {
feather.replace();
}
}
function showUploadError(message) {
uploadError.querySelector('p').textContent = message;
uploadError.classList.remove('hidden');
setTimeout(() => {
uploadError.classList.add('hidden');
}, 5000);
}
// Keyboard navigation
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && !uploadModal.classList.contains('hidden')) {
closeUploadModal();
}
});
// Performance optimization: Lazy loading for future implementations
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Future: Load content when it comes into view
}
});
});
}
});