resolvendo dependencias dos projetos
Deploy / Deploy (push) Successful in 1m53s Details

This commit is contained in:
JotaChina 2025-12-08 18:13:30 -03:00
parent be62cb7c11
commit 3d12853ecc
5 changed files with 136 additions and 16 deletions

View File

@ -260447,8 +260447,7 @@
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Young Kico - Chronicles Of The Atlantic Trap (Sound Kit) @YoungKico/01 src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic01_-_Copia.ogg
Kicks/Kick 1 (Layer With Any 808 For Authentic Zaytoven Delayed Kick).wav
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -260615,7 +260614,7 @@
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: lex_luger_drum_kit/lex_luger_drum_kit/LEX Rim(2).wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic02_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -260939,7 +260938,7 @@
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Kid Urban Christmas BeatKit/Urban 808's/KU 808 5.wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic01_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -261106,7 +261105,7 @@
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Kid Urban Christmas BeatKit/Urban Percussion/KU Perc 10.wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic02_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -261273,7 +261272,7 @@
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Kid Urban End Of The World BeatKit/EOTW Percussion/Kid Urban Perc 13.wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic02_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'

View File

@ -177,8 +177,7 @@ tracks:
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Young Kico - Chronicles Of The Atlantic Trap (Sound Kit) @YoungKico/01 src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic01_-_Copia.ogg
Kicks/Kick 1 (Layer With Any 808 For Authentic Zaytoven Delayed Kick).wav
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -345,7 +344,7 @@ tracks:
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: lex_luger_drum_kit/lex_luger_drum_kit/LEX Rim(2).wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic02_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -669,7 +668,7 @@ tracks:
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Kid Urban Christmas BeatKit/Urban 808's/KU 808 5.wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic01_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -836,7 +835,7 @@ tracks:
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Kid Urban Christmas BeatKit/Urban Percussion/KU Perc 10.wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic02_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'
@ -1003,7 +1002,7 @@ tracks:
looped: '0' looped: '0'
reversed: '0' reversed: '0'
sframe: '0' sframe: '0'
src: Kid Urban End Of The World BeatKit/EOTW Percussion/Kid Urban Perc 13.wav src: /var/www/html/trens/src_mmpSearch/samples/imported/bassdrum_acoustic02_-_Copia.ogg
stutter: '0' stutter: '0'
basenote: '57' basenote: '57'
fxch: '0' fxch: '0'

View File

@ -1,5 +1,8 @@
{ {
"imported": { "imported": {
"bassdrum_acoustic02_-_Copia.ogg": {
"_isFile": true
},
"bassdrum_acoustic01_-_Copia.ogg": { "bassdrum_acoustic01_-_Copia.ogg": {
"_isFile": true "_isFile": true
} }

View File

@ -97,6 +97,8 @@
title="Salvar Projeto (.mmp)" title="Salvar Projeto (.mmp)"
></i> ></i>
<span style="margin-left: 8px">Salvar projeto</span> <span style="margin-left: 8px">Salvar projeto</span>
<i class="fa-solid fa-file-zipper" id="download-package-btn" title="Baixar Pacote Completo (.zip)" style="margin-left: 15px; color: #ffdd57; cursor: pointer;"></i>
<span style="margin-left: 8px; color: #ffdd57;">Baixar ZIP</span>
<i <i
class="fa-solid fa-upload" class="fa-solid fa-upload"
id="upload-sample-btn" id="upload-sample-btn"
@ -770,6 +772,44 @@
} }
</script> </script>
<script>
// Lógica para o botão de Baixar Pacote
document.addEventListener("DOMContentLoaded", () => {
const downloadPackageBtn = document.getElementById("download-package-btn");
if (downloadPackageBtn) {
downloadPackageBtn.addEventListener("click", () => {
// 1. Tenta descobrir o nome do projeto atual
// Se você tiver uma variável global tipo 'currentProjectName', use ela aqui.
// Ex: let projectName = window.currentProjectName || appState.projectName;
// Como fallback, perguntamos ao usuário:
let projectName = prompt("Qual o nome do projeto salvo no servidor que deseja baixar?");
if (projectName) {
// Garante a extensão .mmp apenas para validação, o backend trata isso também
if (!projectName.toLowerCase().endsWith(".mmp")) {
projectName += ".mmp";
}
// 2. Chama a API de Download que criamos no Python
// O navegador vai iniciar o download automaticamente
const apiUrl = `https://alice.ufsj.edu.br:33002/api/download/${projectName}`;
// Feedback visual simples
downloadPackageBtn.style.opacity = "0.5";
// Redireciona para baixar
window.location.href = apiUrl;
// Restaura botão
setTimeout(() => { downloadPackageBtn.style.opacity = "1"; }, 1000);
}
});
}
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>

View File

@ -3,15 +3,15 @@ import subprocess
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import gzip import gzip
import zipfile import zipfile
import zlib # <--- IMPORTANTE: Adicionado para suporte a mmpz raw import zlib
import json import json
import shutil import shutil
import time import time
from flask import Flask, request, jsonify import io
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS from flask_cors import CORS
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
# Importa suas funções e configurações existentes
from main import process_single_file, rebuild_indexes, generate_manifests, slugify from main import process_single_file, rebuild_indexes, generate_manifests, slugify
from utils import ALLOWED_EXTENSIONS, ALLOWED_SAMPLE_EXTENSIONS, MMP_FOLDER, MMPZ_FOLDER, CERT_PATH, KEY_PATH, BASE_DATA, SRC_MMPSEARCH, SAMPLE_SRC, METADATA_FOLDER, XML_IMPORTED_PATH_PREFIX, SAMPLE_MANIFEST from utils import ALLOWED_EXTENSIONS, ALLOWED_SAMPLE_EXTENSIONS, MMP_FOLDER, MMPZ_FOLDER, CERT_PATH, KEY_PATH, BASE_DATA, SRC_MMPSEARCH, SAMPLE_SRC, METADATA_FOLDER, XML_IMPORTED_PATH_PREFIX, SAMPLE_MANIFEST
@ -217,6 +217,85 @@ def update_xml_paths_exact(mmp_filename, replacements):
# --- ROTAS --- # --- ROTAS ---
@app.route("/api/download/<project_name>", methods=["GET"])
def download_project_package(project_name):
"""
Gera um ZIP contendo o arquivo .mmp e apenas os samples importados necessários.
Estrutura do ZIP:
- projeto.mmp
- src_mmpSearch/
- samples/
- imported/
- sample1.wav
- sample2.wav
"""
# Garante que estamos pegando o .mmp (mesmo que peçam sem extensão)
if not project_name.endswith('.mmp'):
project_name += '.mmp'
clean_name = secure_filename(project_name)
mmp_path = os.path.join(MMP_FOLDER, clean_name)
if not os.path.exists(mmp_path):
return jsonify({"error": "Projeto não encontrado"}), 404
# Prepara o buffer do ZIP na memória (não salva no disco para economizar I/O)
memory_file = io.BytesIO()
try:
with zipfile.ZipFile(memory_file, 'w', zipfile.ZIP_DEFLATED) as zf:
# 1. Adiciona o arquivo .mmp na RAIZ do ZIP
# arcname é o nome que o arquivo terá dentro do zip
zf.write(mmp_path, arcname=clean_name)
# 2. Lê o XML para descobrir quais samples incluir
tree = ET.parse(mmp_path)
root = tree.getroot()
# Conjunto para evitar adicionar o mesmo sample 2x
samples_to_pack = set()
for audio_node in root.findall(".//audiofileprocessor"):
src = audio_node.get('src', '')
# Verifica se é um sample importado (nosso padrão)
# O src no XML já deve estar como: src_mmpSearch/samples/imported/nome.wav
if src.startswith(XML_IMPORTED_PATH_PREFIX):
# Extrai apenas o nome do arquivo (ex: kick.wav)
sample_filename = os.path.basename(src)
samples_to_pack.add(sample_filename)
# 3. Adiciona os samples encontrados ao ZIP mantendo a estrutura de pasta
for sample_name in samples_to_pack:
# Caminho físico no servidor (onde o arquivo realmente está)
physical_path = os.path.join(PHYSICAL_IMPORTED_FOLDER, sample_name)
# Caminho DENTRO do ZIP (para o LMMS ler relativo ao mmp)
# Deve ser: src_mmpSearch/samples/imported/sample.wav
zip_internal_path = f"{XML_IMPORTED_PATH_PREFIX}/{sample_name}"
if os.path.exists(physical_path):
zf.write(physical_path, arcname=zip_internal_path)
print(f"[ZIP] Adicionado: {sample_name}")
else:
print(f"[ZIP] AVISO: Sample listado no XML mas não encontrado no disco: {sample_name}")
# Finaliza o ponteiro do arquivo
memory_file.seek(0)
return send_file(
memory_file,
mimetype='application/zip',
as_attachment=True,
download_name=f"{os.path.splitext(clean_name)[0]}_pack.zip"
)
except Exception as e:
import traceback
traceback.print_exc()
return jsonify({"error": f"Erro ao gerar pacote: {str(e)}"}), 500
@app.route("/api/upload", methods=["POST"]) @app.route("/api/upload", methods=["POST"])
def upload_file(): def upload_file():
if "project_file" not in request.files: if "project_file" not in request.files: