38413-vm/core/views.py
2026-02-14 01:45:08 +00:00

293 lines
11 KiB
Python

import json
import random
import string
import uuid
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.utils import timezone
from datetime import timedelta
from django.http import JsonResponse
from .models import GameProject, UserSession, AdminConfig, RentalOption, UserPurchase
from ai.local_ai_api import LocalAIApi
# Helper to check authentication
def get_auth_status(request):
is_admin = request.session.get('is_admin', False)
user_code = request.session.get('user_code')
user = None
if user_code:
user = UserSession.objects.filter(access_code=user_code).first()
return is_admin, user
def index(request):
is_admin, user = get_auth_status(request)
if is_admin:
return redirect('admin_dashboard')
if user:
return redirect('catalog')
return render(request, 'core/index.html', {'title': 'Acesso'})
def admin_login(request):
if request.method == 'POST':
key = request.POST.get('private_key')
if AdminConfig.objects.filter(private_key=key).exists():
request.session['is_admin'] = True
request.session['user_code'] = None
return redirect('admin_dashboard')
messages.error(request, 'Chave Privada Inválida.')
return render(request, 'core/admin_login.html', {'title': 'Admin Login'})
def generate_code(request):
if request.method == 'POST':
phone = request.POST.get('phone')
# Generate 6 digit code for platform access
code = ''.join(random.choices(string.digits, k=6))
while UserSession.objects.filter(access_code=code).exists():
code = ''.join(random.choices(string.digits, k=6))
UserSession.objects.create(access_code=code, phone_number=phone)
request.session['user_code'] = code
request.session['is_admin'] = False
messages.success(request, f'Seu código de acesso é: {code}. Guarde-o bem!')
return redirect('catalog')
return redirect('index')
def recover_code(request):
if request.method == 'POST':
phone = request.POST.get('phone')
user = UserSession.objects.filter(phone_number=phone).first()
if user:
request.session['user_code'] = user.access_code
messages.success(request, f'Bem-vindo de volta! Seu código {user.access_code} foi recuperado.')
return redirect('catalog')
messages.error(request, 'Nenhum código encontrado para este telefone.')
return redirect('index')
def logout(request):
request.session.flush()
return redirect('index')
# AI Helper - PROGRAMADOR AI AUTOMATIZADO
def generate_game_script(prompt, genre):
system_prompt = (
"You are an expert game developer. Create a complete, single-file HTML/JavaScript/CSS game. "
"The game MUST be fully functional, self-contained, and playable in a browser iframe. "
"Use modern JavaScript (ES6+), HTML5 Canvas, or CSS animations. "
"The game MUST have: "
"1. A 'Start Game' screen with instructions. "
"2. Smooth controls (keyboard or touch). "
"3. A scoring system and a 'Game Over' state with a 'Restart' button. "
"4. A polished, modern visual style (dark theme preferred). "
"5. Responsive design to fit any screen size. "
"Return ONLY the raw source code starting with <!DOCTYPE html> and ending with </html>. "
"Do not include any explanations, markdown fences, or text outside the HTML tags."
)
user_prompt = f"Develop a complete {genre} game based on this request: {prompt}. Ensure it's a real, playable game."
response = LocalAIApi.create_response({
"input": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
],
})
if response.get("success"):
return LocalAIApi.extract_text(response)
return None
# ADMIN VIEWS
def admin_dashboard(request):
is_admin, _ = get_auth_status(request)
if not is_admin:
return redirect('admin_login')
projects = GameProject.objects.all().order_by('-created_at')
rental_options = RentalOption.objects.all()
return render(request, 'core/admin_dashboard.html', {
'projects': projects,
'rental_options': rental_options,
'title': 'Painel do Administrador'
})
def admin_create_game(request):
is_admin, _ = get_auth_status(request)
if not is_admin:
return redirect('admin_login')
if request.method == 'POST':
title = request.POST.get('title')
prompt = request.POST.get('prompt')
genre = request.POST.get('genre', 'arcade')
image = request.FILES.get('image')
use_ai = request.POST.get('use_ai') == 'on'
manual_script = request.POST.get('script_code', '')
script = manual_script
if use_ai and prompt:
ai_script = generate_game_script(prompt, genre)
if ai_script:
script = ai_script
else:
messages.error(request, 'Falha ao gerar o script com AI. Usando script manual ou vazio.')
project = GameProject.objects.create(
title=title,
prompt=prompt,
genre=genre,
image_reference=image,
script_code=script,
config_json={"player": {"speed": 200}, "entities": []}
)
messages.success(request, f'Jogo "{title}" criado com sucesso!')
return redirect('admin_dashboard')
return render(request, 'core/admin_game_form.html', {'title': 'Criar Novo Jogo'})
def admin_edit_game(request, pk):
is_admin, _ = get_auth_status(request)
if not is_admin:
return redirect('admin_login')
project = get_object_or_404(GameProject, pk=pk)
if request.method == 'POST':
project.title = request.POST.get('title')
project.prompt = request.POST.get('prompt')
project.genre = request.POST.get('genre')
if request.FILES.get('image'):
project.image_reference = request.FILES.get('image')
use_ai = request.POST.get('use_ai') == 'on'
manual_script = request.POST.get('script_code', '')
if use_ai and project.prompt:
ai_script = generate_game_script(project.prompt, project.genre)
if ai_script:
project.script_code = ai_script
else:
messages.error(request, 'Falha ao gerar o script com AI.')
else:
project.script_code = manual_script
project.save()
messages.success(request, f'Jogo "{project.title}" atualizado!')
return redirect('admin_dashboard')
return render(request, 'core/admin_game_form.html', {'project': project, 'title': 'Editar Jogo'})
def admin_delete_game(request, pk):
is_admin, _ = get_auth_status(request)
if not is_admin:
return redirect('admin_login')
project = get_object_or_404(GameProject, pk=pk)
project.delete()
messages.success(request, 'Jogo excluído com sucesso.')
return redirect('admin_dashboard')
def admin_edit_rental(request, pk):
is_admin, _ = get_auth_status(request)
if not is_admin:
return redirect('admin_login')
option = get_object_or_404(RentalOption, pk=pk)
if request.method == 'POST':
option.title = request.POST.get('title')
option.price = request.POST.get('price')
option.duration_days = request.POST.get('duration_days')
if request.FILES.get('qr1'):
option.qr_code_1 = request.FILES.get('qr1')
if request.FILES.get('qr2'):
option.qr_code_2 = request.FILES.get('qr2')
option.save()
messages.success(request, 'Opção de aluguel atualizada.')
return redirect('admin_dashboard')
return render(request, 'core/admin_rental_form.html', {'option': option, 'title': 'Editar Preço'})
# USER VIEWS
def catalog(request):
is_admin, user = get_auth_status(request)
if not user and not is_admin:
return redirect('index')
projects = GameProject.objects.filter(is_active=True).order_by('-created_at')
return render(request, 'core/catalog.html', {'projects': projects, 'title': 'Catálogo de Jogos'})
def purchase_game(request, pk):
is_admin, user = get_auth_status(request)
if not user:
return redirect('index')
game = get_object_or_404(GameProject, pk=pk)
options = RentalOption.objects.all()
if request.method == 'POST':
confirm_code = request.POST.get('confirm_code')
purchase_id = request.POST.get('purchase_id')
purchase = get_object_or_404(UserPurchase, pk=purchase_id, user_session=user)
if confirm_code == purchase.confirmation_code:
purchase.is_confirmed = True
purchase.save()
messages.success(request, f'Pagamento confirmado! Aproveite o jogo.')
return redirect('play_game', pk=game.pk)
else:
messages.error(request, 'Código de confirmação incorreto.')
return render(request, 'core/purchase.html', {
'game': game,
'options': options,
'title': f'Alugar {game.title}'
})
def generate_purchase(request, game_pk, option_pk):
is_admin, user = get_auth_status(request)
if not user:
return JsonResponse({'success': False, 'error': 'Unauthorized'})
game = get_object_or_404(GameProject, pk=game_pk)
option = get_object_or_404(RentalOption, pk=option_pk)
# Generate 6 digit confirmation code (as requested)
conf_code = ''.join(random.choices(string.digits, k=6))
expires = timezone.now() + timedelta(days=option.duration_days)
purchase = UserPurchase.objects.create(
user_session=user,
game=game,
rental_option=option,
confirmation_code=conf_code,
expires_at=expires,
is_confirmed=False
)
return JsonResponse({
'success': True,
'purchase_id': purchase.id,
'confirmation_code': conf_code
})
def play_game(request, pk):
is_admin, user = get_auth_status(request)
if not user and not is_admin:
return redirect('index')
game = get_object_or_404(GameProject, pk=pk)
if not is_admin:
# Check if user has active purchase
purchase = UserPurchase.objects.filter(
user_session=user,
game=game,
expires_at__gt=timezone.now(),
is_confirmed=True
).first()
if not purchase:
messages.error(request, 'Você não tem tempo de jogo para este título.')
return redirect('purchase_game', pk=game.pk)
return render(request, 'core/play.html', {'game': game, 'title': f'Jogando {game.title}'})