Browse Source

docs: Adiciona documentação completa de deploy do módulo TCE

• INSTRUCOES_DEPLOY_TCE.md: Guia detalhado de instalação
• RESUMO_ALTERACOES_TCE.md: Resumo executivo das alterações
• scripts/install_tce_module.sh: Script de instalação automatizada

Inclui:
- Lista de dependências Python (pyhanko, pyhanko-certvalidator)
- Instruções passo a passo para produção
- Checklist de deploy
- Troubleshooting
- Comandos de verificação

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
pull/3858/head
rangelbruno 12 months ago
parent
commit
88b81c2ac0
  1. 272
      INSTRUCOES_DEPLOY_TCE.md
  2. 273
      RESUMO_ALTERACOES_TCE.md
  3. 246
      scripts/install_tce_module.sh

272
INSTRUCOES_DEPLOY_TCE.md

@ -0,0 +1,272 @@
# Instruções de Deploy - Módulo TCE
## 📋 Resumo das Alterações
O módulo TCE foi implementado com funcionalidades de:
- Upload e organização de arquivos por processo/pasta/subpasta
- Verificação de tamanho de arquivos (≤5MB)
- Aplicação de OCR (preparado, mas simulado)
- **Assinatura digital com certificado A1 (.pfx)** - IMPLEMENTADO
- Geração de arquivos .p7s
- Visualização de PDFs
## 🔧 Instalação no Servidor de Produção
### 1. Atualizar o Código
```bash
cd /caminho/do/sapl
git pull origin 3.1.x
```
### 2. Instalar Dependências Python
```bash
# Ativar o virtualenv do SAPL (ajuste o caminho conforme necessário)
source /opt/venv/bin/activate # ou o caminho do seu venv
# Instalar bibliotecas necessárias
pip install pyhanko==0.31.0
pip install pyhanko-certvalidator==0.29.0
pip install cryptography>=43.0.3
```
**OU** use o arquivo requirements:
```bash
pip install -r /caminho/para/tce_requirements.txt
```
### 3. Executar Migrações do Banco de Dados
```bash
python manage.py migrate
```
**Migrações criadas:**
- `0001_initial.py` - Estrutura inicial (TceProcesso, TcePasta, TceArquivo, etc)
- `0002_tcearquivo_subpasta.py` - Campo subpasta em TceArquivo
- `0003_tcepasta_subpastas_customizadas.py` - Campo para subpastas customizadas
### 4. Coletar Arquivos Estáticos
```bash
python manage.py collectstatic --noinput
```
### 5. Criar Diretórios de Upload
```bash
# Criar diretórios para arquivos TCE
mkdir -p /caminho/do/media/tce/arquivos
mkdir -p /caminho/do/media/tce/reduzidos
mkdir -p /caminho/do/media/tce/ocr
mkdir -p /caminho/do/media/tce/assinados
mkdir -p /caminho/do/media/tce/p7s
# Dar permissões adequadas (ajuste o usuário conforme necessário)
chown -R www-data:www-data /caminho/do/media/tce
chmod -R 755 /caminho/do/media/tce
```
### 6. Reiniciar Serviços
```bash
# Para Apache
sudo systemctl restart apache2
# OU para Nginx + Gunicorn/uWSGI
sudo systemctl restart gunicorn # ou uwsgi
sudo systemctl restart nginx
```
## 📁 Arquivos Criados/Modificados
### Novos Arquivos:
1. **Modelos:**
- `/sapl/tce/models.py` - Modelos TceProcesso, TcePasta, TceArquivo, TceAssinatura, TceLog
2. **Views:**
- `/sapl/tce/admin_views.py` - Views e APIs do módulo TCE
3. **URLs:**
- `/sapl/tce/urls.py` - Rotas do módulo
4. **Templates:**
- `/sapl/templates/admin/tce/admin_index.html` - Dashboard TCE
- `/sapl/templates/admin/tce/processo_detail.html` - Detalhes do processo
- `/sapl/templates/admin/tce/subpasta_detail.html` - Detalhes da subpasta (com wizard de upload)
- `/sapl/templates/admin/tce/change_form.html` - Formulário admin
- `/sapl/templates/admin/tce/change_list.html` - Lista admin
- `/sapl/templates/admin/tce/app_index.html` - Índice do app
5. **Template Filters:**
- `/sapl/tce/templatetags/tce_filters.py` - Filtros customizados
6. **Migrações:**
- `/sapl/tce/migrations/0001_initial.py`
- `/sapl/tce/migrations/0002_tcearquivo_subpasta.py`
- `/sapl/tce/migrations/0003_tcepasta_subpastas_customizadas.py`
### Arquivos Modificados:
1. `/sapl/templates/admin/base_site.html` - Navbar do SAPL no admin
## 🔐 Configurações de Segurança
### Permissões de Arquivos
```python
# Em settings.py, verificar:
MEDIA_ROOT = '/caminho/do/media'
MEDIA_URL = '/media/'
# Limite de upload (opcional)
FILE_UPLOAD_MAX_MEMORY_SIZE = 5242880 # 5MB
DATA_UPLOAD_MAX_MEMORY_SIZE = 5242880 # 5MB
```
### Configuração do Servidor Web
**Para Apache (.htaccess ou VirtualHost):**
```apache
# Permitir upload de arquivos PDF e certificados
<Directory /caminho/do/media/tce>
Options -Indexes
AllowOverride None
Require all granted
# Apenas permitir acesso a arquivos específicos
<FilesMatch "\.(pdf|p7s)$">
Require all granted
</FilesMatch>
</Directory>
```
**Para Nginx:**
```nginx
location /media/tce/ {
alias /caminho/do/media/tce/;
# Apenas permitir download de PDFs e p7s
location ~ \.(pdf|p7s)$ {
add_header Content-Disposition "inline";
}
# Bloquear acesso a outros arquivos
location ~ \.(pfx|p12)$ {
deny all;
}
}
```
## 🧪 Testar a Instalação
### 1. Verificar se as bibliotecas foram instaladas:
```bash
python -c "from pyhanko.sign import signers; print('✓ PyHanko OK')"
python -c "from pyhanko_certvalidator import ValidationContext; print('✓ Certvalidator OK')"
```
### 2. Acessar o módulo:
```
http://seu-servidor.com/tce/admin/
```
### 3. Testar funcionalidades:
1. **Criar um processo** - Dashboard TCE > Novo Processo
2. **Criar pastas/subpastas** - Dentro do processo
3. **Upload de arquivo** - Com wizard de 5 abas
4. **Assinatura digital** - Na aba 4 do wizard (requer certificado .pfx)
5. **Geração .p7s** - Na aba 5 do wizard
## ⚠️ Problemas Conhecidos e Soluções
### Erro: "Biblioteca de assinatura não instalada"
**Solução:**
```bash
pip install pyhanko pyhanko-certvalidator
sudo systemctl restart gunicorn # ou seu servidor WSGI
```
### Erro de permissão ao fazer upload
**Solução:**
```bash
chown -R www-data:www-data /caminho/do/media/tce
chmod -R 755 /caminho/do/media/tce
```
### Erro 404 ao visualizar arquivo
**Solução:**
Verificar se a rota está registrada em `urls.py`:
```python
path('arquivo/<uuid:arquivo_id>/visualizar/', admin_views.visualizar_arquivo, name='visualizar_arquivo'),
```
### JSONField não encontrado (Django < 3.1)
O código já está preparado com fallback:
```python
try:
from django.db.models import JSONField
except ImportError:
from django.contrib.postgres.fields import JSONField
```
## 📊 Monitoramento
### Logs para verificar:
```bash
# Logs do Django
tail -f /var/log/sapl/django.log
# Logs do servidor web
tail -f /var/log/apache2/error.log # Apache
tail -f /var/log/nginx/error.log # Nginx
```
### Verificar uploads:
```bash
ls -lah /caminho/do/media/tce/arquivos/
ls -lah /caminho/do/media/tce/assinados/
ls -lah /caminho/do/media/tce/p7s/
```
## 🔄 Rollback (se necessário)
Se precisar reverter as alterações:
```bash
# Reverter migrações
python manage.py migrate tce 0000_initial # ou zero
# Reverter código
git revert <commit_hash>
git push
```
## 📞 Suporte
Em caso de dúvidas ou problemas:
1. Verificar logs do servidor
2. Testar em ambiente de desenvolvimento primeiro
3. Verificar se todas as dependências foram instaladas
4. Confirmar permissões de arquivos e diretórios
---
**Data de criação:** 03/10/2025
**Versão do SAPL:** 3.1.x
**Última atualização:** Após merge com branch principal

273
RESUMO_ALTERACOES_TCE.md

@ -0,0 +1,273 @@
# Resumo das Alterações - Módulo TCE
## 🎯 O que foi implementado
Sistema completo de gestão de documentos para prestação de contas ao TCE (Tribunal de Contas do Estado) com:
### Funcionalidades Principais:
1. ✅ **Gestão de Processos** - Criar processos por período (trimestral, anual, etc)
2. ✅ **Organização em Pastas** - 3 categorias padrão + pastas customizadas
3. ✅ **Subpastas Dinâmicas** - Estrutura hierárquica com subpastas customizáveis
4. ✅ **Upload com Wizard** - 5 etapas para preparação de documentos
5. ✅ **Verificação de Tamanho** - Validação ≤5MB
6. ✅ **OCR** - Preparado (simulado no frontend)
7. ✅ **Assinatura Digital Real** - Com certificado A1 (.pfx) usando PyHanko
8. ✅ **Geração .p7s** - Arquivo de assinatura destacada
9. ✅ **Visualização de PDFs** - Inline no navegador
10. ✅ **Logs e Auditoria** - Rastreamento completo de ações
---
## 📦 Para o Servidor de Produção
### **Comando Rápido (Instalação Automática):**
```bash
cd /caminho/do/sapl
./scripts/install_tce_module.sh
```
### **OU Manual:**
```bash
# 1. Atualizar código
git pull origin 3.1.x
# 2. Ativar virtualenv
source /opt/venv/bin/activate
# 3. Instalar dependências
pip install pyhanko==0.31.0 pyhanko-certvalidator==0.29.0
# 4. Migrar banco
python manage.py migrate
# 5. Criar diretórios
mkdir -p media/tce/{arquivos,assinados,p7s,ocr,reduzidos}
chown -R www-data:www-data media/tce
chmod -R 755 media/tce
# 6. Coletar estáticos
python manage.py collectstatic --noinput
# 7. Reiniciar serviço
sudo systemctl restart gunicorn # ou apache2/nginx
```
---
## 🔑 Dependências NOVAS Instaladas
### Python:
- ✅ `pyhanko==0.31.0` - Assinatura digital de PDFs
- ✅ `pyhanko-certvalidator==0.29.0` - Validação de certificados
- ✅ `cryptography>=43.0.3` - Criptografia
- ✅ `tzlocal>=5.0.0` - Timezone
- ✅ `uritools>=5.0.0` - Manipulação de URIs
### Frontend (CDN):
- ✅ Font Awesome 6.5.1 - Ícones
- ✅ SweetAlert2 - Alertas modernos
- ✅ Bootstrap (já existente) - UI
---
## 📁 Arquivos Principais Criados
### Backend:
```
sapl/tce/
├── models.py # 5 modelos (Processo, Pasta, Arquivo, Assinatura, Log)
├── admin_views.py # 10+ views e APIs
├── urls.py # Rotas do módulo
├── admin.py # Admin Django
└── migrations/
├── 0001_initial.py
├── 0002_tcearquivo_subpasta.py
└── 0003_tcepasta_subpastas_customizadas.py
```
### Frontend:
```
sapl/templates/admin/tce/
├── admin_index.html # Dashboard principal
├── processo_detail.html # Detalhes do processo
├── subpasta_detail.html # Upload wizard (5 abas)
├── change_form.html # Formulário admin
├── change_list.html # Lista admin
└── app_index.html # Índice do app
```
### Template Filters:
```
sapl/tce/templatetags/
└── tce_filters.py # Filtros customizados
```
---
## 🔄 Migrações do Banco de Dados
### 3 Migrações Criadas:
1. **0001_initial** - Estrutura base:
- TceProcesso (processos TCE)
- TcePasta (categorias/pastas)
- TceArquivo (arquivos PDF/XML)
- TceAssinatura (assinaturas digitais)
- TceLog (auditoria)
2. **0002_tcearquivo_subpasta** - Campo para subpastas
3. **0003_tcepasta_subpastas_customizadas** - Subpastas customizadas (JSON em TextField)
### Executar:
```bash
python manage.py migrate tce
```
---
## 🌐 URLs Adicionadas
```python
/tce/admin/ # Dashboard
/tce/processo/<uuid>/ # Detalhes do processo
/tce/processo/<uuid>/pasta/<uuid>/<subpasta>/ # Detalhes da subpasta
/tce/arquivo/<uuid>/visualizar/ # Visualizar PDF
/tce/api/arquivos/upload/ # Upload
/tce/api/arquivos/<uuid>/assinar/ # Assinar
/tce/api/arquivos/<uuid>/gerar-p7s/ # Gerar .p7s
/tce/api/arquivos/<uuid>/delete/ # Deletar
/tce/api/pastas/criar/ # Criar pasta
/tce/api/subpastas/adicionar/ # Adicionar subpasta
```
---
## ✅ Checklist de Deploy
- [ ] Git pull executado
- [ ] Dependências Python instaladas (`pyhanko`, `pyhanko-certvalidator`)
- [ ] Migrações executadas (`python manage.py migrate`)
- [ ] Diretórios de mídia criados (`media/tce/`)
- [ ] Permissões configuradas (755, owner www-data)
- [ ] Arquivos estáticos coletados (`collectstatic`)
- [ ] Servidor web reiniciado
- [ ] Teste de acesso: `http://servidor/tce/admin/`
- [ ] Teste de upload de arquivo
- [ ] Teste de assinatura digital (com certificado .pfx)
---
## 🧪 Como Testar
1. **Acessar:** `http://seu-servidor/tce/admin/`
2. **Criar processo:** Clicar em "Novo Processo TCE"
3. **Entrar no processo:** Ver pastas e subpastas
4. **Upload:** Clicar em "Adicionar Arquivos" em uma subpasta
5. **Wizard (5 abas):**
- Aba 1: Selecionar PDF
- Aba 2: Verificar tamanho
- Aba 3: Aplicar OCR (simulado)
- Aba 4: **Assinar digitalmente** (usar certificado .pfx + senha)
- Aba 5: Gerar .p7s
6. **Finalizar:** Arquivo aparece na lista
7. **Visualizar:** Clicar no ícone 👁️ para ver o PDF assinado
---
## 🚨 Problemas Comuns
### "Biblioteca de assinatura não instalada"
```bash
pip install pyhanko pyhanko-certvalidator
sudo systemctl restart gunicorn
```
### Erro de permissão ao fazer upload
```bash
chown -R www-data:www-data /caminho/do/media/tce
chmod -R 755 /caminho/do/media/tce
```
### Arquivo não aparece após upload
- Verificar logs: `/var/log/sapl/` ou `/var/log/apache2/error.log`
- Verificar se diretórios existem: `ls -la media/tce/`
- Verificar se migrações foram aplicadas: `python manage.py showmigrations tce`
---
## 📊 Estrutura de Dados
### Hierarquia:
```
TceProcesso (Prestação de Contas - 3º Tri/2025)
└── TcePasta (Gestão Administrativa)
└── Subpasta (Atos de pessoal)
└── TceArquivo (documento.pdf)
├── arquivo_assinado.pdf
├── documento.p7s
└── TceAssinatura (dados do certificado)
```
### Campos Principais:
**TceProcesso:**
- titulo, ano, periodo, status
- numero_protocolo (TCE)
- data_envio, recibo_tce
**TceArquivo:**
- arquivo (original)
- arquivo_assinado (com assinatura)
- arquivo_p7s (destacado)
- tamanho_ok, ocr_ok, assinado, p7s_gerado
- certificado_info (JSON)
---
## 📝 Logs e Monitoramento
### Verificar logs:
```bash
# Django
tail -f /var/log/sapl/django.log
# Servidor web
tail -f /var/log/apache2/error.log # ou nginx/error.log
# Verificar uploads
ls -lah media/tce/arquivos/
ls -lah media/tce/assinados/
```
### Django shell:
```python
python manage.py shell
from sapl.tce.models import *
# Ver processos
TceProcesso.objects.all()
# Ver arquivos
TceArquivo.objects.all()
# Ver assinaturas
TceAssinatura.objects.all()
```
---
## 📞 Documentação Completa
- 📄 `INSTRUCOES_DEPLOY_TCE.md` - Instruções detalhadas
- 🔧 `scripts/install_tce_module.sh` - Script de instalação automática
- 📋 `RESUMO_ALTERACOES_TCE.md` - Este arquivo
---
**Desenvolvido em:** Outubro/2025
**Branch:** 3.1.x
**Status:** ✅ Pronto para produção

246
scripts/install_tce_module.sh

@ -0,0 +1,246 @@
#!/bin/bash
###############################################################################
# Script de Instalação do Módulo TCE
# Versão: 1.0
# Data: 03/10/2025
###############################################################################
set -e # Parar em caso de erro
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Função para log
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Verificar se está rodando como root ou com sudo
if [ "$EUID" -eq 0 ]; then
log_warn "Rodando como root. Certifique-se de que as permissões estão corretas."
fi
###############################################################################
# 1. VERIFICAÇÕES INICIAIS
###############################################################################
log_info "Verificando ambiente..."
# Verificar se o Python está disponível
if ! command -v python3 &> /dev/null; then
log_error "Python3 não encontrado. Instale o Python 3.8 ou superior."
exit 1
fi
PYTHON_VERSION=$(python3 --version | awk '{print $2}')
log_info "Python versão: $PYTHON_VERSION"
# Verificar se o virtualenv está ativado
if [ -z "$VIRTUAL_ENV" ]; then
log_warn "Virtualenv não está ativado. Ativando..."
# Tentar encontrar o virtualenv
if [ -d "/opt/venv" ]; then
source /opt/venv/bin/activate
log_info "Virtualenv ativado: /opt/venv"
elif [ -d "venv" ]; then
source venv/bin/activate
log_info "Virtualenv ativado: venv"
else
log_error "Virtualenv não encontrado. Ative manualmente antes de executar."
exit 1
fi
fi
# Verificar se o Django está instalado
if ! python3 -c "import django" &> /dev/null; then
log_error "Django não encontrado. Instale o Django primeiro."
exit 1
fi
DJANGO_VERSION=$(python3 -c "import django; print(django.get_version())")
log_info "Django versão: $DJANGO_VERSION"
###############################################################################
# 2. INSTALAR DEPENDÊNCIAS
###############################################################################
log_info "Instalando dependências do módulo TCE..."
pip install --upgrade pip
# Instalar pyhanko e dependências
log_info "Instalando pyhanko (assinatura digital)..."
pip install pyhanko==0.31.0 pyhanko-certvalidator==0.29.0
# Instalar dependências complementares
log_info "Instalando dependências complementares..."
pip install cryptography>=43.0.3 requests>=2.31.0 python-dateutil>=2.8.0 tzlocal>=5.0.0
# Verificar instalação
log_info "Verificando instalação das bibliotecas..."
python3 -c "from pyhanko.sign import signers; print('✓ PyHanko instalado com sucesso')" || {
log_error "Falha ao instalar pyhanko"
exit 1
}
python3 -c "from pyhanko_certvalidator import ValidationContext; print('✓ Certvalidator instalado com sucesso')" || {
log_error "Falha ao instalar pyhanko-certvalidator"
exit 1
}
###############################################################################
# 3. EXECUTAR MIGRAÇÕES
###############################################################################
log_info "Executando migrações do banco de dados..."
python3 manage.py migrate tce
log_info "Migrações concluídas com sucesso"
###############################################################################
# 4. CRIAR DIRETÓRIOS DE UPLOAD
###############################################################################
log_info "Criando diretórios para uploads..."
# Detectar MEDIA_ROOT do Django
MEDIA_ROOT=$(python3 -c "from django.conf import settings; print(settings.MEDIA_ROOT)" 2>/dev/null || echo "media")
mkdir -p "$MEDIA_ROOT/tce/arquivos"
mkdir -p "$MEDIA_ROOT/tce/reduzidos"
mkdir -p "$MEDIA_ROOT/tce/ocr"
mkdir -p "$MEDIA_ROOT/tce/assinados"
mkdir -p "$MEDIA_ROOT/tce/p7s"
log_info "Diretórios criados em: $MEDIA_ROOT/tce/"
# Configurar permissões
if [ -d "$MEDIA_ROOT/tce" ]; then
# Tentar detectar o usuário do servidor web
WEB_USER=""
if id "www-data" &>/dev/null; then
WEB_USER="www-data"
elif id "apache" &>/dev/null; then
WEB_USER="apache"
elif id "nginx" &>/dev/null; then
WEB_USER="nginx"
fi
if [ -n "$WEB_USER" ]; then
log_info "Configurando permissões para o usuário: $WEB_USER"
chown -R "$WEB_USER:$WEB_USER" "$MEDIA_ROOT/tce" 2>/dev/null || log_warn "Não foi possível alterar o owner. Execute com sudo se necessário."
else
log_warn "Usuário do servidor web não detectado. Configure as permissões manualmente."
fi
chmod -R 755 "$MEDIA_ROOT/tce"
log_info "Permissões configuradas: 755"
fi
###############################################################################
# 5. COLETAR ARQUIVOS ESTÁTICOS
###############################################################################
log_info "Coletando arquivos estáticos..."
python3 manage.py collectstatic --noinput
log_info "Arquivos estáticos coletados"
###############################################################################
# 6. VERIFICAÇÕES FINAIS
###############################################################################
log_info "Realizando verificações finais..."
# Verificar se o app TCE está instalado
python3 manage.py showmigrations tce | grep -q "\[X\]" && log_info "✓ Migrações TCE aplicadas" || log_error "✗ Migrações TCE não aplicadas"
# Listar URLs do módulo TCE
log_info "URLs do módulo TCE registradas:"
python3 manage.py show_urls 2>/dev/null | grep "tce" || log_warn "Comando show_urls não disponível"
###############################################################################
# 7. REINICIAR SERVIÇOS
###############################################################################
log_info "Preparando para reiniciar serviços..."
# Detectar serviço
SERVICE=""
if systemctl list-units --type=service | grep -q "gunicorn"; then
SERVICE="gunicorn"
elif systemctl list-units --type=service | grep -q "uwsgi"; then
SERVICE="uwsgi"
elif systemctl list-units --type=service | grep -q "apache2"; then
SERVICE="apache2"
elif systemctl list-units --type=service | grep -q "httpd"; then
SERVICE="httpd"
fi
if [ -n "$SERVICE" ]; then
log_info "Serviço detectado: $SERVICE"
read -p "Deseja reiniciar o serviço $SERVICE agora? (s/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[SsYy]$ ]]; then
sudo systemctl restart "$SERVICE"
log_info "Serviço $SERVICE reiniciado"
# Reiniciar nginx se existir
if systemctl list-units --type=service | grep -q "nginx"; then
sudo systemctl restart nginx
log_info "Nginx reiniciado"
fi
else
log_warn "Lembre-se de reiniciar o serviço manualmente:"
log_warn " sudo systemctl restart $SERVICE"
fi
else
log_warn "Serviço web não detectado automaticamente."
log_warn "Reinicie manualmente seu servidor web (Apache/Nginx/Gunicorn/uWSGI)"
fi
###############################################################################
# 8. RESUMO
###############################################################################
echo ""
log_info "=========================================="
log_info "Instalação do Módulo TCE Concluída!"
log_info "=========================================="
echo ""
log_info "Próximos passos:"
echo " 1. Acesse: http://seu-servidor/tce/admin/"
echo " 2. Crie um novo processo TCE"
echo " 3. Faça upload de documentos"
echo " 4. Teste a assinatura digital (aba 4 do wizard)"
echo ""
log_info "Dependências instaladas:"
echo " ✓ pyhanko 0.31.0"
echo " ✓ pyhanko-certvalidator 0.29.0"
echo " ✓ cryptography >= 43.0.3"
echo ""
log_info "Diretórios criados:"
echo " $MEDIA_ROOT/tce/"
echo ""
log_info "Para mais informações, consulte:"
echo " - INSTRUCOES_DEPLOY_TCE.md"
echo " - Logs do servidor web"
echo ""
log_info "=========================================="
exit 0
Loading…
Cancel
Save