corrigindo upload
Deploy / Deploy (push) Failing after 25m21s Details

This commit is contained in:
JotaChina 2026-04-04 12:42:42 -03:00
parent a8fdfde48e
commit f8ebce56a5
13 changed files with 6848493 additions and 979755 deletions

View File

@ -43,16 +43,16 @@ page_gen:
# Excluded items can be processed by explicitly listing the directories or
# their entries' file path in the `include:` list.
#
#exclude:
# - .sass-cache/
# - .jekyll-cache/
# - gemfiles/
# - Gemfile
# - Gemfile.lock
# - node_modules/
# - vendor/bundle/
# - vendor/cache/
# - vendor/gems/
# - vendor/ruby/
# - scripts/
#- mmp/instruments/lmms/presets/ZynAddSubFX
# Exclude from processing.
exclude:
- .sass-cache/
- .jekyll-cache/
- gemfiles/
- Gemfile
- Gemfile.lock
- node_modules/
- vendor/ # Ignora toda a pasta vendor de uma vez
- scripts/ # Seus scripts Python não vão para o HTML
- venv/ # Se você tiver um ambiente virtual Python aí dentro
# - "*.db" # Ignora bancos de dados do SQLite (como o users.db)
- mmp/instruments/lmms/presets/ZynAddSubFX

View File

@ -0,0 +1,730 @@
bpm: '140'
file: a-return-from-the-dancing-stars
original_title: a-return-from-the-dancing-stars
src: /var/www/html/trens/src_mmpSearch/mmp/a-return-from-the-dancing-stars.mmp
tags:
TAG:
- bassline
- plugin
- automation
automation:
- Traccia di automazione
bassline:
- Kick
- HiHatC
plugin:
- audiofileprocessor
- zynaddsubfx
sample: []
tracks:
- bassline_name: Kick
instruments:
- audiofileprocessor:
amp: '100'
eframe: '1'
interp: '1'
lframe: '0.02'
looped: '0'
reversed: '0'
sframe: '0.02'
src: drums/kick01.ogg
stutter: '0'
basenote: '57'
fxch: '1'
instrument_name: Kick
instrument_type: '0'
pan: '0'
patterns:
- name: Kick
pos: '0'
steps:
- false
- false
- true
- false
- true
- false
- false
- false
- true
- false
- false
- false
- true
- false
- false
- false
- name: Kick
pos: '192'
steps:
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
pitch: '0'
pitchrange: '1'
plugin_name: audiofileprocessor
usemasterpitch: '1'
vol: '100'
- audiofileprocessor:
amp: '100'
eframe: '1'
interp: '1'
lframe: '0'
looped: '0'
reversed: '0'
sframe: '0'
src: drums/hihat_closed01.ogg
stutter: '0'
basenote: '57'
fxch: '2'
instrument_name: hihat_closed01.ogg
instrument_type: '0'
pan: '0'
patterns:
- name: hihat_closed01.ogg
pos: '0'
steps:
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- name: hihat_closed01.ogg
pos: '192'
steps:
- true
- false
- true
- false
- true
- false
- true
- false
- true
- false
- true
- false
- false
- true
- true
- true
pitch: '0'
pitchrange: '1'
plugin_name: audiofileprocessor
usemasterpitch: '1'
vol: '100'
- audiofileprocessor:
amp: '100'
eframe: '1'
interp: '1'
lframe: '0'
looped: '0'
reversed: '0'
sframe: '0'
src: drums/hihat_opened01.ogg
stutter: '0'
basenote: '57'
fxch: '3'
instrument_name: Piatto 1
instrument_type: '0'
pan: '0'
patterns:
- name: Piatto 1
pos: '0'
steps:
- false
- false
- true
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- name: Piatto 1
pos: '192'
steps:
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
- false
pitch: '0'
pitchrange: '1'
plugin_name: audiofileprocessor
usemasterpitch: '1'
vol: '100'
playlist_clips:
- len: 2688
name: Kick
pos: 0
- len: 3072
name: Kick
pos: 5760
- len: 1536
name: Kick
pos: 9408
- len: 5376
name: Kick
pos: 14208
- len: 1920
name: Kick
pos: 10944
tags: audiofileprocessor
track_name: Kick
type: bassline
- arpeggiator:
arp: '0'
arp-enabled: '0'
arpcycle: '0'
arpdir: '0'
arpgate: '100'
arpmiss: '0'
arpmode: '0'
arprange: '2'
arpskip: '0'
arptime: '100'
arptime_denominator: '4'
arptime_numerator: '4'
arptime_syncmode: '0'
audiofileprocessor:
amp: '90'
eframe: '1'
interp: '1'
lframe: '0.09'
looped: '0'
reversed: '0'
sframe: '0.09'
src: drumsynth/misc_synth/wowmelodictone.ds
stutter: '0'
chordcreator:
chord: '0'
chord-enabled: '1'
chordrange: '3'
elcut:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '1'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.01'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
eldata:
fcut: '2940'
fres: '3.51'
ftype: '0'
fwet: '0'
elres:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
elvol:
amt: '1'
att: '0'
ctlenvamt: '0'
dec: '0'
hold: '0'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.23'
sustain: '0.95'
userwavefile: ''
x100: '0'
fxchain:
enabled: '1'
numofeffects: '3'
instrumenttrack:
basenote: '69'
fxch: '6'
pan: '0'
pitch: '0'
pitchrange: '1'
usemasterpitch: '1'
vol: '100'
midiport:
basevelocity: '127'
fixedinputvelocity: '0'
fixedoutputnote: '-1'
fixedoutputvelocity: '0'
inputchannel: '0'
inputcontroller: '0'
outputchannel: '1'
outputcontroller: '0'
outputprogram: '1'
readable: '0'
writable: '0'
plugin_name: audiofileprocessor
track_name: Tamburo Elettronico
type: plugin
- bassline_name: HiHatC
instruments: []
playlist_clips:
- len: 8832
name: HiHatC
pos: 0
- len: 7296
name: HiHatC
pos: 11520
- len: 1536
name: HiHatC
pos: 9408
tags: ''
track_name: HiHatC
type: bassline
- arpeggiator:
arp: '0'
arp-enabled: '0'
arpcycle: '0'
arpdir: '0'
arpgate: '100'
arpmiss: '0'
arpmode: '0'
arprange: '1'
arpskip: '0'
arptime: '100'
arptime_denominator: '4'
arptime_numerator: '4'
arptime_syncmode: '0'
chordcreator:
chord: '0'
chord-enabled: '0'
chordrange: '1'
controller:
bandwidth_depth: '64'
filter_cutoff_depth: '64'
filter_q_depth: '64'
mod_wheel_depth: '80'
panning_depth: '64'
pitchwheel_bendrange: '200'
portamento_pitchthresh: '3'
portamento_pitchthreshtype: '1'
portamento_portamento: '0'
portamento_propdepth: '90'
portamento_proportional: '0'
portamento_proprate: '80'
portamento_time: '64'
portamento_updowntimestretch: '64'
resonance_bandwidth_depth: '64'
resonance_center_depth: '64'
elcut:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
eldata:
fcut: '14000'
fres: '0.5'
ftype: '0'
fwet: '0'
elres:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
elvol:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
fxchain:
enabled: '1'
numofeffects: '2'
insertion_effects:
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
instrument_effects:
- route: '0'
type: '0'
- route: '0'
type: '0'
- route: '0'
type: '0'
instrument_name: zynaddsubfx
instrumenttrack:
basenote: '57'
fxch: '5'
pan: '0'
pitch: '0'
pitchrange: '1'
usemasterpitch: '1'
vol: '100'
midiport:
basevelocity: '127'
fixedinputvelocity: '-1'
fixedoutputnote: '-1'
fixedoutputvelocity: '-1'
inputchannel: '0'
inputcontroller: '0'
outputchannel: '1'
outputcontroller: '0'
outputprogram: '1'
readable: '0'
writable: '0'
system_effects:
- send_vol: '0'
type: '0'
vol: '0'
- send_vol: '0'
type: '0'
vol: '0'
- send_vol: '0'
type: '0'
vol: '0'
- type: '0'
vol: '0'
track_name: Basso Elettronico 1
type: plugin
- arpeggiator:
arp: '0'
arp-enabled: '0'
arpcycle: '0'
arpdir: '0'
arpgate: '100'
arpmiss: '0'
arpmode: '0'
arprange: '1'
arpskip: '0'
arptime: '100'
arptime_denominator: '4'
arptime_numerator: '4'
arptime_syncmode: '0'
chordcreator:
chord: '0'
chord-enabled: '0'
chordrange: '1'
controller:
bandwidth_depth: '64'
filter_cutoff_depth: '64'
filter_q_depth: '64'
mod_wheel_depth: '80'
panning_depth: '64'
pitchwheel_bendrange: '200'
portamento_pitchthresh: '3'
portamento_pitchthreshtype: '1'
portamento_portamento: '0'
portamento_propdepth: '90'
portamento_proportional: '0'
portamento_proprate: '80'
portamento_time: '64'
portamento_updowntimestretch: '64'
resonance_bandwidth_depth: '64'
resonance_center_depth: '64'
elcut:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
eldata:
fcut: '14000'
fres: '0.5'
ftype: '0'
fwet: '0'
elres:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
elvol:
amt: '0'
att: '0'
ctlenvamt: '0'
dec: '0.5'
hold: '0.5'
lamt: '0'
latt: '0'
lpdel: '0'
lshp: '0'
lspd: '0.1'
lspd_denominator: '4'
lspd_numerator: '4'
lspd_syncmode: '0'
pdel: '0'
rel: '0.1'
sustain: '0.5'
userwavefile: ''
x100: '0'
fxchain:
enabled: '1'
numofeffects: '1'
insertion_effects:
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
- part: '-1'
type: '0'
instrument_effects:
- route: '0'
type: '0'
- route: '0'
type: '0'
- route: '0'
type: '0'
instrument_name: zynaddsubfx
instrumenttrack:
basenote: '45'
fxch: '0'
pan: '0'
pitch: '0'
pitchrange: '1'
usemasterpitch: '1'
vol: '100'
midiport:
basevelocity: '127'
fixedinputvelocity: '-1'
fixedoutputnote: '-1'
fixedoutputvelocity: '-1'
inputchannel: '0'
inputcontroller: '0'
outputchannel: '1'
outputcontroller: '0'
outputprogram: '1'
readable: '0'
writable: '0'
system_effects:
- send_vol: '0'
type: '0'
vol: '0'
- send_vol: '0'
type: '0'
vol: '0'
- send_vol: '0'
type: '0'
vol: '0'
- type: '0'
vol: '0'
track_name: Strings Elettronica 4
type: plugin
- automations:
- automation_name: Traccia di automazione
automation_patterns:
- len: '1728'
mute: '0'
name: Volume principale
pos: '17280'
prog: '1'
tens: '1'
times:
- pos: '0'
value: '100'
- pos: '1536'
value: '6'
- len: '192'
mute: '0'
name: Volume principale
pos: '0'
prog: '0'
tens: '1'
times:
- pos: '0'
value: '100'
- len: '1536'
mute: '0'
name: Volume principale
pos: '14208'
prog: '1'
tens: '1'
times:
- pos: '0'
value: '100'
- pos: '576'
value: '199'
- pos: '1800'
value: '98'
- len: '1536'
mute: '0'
name: Volume principale
pos: '15744'
prog: '1'
tens: '1'
times:
- pos: '0'
value: '100'
- pos: '576'
value: '198'
- pos: '1800'
value: '98'
- len: '1536'
mute: '0'
name: Volume principale
pos: '4224'
prog: '1'
tens: '1'
times:
- pos: '0'
value: '100'
- pos: '576'
value: '199'
- pos: '1800'
value: '98'
automationtrack: Present
type: automation

File diff suppressed because it is too large Load Diff

833214
_data/all.yml

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

34344
_data/another-dancefloor.yml Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,3 +1,8 @@
---
### `manual.md`
```markdown
Documentação Técnica: Arquitetura e Implementação do MMPSearch & MMPCreator
1. Visão Geral da Arquitetura
O sistema foi projetado para resolver o desafio de catalogar, processar e permitir a colaboração em projetos musicais (formato LMMS) na web. A solução adota uma Arquitetura Híbrida Dinâmica-Estática:
@ -24,14 +29,14 @@ A funcionalidade mais crítica para a dissertação é a capacidade de gerar áu
Ambiente Offscreen: O script configura a variável de ambiente QT_QPA_PLATFORM="offscreen". Isso engana o LMMS (que é uma aplicação gráfica Qt), permitindo que ele rode via linha de comando dentro do servidor Linux.
Renderização CLI: O áudio é gerado invocando o comando: lmms -r <input.mmp> -o <output.wav> -f wav.
Renderização CLI: O áudio é gerado invocando o comando: lmms -r <input.mmp> -o <output.ogg> -f ogg. (O formato OGG foi escolhido como padrão do pipeline assíncrono para otimizar transferência e armazenamento web).
Paralelismo: Utiliza-se a biblioteca multiprocessing para criar um pool de workers, permitindo que múltiplos projetos sejam renderizados simultaneamente, otimizando o uso da CPU.
4. Geração de Manifestos e Dados Estáticos
Para desacoplar o banco de dados da interface pública, o sistema utiliza o script generate_manifest.py.
Indexação: O script varre os diretórios de mídia (samples, mmp, wav) e gera arquivos JSON e YAML.
Indexação: O script varre os diretórios de mídia (samples, mmp, wav/ogg) e gera arquivos JSON e YAML.
Integração com Jekyll: Estes arquivos YAML são salvos diretamente na pasta _data do Jekyll, servindo como fonte de verdade para a geração das páginas HTML estáticas.
@ -61,12 +66,12 @@ HEALTHY: O caminho no XML bate com o servidor.
RECOVERED: O caminho original (ex: C:/Users/...) não existe, mas o sistema encontrou o arquivo pelo nome e remapeou o link automaticamente.
BROKEN: Arquivo inexistente; o sistema marca para alerta.
BROKEN: Arquivo inexistente, o sistema marca para alerta.
7. Frontend: Visualização e Sequenciador
A interface (projetos.html) demonstra como dados complexos podem ser visualizados sem JavaScript pesado.
Sequenciador CSS: A grade de bateria (Step Sequencer) é renderizada usando lógica de template Liquid e CSS puro. O template itera sobre o array de steps ({% for step in patterns %}) e aplica classes de cor condicionalmente.
Sequenciador CSS: A grade de bateria (Step Sequencer) é renderizada usando lógica de template Liquid e CSS puro. O template itera sobre o array de steps ({% raw %}{% for step in patterns %}{% endraw %}) e aplica classes de cor condicionalmente.
Interatividade Híbrida:
@ -107,8 +112,8 @@ Upload: Usuário envia .mmpz via API Flask (Porta 33002).
Trigger: Flask salva o arquivo e dispara a thread de processamento.
Processamento: Python descompacta o projeto, renderiza o .wav (Headless LMMS) e extrai o .json.
Processamento: Python descompacta o projeto, renderiza o .ogg (Headless LMMS) e extrai o .json.
Build: Python invoca bundle exec jekyll build para regenerar o HTML.
Serviço: Nginx serve o novo HTML estático; Node.js aguarda conexões para edição colaborativa.
Serviço: Serve o novo HTML estático, Node.js aguarda conexões para edição colaborativa.

View File

@ -1,4 +1,15 @@
# mmpCreator - Documentação Técnica
# mmpCreator & MMPSearch - Documentação Técnica
---
## 🏗️ Arquitetura do Sistema
O sistema é um ecossistema completo para submissão, processamento e colaboração em projetos musicais (LMMS), estruturado nos seguintes pilares:
1. **Banco de Dados e Autenticação (Flask / SQLite):** Gestão segura de usuários (Bcrypt, Flask-Login), controle de propriedade de projetos e samples, além de um painel de administração (`Flask-Admin`).
2. **Motor de Renderização Headless (Python):** Processamento assíncrono via biblioteca `multiprocessing`. Utiliza o binário do LMMS em modo `offscreen` para extrair dados do XML (`.mmp` / `.mmpz`) e exportar o áudio gerado nativamente no servidor.
3. **MMPSearch (Catálogo Front-end):** Biblioteca estática gerada via Jekyll a partir de arquivos JSON/YAML, focada em leveza, indexação e busca de projetos com renderização via Web Audio API.
4. **MMPCreator (Colaboração em Tempo Real):** Sequenciador interativo hospedado em Node.js. Utiliza WebSockets para sincronizar edições simultâneas (áudio e MIDI) entre múltiplos usuários em salas virtuais.
---
@ -6,9 +17,7 @@
O site está sendo desenvolvido em um ambiente virtual Python (`venv`). Para executá-lo corretamente, ative o ambiente com o comando:
```bash
source venv/bin/activate
```
`source venv/bin/activate`
Isso garante que todas as dependências do projeto sejam utilizadas corretamente.
@ -28,66 +37,49 @@ Dessa forma, os arquivos de manifesto serão gerados, contendo as informações
---
## 👁️ Serviço de Monitoramento (Watchdog)
## 📤 Servidor de Upload, Samples e Build (Flask)
Um serviço systemd foi criado para monitorar alterações na pasta `src/samples`:
- **Serviço:** `/etc/systemd/system/mmpCreator-upload-server.service`
- **Nome do serviço:** `mmpCreator-upload-server.service`
- **Frequência:** A cada 5 segundos
- **Tecnologia utilizada: ** Python
### Funcionalidade:
Sempre que houver mudanças na pasta de samples, o serviço irá:
1. Detectar alterações via `watchdog`.
2. Executar um novo build do site.
3. Atualizar automaticamente o conteúdo do site em tempo real.
> **Nota:** O build atual está sendo feito apenas na parte de testes. Verificar e ajustar o caminho correto do build.
---
## 📤 Servidor de Upload de Samples
O servidor `upload_server.py` é responsável por receber arquivos de áudio (samples) para a plataforma. Ele é construído com:
O servidor `upload_server.py` atua como a API central do sistema. Ele recebe arquivos, gerencia a sessão dos usuários (Login/Registro) e automatiza a reconstrução da plataforma.
- **Framework:** Flask
- **Monitoramento:** Biblioteca `watchdog`
- **Banco de Dados:** SQLite (com SQLAlchemy)
- **Automação de Build:** Uso de Threads em segundo plano (Background Tasks) acionadas via rotas HTTP.
### Funcionamento:
1. Após qualquer modificação nas pastas de samples:
- O script atualiza os arquivos `samples-manifest.json` e `mmp-manifest.json`.
- Os caminhos dos arquivos são ajustados para garantir exibição e execução corretas.
Sempre que um novo upload (Projeto ou Sample) é processado via API:
1. O arquivo é sanitizado e validado.
2. O sistema verifica a dependência de samples externos no XML.
3. Os manifestos (`samples-manifest.json`, metadados de projetos) são atualizados em tempo real no servidor.
4. Uma thread secundária segura (com Lock) dispara o comando `bundle exec jekyll build`, reconstruindo o frontend estático do MMPSearch para refletir a submissão imediatamente.
### Acesso:
### Acesso da API:
- `http://127.0.0.1:5000`
- `http://127.0.0.1:33002`
> ⚠️ **Importante:** Avaliar a segurança do servidor antes de validar como ferramenta oficial do projeto. Atualmente está sendo usado apenas para testes.
> ⚠️ **Importante:** A estabilidade da reconstrução em produção depende do caminho absoluto do binário Ruby e do pacote Bundle configurados no script (`upload_server.py`).
---
## 💻 Backend para controle das salas online (Colaboração)
Um serviço systemd foi criado para hospedar o backend de um servidor em nodeJS responsável por gerenciar as salas e a colaboração online:
Um serviço systemd foi criado para hospedar o backend de um servidor em nodeJS responsável por gerenciar as salas e a colaboração online do MMPCreator:
- **Serviço:** `/etc/systemd/system/backend-MMPCreator.service`
- **Nome do serviço:** `backend-MMPCreator.service`
- **Frequência:** Tempo integral
- **Tecnologia utilizada: ** NodeJS
- **Tecnologia utilizada:** NodeJS (Socket.io)
### Funcionalidade:
- Seu intuíto é deixar o backend online em tempo integral, possibilitando a utilização da plataforma em qualquer momento.
- Para isso foi necessário inserir meu usuário no grupo de "ssl-cert" para acesso ao certificado
- Essa abordagem foi escolhida, pois a "não" utilização do apache traz algumas variáveis a mais para a implementação de um proxy reverso para a comunicação via wss e https nas salas.
- Para isso foi necessário inserir meu usuário no grupo de "ssl-cert" para acesso aos certificados (Let's Encrypt).
- Essa abordagem foi escolhida, pois a "não" utilização do apache traz algumas variáveis a mais para a implementação de um proxy reverso para a comunicação segura via `wss://` e `https://` nas salas de colaboração.
### Acesso:
- `http://127.0.0.1:33001`
---
## ✅ Funcionalidades Já Implementadas
@ -107,6 +99,8 @@ Um serviço systemd foi criado para hospedar o backend de um servidor em nodeJS
- [x] Salas online e colaboração em tempo real
- [x] Botões de modo global e local para controle do editor de samples (controla play/pause/stop, loop e janela de loop)
- [x] Exibição de notificações em alterações nos projetos em tempo real
- [x] Gestão de usuários (Login, Registro, Perfis e painel Admin)
- [x] Identificação automática de samples externos faltantes no upload de projetos.
---
@ -114,16 +108,16 @@ Um serviço systemd foi criado para hospedar o backend de um servidor em nodeJS
### 🛠️ Funcionalidades
- [ x ] Validar projetos MMP antes de aceitar uploads:
- [ x ] Verificar se os samples são nativos
- [x] Validar projetos MMP antes de aceitar uploads:
- [x] Verificar se os samples são nativos
- [ ] Corrigir caminhos dos samples (evitar problemas de execução)
- [ x ] Para downloads dos zip de projetos;
- [ x ] Para enviar projetos para a plataforma;
- [x] Para downloads dos zip de projetos;
- [x] Para enviar projetos para a plataforma;
- [ ] Reconhecer os caminhos atualizados no MMPCreator;
- [ ] Fazer com que os caminhos atualizados permaneçam após cada build.
- [ x ] Permitir envio de samples gravados com microfone:
- [x] Permitir envio de samples gravados com microfone:
- [ ] Executar e recortar antes de salvar no servidor
- [ x ] Gravar músicas diretamente na plataforma, mesmo sem mixagem
- [x] Gravar músicas diretamente na plataforma, mesmo sem mixagem
- [ ] Ativar/desativar samples em patterns
- [ ] Remover botões inúteis no controle de patterns
- [ ] Melhorar documentação do código
@ -150,4 +144,4 @@ The intuitive is to be able to collect information from the files by indexing it
It is part of the master's research in Computer Science at the Federal University of São João del Rei, focused on independent underground music production and the use of open source technologies.
The mainstream only exists because the underground created the scene.
The mainstream only exists because the underground created the scene.

BIN
scripts/handler/__pycache__/main.cpython-312.pyc Executable file → Normal file

Binary file not shown.

View File

@ -12,6 +12,8 @@ import re
import unicodedata
import csv
import psutil
import glob
import json
from datetime import datetime, timedelta
# Importando seus módulos locais
@ -384,6 +386,38 @@ def process_single_file(args):
return result
def rebuild_all_yamls():
"""Lê todos os JSONs individuais e reconstrói APENAS os arquivos necessários (JSON e YAML leve)."""
logging.info("Reconstruindo all.json e all_leve.yml a partir dos projetos individuais...")
all_data = []
# Busca todos os arquivos .json na pasta de metadados
json_files = glob.glob(os.path.join(METADATA_FOLDER, "*.json"))
for j_file in json_files:
filename = os.path.basename(j_file)
if filename in ["all.json", "samples-manifest.json", "mmp-manifest.json", "dependency_report.json"]:
continue
try:
with open(j_file, 'r', encoding='utf-8') as f:
data = json.load(f)
all_data.append(data)
except Exception as e:
logging.error(f"Erro ao ler {j_file} para agregar: {e}")
if all_data:
# 1. Salva o JSON completo (A biblioteca JSON é nativa e MUITO mais eficiente em RAM)
save_to_json(all_data, os.path.join(METADATA_FOLDER, "all.json"))
# 2. Transforma o 'elefante' num 'camundongo' ANTES de passar pro YAML
dados_leves = create_lightweight_dataset(all_data)
# 3. Salva APENAS a versão leve para o Jekyll (Isso não vai estourar a memória)
save_to_yaml(dados_leves, os.path.join(DATA_FOLDER, "all_leve.yml"))
logging.info(f"Arquivos agregados (all.json / all_leve.yml) atualizados com {len(all_data)} projetos!")
def main_parallel():
logger, log_file_path = setup_logger()

View File

@ -28,7 +28,7 @@ from flask_login import (
from flask_admin import Admin, AdminIndexView, expose
from flask_admin.contrib.sqla import ModelView
from main import process_single_file, generate_manifests, slugify
from main import process_single_file, generate_manifests, slugify, rebuild_all_yamls
from utils import (
ALLOWED_EXTENSIONS,
ALLOWED_SAMPLE_EXTENSIONS,
@ -174,13 +174,16 @@ def allowed_sample(filename):
and filename.rsplit(".", 1)[1].lower() in ALLOWED_SAMPLE_EXTENSIONS
)
def run_jekyll_build():
RUBY_BIN_PATH = "/usr/bin/ruby3.2"
BUNDLE_PATH = "/nethome/jotachina/projetos/mmpSearch/vendor/bundle/ruby/3.2.0/bin/bundle"
BUNDLE_PATH = (
"/nethome/jotachina/projetos/mmpSearch/vendor/bundle/ruby/3.2.0/bin/bundle"
)
env_vars = os.environ.copy()
env_vars["PATH"] = f"{RUBY_BIN_PATH}:{env_vars.get('PATH', '')}"
command = [
BUNDLE_PATH,
"exec",
@ -189,7 +192,7 @@ def run_jekyll_build():
"--destination",
"/var/www/html/trens/mmpSearch/",
]
logging.info("⏳ Aguardando liberação para iniciar build do Jekyll...")
with JEKYLL_LOCK:
logging.info("🔨 Iniciando build do Jekyll (Travando a fila)...")
@ -200,11 +203,13 @@ def run_jekyll_build():
env=env_vars,
capture_output=True,
text=True,
check=True
check=True,
)
logging.info("✅ Jekyll Build concluído com sucesso!")
except subprocess.CalledProcessError as e:
logging.error(f"❌ ERRO FATAL no Jekyll Build (Code {e.returncode}):\n{e.stderr}")
logging.error(
f"❌ ERRO FATAL no Jekyll Build (Code {e.returncode}):\n{e.stderr}"
)
except Exception as e:
logging.error(f"❌ Erro inesperado ao chamar Jekyll: {e}")
@ -331,11 +336,14 @@ def update_xml_paths_exact(mmp_filename, replacements):
print(f"Erro crítico ao editar XML: {e}")
return False
def run_heavy_tasks_in_background():
logging.info("--- [BACKGROUND] Iniciando tarefas assíncronas ---")
try:
generate_manifests(SRC_MMPSEARCH)
# ---> ATUALIZA OS ARQUIVOS "ALL" AQUI <---
rebuild_all_yamls()
run_jekyll_build()
logging.info("--- [BACKGROUND] Todas as tarefas concluídas ---")
except Exception as e: