adbrasi commited on
Commit
1813159
·
verified ·
1 Parent(s): 1465d9c

Upload image_Studio.sh

Browse files
Files changed (1) hide show
  1. image_Studio.sh +506 -0
image_Studio.sh ADDED
@@ -0,0 +1,506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # setup_comfyui_custom.sh
3
+ # Script modificado para instalação do ComfyUI com custom nodes e modelos personalizados
4
+
5
+ set -euo pipefail
6
+
7
+ # -----------------------------
8
+ # Cores para output
9
+ # -----------------------------
10
+ RED='\033[0;31m'
11
+ GREEN='\033[0;32m'
12
+ YELLOW='\033[1;33m'
13
+ BLUE='\033[0;34m'
14
+ NC='\033[0m'
15
+
16
+ log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
17
+ log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
18
+ log_warn() { echo -e "${YELLOW}[!]${NC} $1"; }
19
+ log_error() { echo -e "${RED}[✗]${NC} $1"; }
20
+
21
+ # -----------------------------
22
+ # Configuração
23
+ # -----------------------------
24
+ COMFY_DIR="/root/comfy/ComfyUI"
25
+ MODELS_DIR="$COMFY_DIR/models"
26
+ COMFY_HOST="${COMFY_HOST:-0.0.0.0}"
27
+ COMFY_PORT="${COMFY_PORT:-8818}"
28
+ CIVITAI_TOKEN="${CIVITAI_TOKEN:-4fcb2834969399006a736ee402b061e5}"
29
+ HF_TOKEN="${HF_TOKEN:-}" # Token opcional do HuggingFace para login
30
+
31
+ # Configurações de performance
32
+ export MAX_JOBS=32
33
+ export NVCC_APPEND_FLAGS="--threads 8"
34
+ export UV_SYSTEM_PYTHON=1
35
+ export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True"
36
+ export HF_HUB_ENABLE_HF_TRANSFER=1
37
+ export HF_TRANSFER_CONCURRENCY=16
38
+ export EXT_PARALLEL=4
39
+
40
+ # -----------------------------
41
+ # Lista de downloads
42
+ # -----------------------------
43
+ # Formato: "URL|TIPO|NOME_ARQUIVO_OPCIONAL"
44
+ readonly DOWNLOAD_FILES=(
45
+ # Checkpoints from Civitai
46
+ "https://civitai.com/api/download/models/1761560?type=Model&format=SafeTensor&size=pruned&fp=fp16|checkpoints|"
47
+ "https://civitai.com/api/download/models/1410435?type=Model&format=SafeTensor&size=pruned&fp=fp16|checkpoints|"
48
+ "https://civitai.com/api/download/models/1522463?type=Model&format=SafeTensor&size=full&fp=fp16|checkpoints|"
49
+ "https://civitai.com/api/download/models/2122278?type=Model&format=SafeTensor&size=pruned&fp=fp16|checkpoints|raehoshiIllustXL_v60.safetensors"
50
+
51
+ # LoRAs from Civitai
52
+ "https://civitai.com/api/download/models/1268294?type=Model&format=SafeTensor|loras|"
53
+ "https://civitai.com/api/download/models/1715330?type=Model&format=SafeTensor|loras|"
54
+ "https://civitai.com/api/download/models/1499397?type=Model&format=SafeTensor|loras|"
55
+ "https://civitai.com/api/download/models/1779002?type=Model&format=SafeTensor|loras|"
56
+ "https://civitai.com/api/download/models/1114313?type=Model&format=SafeTensor|loras|"
57
+ "https://civitai.com/api/download/models/1780244?type=Model&format=SafeTensor|loras|"
58
+
59
+ # Upscale models
60
+ "https://huggingface.co/Kim2091/AnimeSharp/resolve/main/4x-AnimeSharp.pth|upscale_models|4x-AnimeSharp.pth"
61
+ "https://huggingface.co/Kim2091/AnimeSharpV3/resolve/main/2x-AnimeSharpV3.pth|upscale_models|2x-AnimeSharpV3.pth"
62
+ "https://huggingface.co/ABDALLALSWAITI/Upscalers/resolve/main/anime/2x-AnimeSharpV2_MoSR_Soft.pth|upscale_models|2x-AnimeSharpV2_MoSR_Soft.pth"
63
+
64
+ # Ultralytics model
65
+ "https://huggingface.co/adbrasi/testedownload/resolve/main/99coins_anime_girl_face_m_seg.pt|ultralytics/bbox|99coins_anime_girl_face_m_seg.pt"
66
+
67
+ # ControlNet
68
+ "hf://xinsir/controlnet-union-sdxl-1.0/diffusion_pytorch_model_promax.safetensors|controlnet|controlnet-union.safetensors"
69
+ )
70
+
71
+ # Custom nodes para instalar
72
+ readonly CUSTOM_NODES=(
73
+ "https://github.com/adbrasi/huggpackreator"
74
+ "https://github.com/adbrasi/packreator_processor"
75
+ "https://github.com/adbrasi/Packreator_manager"
76
+ "https://github.com/adbrasi/cezarsave34"
77
+ "https://github.com/adbrasi/pageonetor"
78
+ "https://github.com/adbrasi/pakreatorio"
79
+ "https://github.com/adbrasi/WaterMark_bumbumzin"
80
+ "https://github.com/adbrasi/marcadaguita"
81
+ "https://github.com/adbrasi/randomico"
82
+ "https://github.com/adbrasi/groqrouter"
83
+ "https://github.com/adbrasi/find_charakito"
84
+ "https://github.com/adbrasi/randomsizito"
85
+ "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes"
86
+ "https://github.com/sipherxyz/comfyui-art-venture"
87
+ "https://github.com/pamparamm/sd-perturbed-attention"
88
+ "https://github.com/KoreTeknology/ComfyUI-Universal-Styler"
89
+ "https://github.com/WASasquatch/was-node-suite-comfyui"
90
+ "https://github.com/chflame163/ComfyUI_LayerStyle"
91
+ "https://github.com/ltdrdata/ComfyUI-Impact-Pack"
92
+ "https://github.com/pythongosssss/ComfyUI-Custom-Scripts"
93
+ "https://github.com/rgthree/rgthree-comfy"
94
+ "https://github.com/ssitu/ComfyUI_UltimateSDUpscale"
95
+ "https://github.com/adbrasi/Importador"
96
+ "https://github.com/adbrasi/GetFirstTag"
97
+ "https://github.com/adbrasi/comfydodi"
98
+ "https://github.com/omar92/ComfyUI-QualityOfLifeSuit_Omar92"
99
+ "https://github.com/Cezarsaint/blacklisto"
100
+ "https://github.com/TinyTerra/ComfyUI_tinyterraNodes"
101
+ "https://github.com/ltdrdata/ComfyUI-Impact-Subpack"
102
+ "https://github.com/Cezarsaint/rand0micoUploaderLoven"
103
+ "https://github.com/adbrasi/pixivmosaic"
104
+ "https://github.com/adbrasi/storitadifusita"
105
+ "https://github.com/adbrasi/attentionPPM"
106
+ "https://github.com/adbrasi/futfilter"
107
+ "https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit"
108
+ "https://github.com/shiimizu/ComfyUI_smZNodes"
109
+ "https://github.com/CoreyCorza/ComfyUI-CRZnodes"
110
+ )
111
+
112
+ # Custom nodes que precisam de instalação especial via comfy-cli
113
+ readonly SPECIAL_NODES=(
114
+ "Civicomfy"
115
+ "ComfyUI-RMBG"
116
+ )
117
+
118
+ # -----------------------------
119
+ # Funções auxiliares
120
+ # -----------------------------
121
+ command_exists() {
122
+ command -v "$1" >/dev/null 2>&1
123
+ }
124
+
125
+ # Adicionar token do Civitai se necessário
126
+ add_civitai_token() {
127
+ local url="$1"
128
+ if [[ "$url" == *"civitai.com/api/download"* ]] && [[ "$url" != *"token="* ]]; then
129
+ echo "${url}&token=${CIVITAI_TOKEN}"
130
+ else
131
+ echo "$url"
132
+ fi
133
+ }
134
+
135
+ # Download HuggingFace usando hf com hf_transfer
136
+ download_hf() {
137
+ local repo="$1"
138
+ local file_path="$2"
139
+ local target_dir="$3"
140
+ local filename="$4"
141
+
142
+ # Se filename não foi fornecido, extrair do caminho
143
+ if [ -z "$filename" ]; then
144
+ filename=$(basename "$file_path")
145
+ fi
146
+
147
+ local target_file="$target_dir/$filename"
148
+
149
+ # Se arquivo já existe e tem tamanho razoável, pular
150
+ if [ -f "$target_file" ] && [ $(stat -c%s "$target_file" 2>/dev/null || echo 0) -gt 1000000 ]; then
151
+ log_success "Arquivo já existe: $filename"
152
+ return 0
153
+ fi
154
+
155
+ log_info "Baixando de HF: $filename"
156
+ log_info " Repo: $repo"
157
+ log_info " Path: $file_path"
158
+
159
+ # Criar diretório temporário para download
160
+ local temp_dir=$(mktemp -d)
161
+
162
+ # Tentar primeiro com 'hf download' (novo comando)
163
+ local download_success=false
164
+
165
+ if command_exists hf; then
166
+ if HF_HUB_ENABLE_HF_TRANSFER=1 hf download "$repo" "$file_path" \
167
+ --local-dir "$temp_dir" \
168
+ --local-dir-use-symlinks False 2>/dev/null; then
169
+ download_success=true
170
+ fi
171
+ fi
172
+
173
+ # Se 'hf' não funcionou, tentar com huggingface-cli
174
+ if [ "$download_success" = false ] && command_exists huggingface-cli; then
175
+ log_warn "Tentando com huggingface-cli..."
176
+ if HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$repo" "$file_path" \
177
+ --local-dir "$temp_dir" \
178
+ --local-dir-use-symlinks False 2>/dev/null; then
179
+ download_success=true
180
+ fi
181
+ fi
182
+
183
+ if [ "$download_success" = true ]; then
184
+ # Procurar o arquivo baixado (pode estar em subdiretórios)
185
+ local downloaded_file=$(find "$temp_dir" -type f \( -name "*.safetensors" -o -name "*.pth" -o -name "*.pt" -o -name "*.bin" \) 2>/dev/null | head -1)
186
+
187
+ if [ -n "$downloaded_file" ]; then
188
+ # Mover para o destino correto com o nome correto
189
+ mv "$downloaded_file" "$target_file"
190
+ rm -rf "$temp_dir"
191
+ log_success "Download concluído: $filename"
192
+ return 0
193
+ else
194
+ log_error "Arquivo baixado mas não encontrado em $temp_dir"
195
+ fi
196
+ fi
197
+
198
+ rm -rf "$temp_dir"
199
+ log_error "Falha ao baixar: $filename"
200
+ return 1
201
+ }
202
+
203
+ # Download genérico com aria2c, wget ou curl
204
+ download_file() {
205
+ local url="$1"
206
+ local target_dir="$2"
207
+ local filename="$3"
208
+
209
+ # Adicionar token Civitai se necessário
210
+ url=$(add_civitai_token "$url")
211
+
212
+ # Se arquivo já existe e tem tamanho razoável, pular
213
+ if [ -n "$filename" ] && [ -f "$target_dir/$filename" ] && [ $(stat -c%s "$target_dir/$filename" 2>/dev/null || echo 0) -gt 1000000 ]; then
214
+ log_success "Arquivo já existe: $filename"
215
+ return 0
216
+ fi
217
+
218
+ log_info "Baixando: ${filename:-$(basename "$url" | cut -d'?' -f1)}"
219
+
220
+ # Tentar com aria2c primeiro (mais rápido)
221
+ if command_exists aria2c; then
222
+ local aria_opts="-c -s 16 -x 16 -k 1M --console-log-level=warn --summary-interval=10"
223
+ if [ -n "$filename" ]; then
224
+ aria2c $aria_opts --dir="$target_dir" --out="$filename" "$url" && return 0
225
+ else
226
+ aria2c $aria_opts --dir="$target_dir" "$url" && return 0
227
+ fi
228
+ fi
229
+
230
+ # Fallback para wget
231
+ if command_exists wget; then
232
+ if [ -n "$filename" ]; then
233
+ wget -q --show-progress -c -O "$target_dir/$filename" "$url" && return 0
234
+ else
235
+ wget -q --show-progress -c --content-disposition -P "$target_dir" "$url" && return 0
236
+ fi
237
+ fi
238
+
239
+ # Último recurso: curl
240
+ if command_exists curl; then
241
+ if [ -n "$filename" ]; then
242
+ curl -L -# -C - -o "$target_dir/$filename" "$url" && return 0
243
+ else
244
+ local headers=$(curl -sI -L "$url")
245
+ local detected_name=$(echo "$headers" | grep -i "content-disposition" | sed -n 's/.*filename="\([^"]*\)".*/\1/p' | tr -d '\r')
246
+ if [ -z "$detected_name" ]; then
247
+ detected_name="downloaded_$(date +%s).safetensors"
248
+ fi
249
+ curl -L -# -C - -o "$target_dir/$detected_name" "$url" && return 0
250
+ fi
251
+ fi
252
+
253
+ log_error "Falha ao baixar: $url"
254
+ return 1
255
+ }
256
+
257
+ # Processar lista de downloads
258
+ process_downloads() {
259
+ local failed_count=0
260
+
261
+ for entry in "${DOWNLOAD_FILES[@]}"; do
262
+ IFS='|' read -r url type filename <<< "$entry"
263
+
264
+ # Limpar espaços
265
+ url=$(echo "$url" | xargs)
266
+ type=$(echo "$type" | xargs)
267
+ filename=$(echo "$filename" | xargs)
268
+
269
+ # Determinar diretório de destino
270
+ local target_dir="$MODELS_DIR"
271
+ case "$type" in
272
+ checkpoints) target_dir="$MODELS_DIR/checkpoints" ;;
273
+ diffusion_models) target_dir="$MODELS_DIR/diffusion_models" ;;
274
+ loras) target_dir="$MODELS_DIR/loras" ;;
275
+ vae) target_dir="$MODELS_DIR/vae" ;;
276
+ vae_approx) target_dir="$MODELS_DIR/vae_approx" ;;
277
+ text_encoders) target_dir="$MODELS_DIR/text_encoders" ;;
278
+ clip_vision) target_dir="$MODELS_DIR/clip_vision" ;;
279
+ controlnet) target_dir="$MODELS_DIR/controlnet" ;;
280
+ upscale_models) target_dir="$MODELS_DIR/upscale_models" ;;
281
+ ultralytics/bbox) target_dir="$MODELS_DIR/ultralytics/bbox" ;;
282
+ *) target_dir="$MODELS_DIR/$type" ;;
283
+ esac
284
+
285
+ # Criar diretório se não existir
286
+ mkdir -p "$target_dir"
287
+
288
+ # Processar URL
289
+ if [[ "$url" == hf://* ]]; then
290
+ # HuggingFace download
291
+ url="${url#hf://}" # Remove prefixo hf://
292
+
293
+ # Separar repo e caminho do arquivo
294
+ local repo=$(echo "$url" | cut -d'/' -f1-2)
295
+ local file_path=$(echo "$url" | cut -d'/' -f3-)
296
+
297
+ download_hf "$repo" "$file_path" "$target_dir" "$filename" || ((failed_count++))
298
+ else
299
+ # Download normal (HTTP/HTTPS)
300
+ download_file "$url" "$target_dir" "$filename" || ((failed_count++))
301
+ fi
302
+ done
303
+
304
+ return $failed_count
305
+ }
306
+
307
+ # Clonar ou atualizar repositório git
308
+ clone_or_update() {
309
+ local url="$1"
310
+ local dest="$2"
311
+ local node_name=$(basename "$dest")
312
+
313
+ # Timeout de 60 segundos para operações git
314
+ if [ -d "$dest/.git" ]; then
315
+ log_info "Atualizando $node_name..."
316
+ timeout 60 git -C "$dest" pull --ff-only 2>/dev/null || {
317
+ log_warn "Timeout ou erro ao atualizar $node_name"
318
+ return 0 # Não falhar, apenas avisar
319
+ }
320
+ else
321
+ log_info "Clonando $node_name..."
322
+ timeout 60 git clone --recursive --depth 1 "$url" "$dest" 2>/dev/null || {
323
+ log_warn "Falha ao clonar $node_name"
324
+ return 0 # Não falhar, apenas avisar
325
+ }
326
+ fi
327
+
328
+ # Instalar requirements se existir (com timeout)
329
+ if [ -f "$dest/requirements.txt" ]; then
330
+ timeout 120 python3 -m pip install --no-warn-script-location -q -r "$dest/requirements.txt" 2>/dev/null || {
331
+ log_warn "Falha ao instalar requirements para $node_name"
332
+ }
333
+ fi
334
+
335
+ return 0
336
+ }
337
+
338
+ # -----------------------------
339
+ # Instalação principal
340
+ # -----------------------------
341
+ echo ""
342
+ log_info "========================================="
343
+ log_info " ComfyUI Custom Setup"
344
+ log_info "========================================="
345
+ echo ""
346
+
347
+ # [1] Verificar e instalar dependências
348
+ log_info "[1/7] Verificando e instalando dependências..."
349
+
350
+ # Instalar aria2c do sistema se não existir
351
+ if ! command_exists aria2c; then
352
+ log_info "Instalando aria2c do sistema..."
353
+ apt-get update -qq && apt-get install -y -qq aria2 2>/dev/null
354
+ fi
355
+
356
+ for cmd in python3 git wget curl; do
357
+ if ! command_exists "$cmd"; then
358
+ log_error "Dependência faltando: $cmd"
359
+ exit 1
360
+ fi
361
+ done
362
+ log_success "Dependências OK"
363
+
364
+ # [2] Atualizar pip e instalar ferramentas
365
+ log_info "[2/7] Preparando ferramentas Python..."
366
+ python3 -m pip install --upgrade pip wheel setuptools -q
367
+
368
+ # Instalar huggingface_hub com CLI e hf_transfer para velocidade máxima
369
+ python3 -m pip install --upgrade "huggingface_hub[cli,hf_transfer]>=0.26.0" comfy-cli -q
370
+
371
+ # Configurar token HF se disponível (opcional)
372
+ HF_TOKEN="${HF_TOKEN:-}"
373
+ if [ -n "$HF_TOKEN" ]; then
374
+ if huggingface-cli login --token "$HF_TOKEN" 2>/dev/null; then
375
+ log_success "Login HF configurado"
376
+ else
377
+ log_warn "Falha ao configurar login HF, continuando sem autenticação"
378
+ fi
379
+ fi
380
+
381
+ # Verificar comandos disponíveis
382
+ if command_exists hf; then
383
+ log_success "Comando 'hf' disponível (recomendado)"
384
+ elif command_exists huggingface-cli; then
385
+ log_warn "Usando 'huggingface-cli' (deprecated, mas funcional)"
386
+ else
387
+ log_error "Nenhum comando HF disponível!"
388
+ fi
389
+
390
+ log_success "Ferramentas instaladas"
391
+
392
+ # [3] Instalar PyTorch com CUDA 12.8
393
+ log_info "[3/7] Instalando PyTorch com CUDA 12.8..."
394
+ python3 -m pip install --upgrade torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
395
+ log_success "PyTorch com CUDA 12.8 instalado"
396
+
397
+ # [4] Instalar ComfyUI
398
+ log_info "[4/7] Instalando ComfyUI..."
399
+ if [ -f "$COMFY_DIR/main.py" ]; then
400
+ log_warn "ComfyUI já existe, pulando instalação base"
401
+ else
402
+ comfy --skip-prompt install --fast-deps --nvidia
403
+
404
+ # Verificar instalação
405
+ if [ ! -f "$COMFY_DIR/main.py" ]; then
406
+ log_error "ComfyUI não foi instalado corretamente!"
407
+ exit 1
408
+ fi
409
+ fi
410
+ log_success "ComfyUI instalado em: $COMFY_DIR"
411
+
412
+ # [5] Baixar modelos
413
+ log_info "[5/7] Baixando modelos..."
414
+ mkdir -p "$MODELS_DIR"/{diffusion_models,loras,vae,vae_approx,text_encoders,clip_vision,controlnet,upscale_models,checkpoints,ultralytics/bbox}
415
+
416
+ # Verificar ferramentas de download
417
+ if command_exists aria2c; then
418
+ log_success "Usando aria2c para downloads (rápido)"
419
+ else
420
+ log_warn "aria2c não encontrado, usando wget/curl (mais lento)"
421
+ fi
422
+
423
+ # Processar downloads
424
+ if process_downloads; then
425
+ log_success "Todos os modelos baixados com sucesso"
426
+ else
427
+ log_warn "Alguns downloads falharam, mas continuando..."
428
+ fi
429
+
430
+ # [6] Instalar custom nodes
431
+ log_info "[6/7] Instalando custom nodes..."
432
+ CN_DIR="$COMFY_DIR/custom_nodes"
433
+ mkdir -p "$CN_DIR"
434
+
435
+ # Instalar nodes do GitHub
436
+ for repo_url in "${CUSTOM_NODES[@]}"; do
437
+ node_name=$(basename "$repo_url")
438
+ clone_or_update "$repo_url" "$CN_DIR/$node_name"
439
+ done
440
+
441
+ # Instalar nodes especiais via comfy-cli
442
+ for node_name in "${SPECIAL_NODES[@]}"; do
443
+ log_info "Instalando $node_name via comfy-cli..."
444
+ comfy node install "$node_name" 2>/dev/null || log_warn "Falha ao instalar $node_name"
445
+ done
446
+
447
+ log_success "Custom nodes instalados"
448
+
449
+ # [7] Verificação final
450
+ echo ""
451
+ log_info "[7/7] Verificando instalação..."
452
+
453
+ # Verificar arquivos principais
454
+ check_critical_files() {
455
+ local files=(
456
+ "$COMFY_DIR/main.py"
457
+ )
458
+
459
+ local missing=0
460
+ for file in "${files[@]}"; do
461
+ if [ -f "$file" ]; then
462
+ log_success "✓ $(basename "$file")"
463
+ else
464
+ log_error "✗ $(basename "$file") não encontrado"
465
+ ((missing++))
466
+ fi
467
+ done
468
+
469
+ # Listar modelos baixados
470
+ echo ""
471
+ log_info "Modelos disponíveis:"
472
+ for dir in checkpoints loras vae vae_approx text_encoders clip_vision controlnet upscale_models ultralytics; do
473
+ if [ -d "$MODELS_DIR/$dir" ]; then
474
+ local count=$(find "$MODELS_DIR/$dir" -type f \( -name "*.safetensors" -o -name "*.pth" -o -name "*.pt" -o -name "*.ckpt" \) 2>/dev/null | wc -l)
475
+ if [ $count -gt 0 ]; then
476
+ log_success " $dir: $count arquivo(s)"
477
+ fi
478
+ fi
479
+ done
480
+
481
+ # Listar custom nodes instalados
482
+ echo ""
483
+ log_info "Custom nodes instalados:"
484
+ local node_count=$(find "$CN_DIR" -maxdepth 1 -type d | wc -l)
485
+ log_success " Total: $((node_count - 1)) nodes"
486
+
487
+ return $missing
488
+ }
489
+
490
+ if check_critical_files; then
491
+ log_success "Instalação concluída com sucesso!"
492
+ echo ""
493
+ log_info "========================================="
494
+ log_info "Iniciando ComfyUI..."
495
+ log_info "URL: http://localhost:$COMFY_PORT"
496
+ log_info "========================================="
497
+
498
+ cd "$COMFY_DIR"
499
+ exec comfy launch -- --listen "$COMFY_HOST" --port "$COMFY_PORT"
500
+ else
501
+ log_error "Alguns arquivos críticos não foram encontrados!"
502
+ log_info "Tentando iniciar ComfyUI mesmo assim..."
503
+
504
+ cd "$COMFY_DIR"
505
+ exec comfy launch -- --listen "$COMFY_HOST" --port "$COMFY_PORT"
506
+ fi