diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 69a6b19..3fec2a3 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index f74125d..2b5aa39 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 500c278..7b260f0 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/migrations/0003_studioconfig_cgiasset_assigned_artist_and_more.py b/core/migrations/0003_studioconfig_cgiasset_assigned_artist_and_more.py new file mode 100644 index 0000000..295d47f --- /dev/null +++ b/core/migrations/0003_studioconfig_cgiasset_assigned_artist_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 5.2.7 on 2026-02-16 00:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_alter_pipelinestep_name'), + ] + + operations = [ + migrations.CreateModel( + name='StudioConfig', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('admin_access_key', models.CharField(max_length=100, unique=True)), + ('is_setup', models.BooleanField(default=False)), + ], + ), + migrations.AddField( + model_name='cgiasset', + name='assigned_artist', + field=models.CharField(blank=True, max_length=100), + ), + migrations.AddField( + model_name='cgiasset', + name='file_location', + field=models.CharField(blank=True, help_text='Path or URL to the digital file', max_length=500), + ), + migrations.AddField( + model_name='cgiasset', + name='version', + field=models.PositiveIntegerField(default=1), + ), + ] diff --git a/core/migrations/__pycache__/0003_studioconfig_cgiasset_assigned_artist_and_more.cpython-311.pyc b/core/migrations/__pycache__/0003_studioconfig_cgiasset_assigned_artist_and_more.cpython-311.pyc new file mode 100644 index 0000000..f36064c Binary files /dev/null and b/core/migrations/__pycache__/0003_studioconfig_cgiasset_assigned_artist_and_more.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 9b7a9e0..de6be32 100644 --- a/core/models.py +++ b/core/models.py @@ -1,5 +1,19 @@ from django.db import models from django.utils.text import slugify +import uuid + +class StudioConfig(models.Model): + """Singleton model to store studio-wide settings and the unique admin key.""" + admin_access_key = models.CharField(max_length=100, unique=True) + is_setup = models.BooleanField(default=False) + + def save(self, *args, **kwargs): + if not self.admin_access_key: + self.admin_access_key = str(uuid.uuid4()) + super().save(*args, **kwargs) + + def __str__(self): + return "Studio Configuration" class Project(models.Model): TYPES = ( @@ -72,6 +86,9 @@ class CgiAsset(models.Model): asset_type = models.CharField(max_length=10, choices=ASSET_TYPES) is_realistic = models.BooleanField(default=True) current_stage = models.CharField(max_length=100, default='Modeling') + version = models.PositiveIntegerField(default=1) + file_location = models.CharField(max_length=500, blank=True, help_text="Path or URL to the digital file") + assigned_artist = models.CharField(max_length=100, blank=True) def __str__(self): - return f"{self.name} ({self.get_asset_type_display()})" \ No newline at end of file + return f"{self.name} ({self.get_asset_type_display()})" diff --git a/core/templates/base.html b/core/templates/base.html index a656bcd..b40e57e 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,3 +1,4 @@ +{% load static %} @@ -7,15 +8,17 @@ - + + + {% block extra_head %}{% endblock %} @@ -38,7 +55,7 @@
+ {% if messages %} +
+ {% for message in messages %} +
+ {{ message }} +
+ {% endfor %} +
+ {% endif %} {% block content %}{% endblock %}
@@ -71,4 +100,4 @@ {% block extra_js %}{% endblock %} - + \ No newline at end of file diff --git a/core/templates/core/admin_login.html b/core/templates/core/admin_login.html new file mode 100644 index 0000000..7bfa4fc --- /dev/null +++ b/core/templates/core/admin_login.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block content %} +
+
+
+ +

Acesso Restrito

+

Insira sua Chave Privada de Administrador para prosseguir.

+
+ +
+ {% csrf_token %} +
+ +
+ +
+ + +
+
+ + +{% endblock %} diff --git a/core/templates/core/asset_library.html b/core/templates/core/asset_library.html new file mode 100644 index 0000000..40b6400 --- /dev/null +++ b/core/templates/core/asset_library.html @@ -0,0 +1,89 @@ +{% extends "base.html" %} + +{% block content %} +
+ +
+
+

Biblioteca de Assets

+

Catálogo central de personagens, cenários e objetos digitais.

+
+
+ Total de Assets + {{ assets|length }} +
+
+ + + + +
+ +
+
+ {% for asset in assets %} +
+
+
+
+ {{ asset.get_asset_type_display }} + v{{ asset.version }} +
+
{{ asset.name }}
+

Projeto: {{ asset.project.title }}

+ +
+ {{ asset.current_stage }} +
+
+
+
+ {% empty %} +
+

Nenhum asset cadastrado ainda.

+
+ {% endfor %} +
+
+ + +
+
+ {% for asset in asset_types.CHAR %} +
+ +
+
+
{{ asset.name }}
+

{{ asset.project.title }}

+
+
+
+ {% endfor %} +
+
+ +
+
+ + +{% endblock %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index d224271..07aa9a3 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,181 +1,101 @@ {% extends "base.html" %} -{% load static %} - -{% block title %}Command Center | Studio CGI Virtual{% endblock %} {% block content %} -
-
-
- NEXT-GEN CGI PIPELINE +
+ +
+
+

STUDIO COMMAND CENTER

+

Gerenciamento de Super-Produções CGI

-

Studio de Cinema Virtual

-

- A fábrica digital para super-produções. Gerencie do roteiro à renderização em um fluxo de produção rigoroso e colaborativo. -

-
- Acessar Produções - Nova Super-Produção + +
+
+ Projetos Ativos + {{ active_productions }} +
+
+ Status do Sistema + ONLINE +
-
-
-
-
-
-
- Total de Projetos - {{ total_projects }} + +
+
+
+ +
+ {% if is_admin %} + MODO ADMIN + Sair + {% else %} + + Acesso Restrito + + {% endif %}
-
-
- Produções Ativas - {{ active_productions }} -
-
-
-
- Obras Finalizadas - {{ completed_projects }} -
-
-
- -
-
-

Produções em Andamento

-

Status em tempo real do pipeline CGI

-
-
- -
- {% for project in projects %} -
-
-
- {{ project.get_status_display }} - {{ project.get_project_type_display }} -
- -

- - {{ project.title }} - -

- -

- {{ project.description|default:"Sem descrição definida para esta super-produção."|truncatewords:20 }} -

- -
-
- Progresso do Pipeline - {% with last_step=project.steps.last %} - {{ last_step.progress|default:0 }}% - {% endwith %} -
-
- {% with last_step=project.steps.last %} -
- {% endwith %} -
- -
- {% for step in project.steps.all|slice:":4" %} - - {{ step.get_name_display }} - - {% endfor %} - {% if project.steps.count > 4 %} - +{{ project.steps.count|add:"-4" }} - {% endif %} -
-
- - -
-
- {% empty %} -
-
- - - - -
-

Nenhuma produção ativa

-

Comece sua primeira super-produção 3D agora.

- Iniciar Projeto -
- {% endfor %}
-
-
-
-
-
-

Pipeline CGI Profissional

-

Nosso estúdio segue o fluxo de trabalho dos maiores estúdios de Hollywood, garantindo qualidade em cada quadro.

-
-
-
-

Pré-produção

-

Roteiro, Concept Art e Animatic para definir a alma do filme.

-
-
-
-
-

Produção

-

Modelagem, Rigging e Animação com personagens realistas.

-
-
-
-
-

Iluminação & FX

-

Simulação de partículas, fluidos e luzes cinematográficas.

-
-
-
-
-

Pós-produção

-

Renderização em render farm e composição final.

-
-
-
-
-
-
-
-
-
-
-
+ +
+ {% for project in projects %} +
+
+
+
+ {% if project.thumbnail_url %} + {{ project.title }} + {% else %} +
+
-

Status da Render Farm

-
-
- Nodes Ativos - 128 / 128 -
-
- CPU Load - 94% -
-
- Tempo Estimado - 04:12:33 -
-
-
+ {% endif %} +
+
+
+
+

{{ project.title }}

+ + {{ project.get_status_display }} + +
+

{{ project.description|truncatewords:20 }}

+ + +
+
+ Progresso Geral + 85% +
+
+
+
+
+ + + Ver Pipeline Detalhado +
+ {% endfor %}
-
-{% endblock %} \ No newline at end of file + + + +{% endblock %} diff --git a/core/urls.py b/core/urls.py index b9e0a07..dc67e2f 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,10 @@ from django.urls import path -from .views import home, project_detail +from .views import home, project_detail, asset_library, admin_login, admin_logout urlpatterns = [ path("", home, name="home"), path("project//", project_detail, name="project_detail"), -] \ No newline at end of file + path("assets/", asset_library, name="asset_library"), + path("studio-admin/login/", admin_login, name="admin_login"), + path("studio-admin/logout/", admin_logout, name="admin_logout"), +] diff --git a/core/views.py b/core/views.py index 9e5fe2c..e0f522a 100644 --- a/core/views.py +++ b/core/views.py @@ -1,17 +1,31 @@ import os import platform - +from functools import wraps from django import get_version as django_version -from django.shortcuts import render, get_object_or_404 +from django.shortcuts import render, get_object_or_404, redirect from django.utils import timezone -from .models import Project, PipelineStep, CgiAsset +from django.contrib import messages +from .models import Project, PipelineStep, CgiAsset, StudioConfig +def studio_admin_required(view_func): + """Decorator to restrict access to studio admin only.""" + @wraps(view_func) + def _wrapped_view(request, *args, **kwargs): + if not request.session.get('is_studio_admin', False): + messages.warning(request, "Acesso restrito. Por favor, insira sua chave de administrador.") + return redirect('admin_login') + return view_func(request, *args, **kwargs) + return _wrapped_view def home(request): """Render the CGI Studio Command Center.""" + # Ensure StudioConfig exists and generate key if needed + config, created = StudioConfig.objects.get_or_create(id=1) + if created or not config.admin_access_key: + config.save() # Triggers uuid generation + projects = Project.objects.prefetch_related('steps').all() - # Simple statistics for the dashboard total_projects = projects.count() active_productions = projects.filter(status='PROD').count() completed_projects = projects.filter(status='DONE').count() @@ -22,9 +36,48 @@ def home(request): "active_productions": active_productions, "completed_projects": completed_projects, "current_time": timezone.now(), + "is_admin": request.session.get('is_studio_admin', False), } return render(request, "core/index.html", context) +def admin_login(request): + """View to enter the unique admin access key.""" + if request.method == "POST": + key = request.POST.get("access_key") + try: + config = StudioConfig.objects.get(id=1) + if key == config.admin_access_key: + request.session['is_studio_admin'] = True + messages.success(request, "Bem-vindo, Comandante do Estúdio!") + return redirect('home') + else: + messages.error(request, "Chave de acesso inválida.") + except StudioConfig.DoesNotExist: + messages.error(request, "Configuração do estúdio não encontrada.") + + return render(request, "core/admin_login.html") + +def admin_logout(request): + """Logout the studio admin.""" + request.session['is_studio_admin'] = False + return redirect('home') + +@studio_admin_required +def asset_library(request): + """View all digital assets (Characters, Props, Environments).""" + assets = CgiAsset.objects.select_related('project').all() + asset_types = { + 'CHAR': assets.filter(asset_type='CHAR'), + 'PROP': assets.filter(asset_type='PROP'), + 'ENV': assets.filter(asset_type='ENV'), + } + + context = { + "assets": assets, + "asset_types": asset_types, + } + return render(request, "core/asset_library.html", context) + def project_detail(request, slug): """Render the detailed pipeline for a specific production.""" project = get_object_or_404(Project.objects.prefetch_related('steps', 'assets'), slug=slug) @@ -34,4 +87,4 @@ def project_detail(request, slug): "steps": project.steps.all(), "assets": project.assets.all(), } - return render(request, "core/project_detail.html", context) \ No newline at end of file + return render(request, "core/project_detail.html", context)