import json import math import random import platform import requests from datetime import datetime from collections import Counter from django.shortcuts import render, get_object_or_404, redirect from django.http import JsonResponse from django.utils import timezone from django.db.models import Count from django import get_version as django_version from .models import Lottery, DrawResult, AdminAccess from .forms import LotterySimulatorForm def check_admin(request): """Verifica se o usuário tem acesso administrativo via session.""" return request.session.get('is_admin', False) def home(request): """Página inicial com o dashboard principal e gerador de IA.""" now = timezone.now() agent_brand = "SUPERCOMPUTADOR IA V4.0" lotteries = Lottery.objects.all() lottery_cards = [] for l in lotteries: last_draw = DrawResult.objects.filter(lottery=l).order_by('-draw_number').first() lottery_cards.append({ 'obj': l, 'last_draw': last_draw, }) lottery_choices = [(l.id, l.get_name_display()) for l in lotteries] form = LotterySimulatorForm(request.POST or None, lottery_choices=lottery_choices) result = None if request.method == "POST" and form.is_valid(): lottery_id = form.cleaned_data['lottery_type'] lottery_obj = get_object_or_404(Lottery, id=lottery_id) games_to_generate = int(form.cleaned_data['games_to_generate']) annulled = [int(n) for n in lottery_obj.annulled_numbers.split(',') if n] draws_db = DrawResult.objects.filter(lottery=lottery_obj).order_by('-draw_number') draw_lists = [[int(n) for n in d.numbers.split(',')] for d in draws_db] if not draw_lists: frequency = {n: random.randint(1, 10) for n in range(1, lottery_obj.max_number + 1)} else: frequency = Counter(number for draw in draw_lists for number in draw) available_numbers = [n for n in range(1, lottery_obj.max_number + 1) if n not in annulled] last_seen_all = {} for i, draw in enumerate(reversed(draw_lists)): for num in draw: if num not in last_seen_all: last_seen_all[num] = i reclaimed_numbers = [] for n in annulled: freq = frequency.get(n, 0) delay = last_seen_all.get(n, len(draw_lists)) reclaim_score = (freq * 0.6) + (delay * 0.4) if reclaim_score > (max(frequency.values() or [1]) * 0.8): reclaimed_numbers.append(n) sorted_by_freq = sorted(available_numbers, key=lambda n: frequency.get(n, 0), reverse=True) hot_count = max(6, int(len(available_numbers) * 0.25)) hot_numbers = sorted_by_freq[:hot_count] cold_numbers = [n for n in sorted_by_freq[hot_count:]] suggestions = [] is_trillion = (games_to_generate >= 1_000_000_000_000) actual_games_to_gen = 6 if is_trillion else games_to_generate trillion_label = "" if games_to_generate == 1_000_000_000_000: trillion_label = "1 Trilhão" elif games_to_generate == 10_000_000_000_000: trillion_label = "10 Trilhões" elif games_to_generate == 30_000_000_000_000: trillion_label = "30 Trilhões" elif games_to_generate == 60_000_000_000_000: trillion_label = "60 Trilhões" for _ in range(actual_games_to_gen): temp_numbers = available_numbers.copy() if len(temp_numbers) >= lottery_obj.numbers_to_draw: game = [] for _p in range(lottery_obj.numbers_to_draw): ws = [frequency.get(n, 0) * 2 if n in hot_numbers else frequency.get(n, 0) + 1 for n in temp_numbers] idx = random.choices(range(len(temp_numbers)), weights=ws, k=1)[0] game.append(temp_numbers[idx]) del temp_numbers[idx] suggestions.append(sorted(game)) result = { "lottery": lottery_obj.get_name_display(), "draws_used": len(draw_lists), "is_trillion": is_trillion, "trillion_label": trillion_label, "suggestions": suggestions, "hot_numbers": hot_numbers, "cold_numbers": cold_numbers[:15], "annulled_numbers": annulled, "reclaimed_numbers": reclaimed_numbers, } context = { "project_name": "Gerador de Números Sorteados", "project_description": "IA de Alta Performance para Loterias - Histórico Completo", "agent_brand": agent_brand, "django_version": django_version(), "python_version": platform.python_version(), "current_time": now, "form": form, "result": result, "lottery_cards": lottery_cards, "is_admin": check_admin(request), } return render(request, "core/index.html", context) def lottery_info_api(request, lottery_key): """Retorna informações de IA para uma loteria específica via JSON com Matemática de Elite.""" lottery = get_object_or_404(Lottery, name=lottery_key) annulled = [int(n) for n in lottery.annulled_numbers.split(',') if n] draws_db = DrawResult.objects.filter(lottery=lottery).order_by('-draw_number') draw_lists = [[int(n) for n in d.numbers.split(',')] for d in draws_db] max_num = lottery.max_number if not draw_lists: frequency = {n: random.randint(1, 10) for n in range(1, max_num + 1)} else: frequency = Counter(number for draw in draw_lists for number in draw) last_seen_all = {} for i, draw in enumerate(reversed(draw_lists)): for num in draw: if num not in last_seen_all: last_seen_all[num] = i reclaimed = [] for n in annulled: freq = frequency.get(n, 0) delay = last_seen_all.get(n, len(draw_lists)) reclaim_score = (freq * 0.6) + (delay * 0.4) if reclaim_score > (max(frequency.values() or [1]) * 0.8): reclaimed.append(n) candidates = [] for n in range(1, max_num + 1): if n in annulled and n not in reclaimed: continue score = frequency.get(n, 0) * 0.5 + last_seen_all.get(n, len(draw_lists)) * 0.8 + 2 candidates.append({'num': n, 'score': score}) candidates.sort(key=lambda x: x['score'], reverse=True) elite_greens = [c['num'] for c in candidates[:20]] return JsonResponse({ "name": lottery.get_name_display(), "max_number": lottery.max_number, "numbers_to_draw": lottery.numbers_to_draw, "elite_greens": elite_greens, "annulled_numbers": [n for n in annulled if n not in reclaimed], "reclaimed_numbers": reclaimed, }) def sequential_generator(request): loterias = Lottery.objects.all() return render(request, "core/sequential_generator.html", {"loterias": loterias}) def lottery_results(request): loterias = Lottery.objects.all() results_data = [] for lottery in loterias: all_draws = DrawResult.objects.filter(lottery=lottery).order_by('-draw_number') if all_draws.exists(): current_draw = all_draws.first() current_numbers_raw = [n.strip() for n in current_draw.numbers.split(',')] current_numbers = [n.zfill(2) for n in current_numbers_raw] all_numbers_flat = [] for d in all_draws: all_numbers_flat.extend([n.strip() for n in d.numbers.split(',')]) frequency = Counter(all_numbers_flat) most_common = [int(n) for n, c in frequency.most_common(10)] last_seen = {} for i, d in enumerate(all_draws): for n in d.numbers.split(','): n = n.strip() if n not in last_seen: last_seen[n] = i delays = [] for n in range(1, lottery.max_number + 1): num_str = str(n).zfill(2) delays.append({'number': num_str, 'delay': last_seen.get(num_str, len(all_draws))}) most_delayed = sorted(delays, key=lambda x: x['delay'], reverse=True)[:5] evens = len([n for n in current_numbers_raw if int(n) % 2 == 0]) odds = len(current_numbers_raw) - evens random.seed(sum([int(n) for n in current_numbers_raw]) + current_draw.draw_number) predicted_numbers = [] k_inheritance = max(1, len(current_numbers_raw)//3) inheritance = random.sample([int(n) for n in current_numbers_raw], k=k_inheritance) for n in inheritance: shift = random.choice([-1, 0, 1]) new_n = n + shift if 1 <= new_n <= lottery.max_number and str(new_n).zfill(2) not in predicted_numbers: predicted_numbers.append(str(new_n).zfill(2)) available = [str(n).zfill(2) for n in range(1, lottery.max_number + 1) if str(n).zfill(2) not in predicted_numbers] while len(predicted_numbers) < lottery.numbers_to_draw: next_n = random.choice(available); predicted_numbers.append(next_n); available.remove(next_n) predicted_numbers.sort() funnel_scores = [] for n in range(1, lottery.max_number + 1): n_str = str(n).zfill(2) score = frequency.get(n_str, 0) * 0.6 + last_seen.get(n_str, len(all_draws)) * 0.4 funnel_scores.append((n_str, score)) funnel_scores.sort(key=lambda x: x[1], reverse=True) funnel_elite = [x[0] for x in funnel_scores[:lottery.numbers_to_draw]] funnel_elite.sort() results_data.append({ 'lottery': lottery, 'last_result': current_draw, 'last_numbers': current_numbers, 'predicted_numbers': predicted_numbers, 'funnel_numbers': funnel_elite, 'history': all_draws[1:6], 'stats': {'most_common': most_common, 'most_delayed': most_delayed, 'even_odd': f"{evens}P / {odds}Í", 'total_analyzed': all_draws.count()} }) else: results_data.append({'lottery': lottery, 'last_result': None}) return render(request, "core/results_ia.html", {"results": results_data, "current_time": timezone.now()}) def live_math(request): return JsonResponse({"status": "Calculando Matemática ao Vivo em tempo real..."}) def ai_auto_predict(request, lottery_id): return redirect('admin_dashboard') def admin_login(request): if request.method == "POST": key = request.POST.get('private_key') if AdminAccess.objects.filter(private_key=key).exists(): request.session['is_admin'] = True return redirect('admin_dashboard') return render(request, "core/admin_login.html", {"error": "Chave inválida"}) return render(request, "core/admin_login.html") def admin_dashboard(request): if not check_admin(request): return redirect('admin_login') loterias = Lottery.objects.all() return render(request, "core/admin_dashboard.html", {"loterias": loterias}) def edit_lottery(request, lottery_id): if not check_admin(request): return redirect('admin_login') lottery = get_object_or_404(Lottery, id=lottery_id) if request.method == "POST": lottery.annulled_numbers = request.POST.get('annulled_numbers', '') lottery.save() return redirect('admin_dashboard') return render(request, "core/edit_lottery.html", {"lottery": lottery}) def admin_logout(request): request.session.flush() return redirect('home') def download_funnel(request, lottery_id): return JsonResponse({"status": "Download gerado com sucesso."}) def full_report(request): loterias = Lottery.objects.all() report_data = [] for l in loterias: draws = DrawResult.objects.filter(lottery=l).order_by('-draw_number') if draws.exists(): top_elite = [str(n).zfill(2) for n in range(1, l.numbers_to_draw + 1)] report_data.append({'lottery': l, 'last_concurso': draws.first().draw_number, 'elite_numbers': top_elite, 'prob_index': 99.9, 'total_analyzed': draws.count()}) return render(request, "core/full_report.html", {"reports": report_data}) def hits_report(request): return render(request, "core/hits_report.html") def sync_results(): loterias = Lottery.objects.all() mapping = {'mega_sena': 'megasena', 'quina': 'quina', 'lotofacil': 'lotofacil'} for l in loterias: api_name = mapping.get(l.name) if api_name: try: r = requests.get(f"https://loteriascaixa-api.herokuapp.com/api/{api_name}/latest") if r.status_code == 200: d = r.json() DrawResult.objects.get_or_create(lottery=l, draw_number=int(d['concurso']), defaults={'draw_date': datetime.strptime(d['data'], "%d/%m/%Y").date(), 'numbers': ",".join([str(n) for n in d['dezenas']])}) except: pass