Files
pymediamanager/app/modules/renamer.py

159 lines
5.9 KiB
Python
Executable File

import streamlit as st
import os
import re
import shutil
import pandas as pd
import time
# Define a raiz absoluta
ROOT_DIR = "/downloads"
def get_all_subfolders(root_path):
folder_list = [root_path]
try:
for root, dirs, files in os.walk(root_path):
for d in dirs:
folder_list.append(os.path.join(root, d))
except: pass
return sorted(folder_list)
def extract_season_episode(filename):
"""
Testa uma lista de padrões regex para extrair Temporada e Episódio.
Retorna (season, episode) ou (None, None).
"""
# LISTA DE PADRÕES (Do mais específico para o mais genérico)
patterns = [
# 1. Padrão Scene/Universal: S01E01, S01.E01, S01_E01, S01 - E01
r'(?i)S(\d{1,4})[\s._-]*E(\d{1,4})',
# 2. Padrão Anime/P2P (Seu caso): S01EP01, S01.EP01
r'(?i)S(\d{1,4})[\s._-]*EP(\d{1,4})',
# 3. Padrão Antigo: 1x01, 01x01
r'(?i)(\d{1,4})x(\d{1,4})',
# 4. Padrão Extenso: Season 1 Episode 1
r'(?i)Season[\s._-]*(\d{1,4})[\s._-]*Episode[\s._-]*(\d{1,4})',
# 5. Padrão Hífen (Anime): "Nome S01 - 05.mkv"
r'(?i)S(\d{1,4})[\s._-]*-\s*(\d{1,4})',
# 6. Padrão Colchetes: [1x01]
r'(?i)\[(\d{1,4})x(\d{1,4})\]',
]
for pattern in patterns:
match = re.search(pattern, filename)
if match:
# Retorna Temporada, Episódio
return match.group(1), match.group(2)
return None, None
def render():
st.header("🏷️ Renomeador de Séries")
st.info("Suporta: S01E01, S01EP01, 1x01, S01 - 01, Season 1 Episode 1...")
# --- SELEÇÃO DE PASTA ---
all_folders = get_all_subfolders(ROOT_DIR)
idx = 0
if 'rn_last_folder' in st.session_state and st.session_state.rn_last_folder in all_folders:
idx = all_folders.index(st.session_state.rn_last_folder)
root_path = st.selectbox(
"Selecione a pasta para analisar:",
options=all_folders,
index=idx,
format_func=lambda x: x.replace(ROOT_DIR, "") if x != ROOT_DIR else "Raiz (/downloads)"
)
st.session_state.rn_last_folder = root_path
if st.button("🔍 Analisar Arquivos", type="primary"):
if not os.path.exists(root_path):
st.error("Pasta não encontrada.")
return
preview_data = []
ignored_files = []
# Varre a pasta
for root, dirs, files in os.walk(root_path):
# Ignora pastas do sistema
if "finalizados" in root or "temp" in root: continue
for file in files:
if file.lower().endswith(('.mkv', '.mp4', '.avi')):
# Chama a função inteligente de detecção
season, episode = extract_season_episode(file)
if season and episode:
try:
s_fmt = f"{int(season):02d}"
e_fmt = f"{int(episode):02d}"
ext = os.path.splitext(file)[1]
season_folder = f"Temporada {s_fmt}"
new_name = f"Episódio {e_fmt}{ext}"
original_full = os.path.join(root, file)
dest_full = os.path.join(root_path, season_folder, new_name)
preview_data.append({
"Arquivo Original": file,
"Nova Estrutura": f"{season_folder}/{new_name}",
"src": original_full,
"dst": dest_full
})
except:
ignored_files.append(file)
else:
ignored_files.append(file)
st.session_state['renamer_preview'] = preview_data
st.session_state['renamer_ignored'] = ignored_files
# --- RESULTADOS ---
if 'renamer_preview' in st.session_state and st.session_state['renamer_preview']:
st.divider()
st.subheader(f"✅ Identificados ({len(st.session_state['renamer_preview'])})")
df = pd.DataFrame(st.session_state['renamer_preview'])
st.dataframe(
df[["Arquivo Original", "Nova Estrutura"]],
use_container_width=True,
hide_index=True
)
col1, col2 = st.columns([1, 4])
with col1:
if st.button("🚀 Confirmar", type="primary", use_container_width=True):
count = 0
for item in st.session_state['renamer_preview']:
dst_folder = os.path.dirname(item["dst"])
try:
if not os.path.exists(dst_folder):
os.makedirs(dst_folder, exist_ok=True)
if not os.path.exists(item["dst"]):
shutil.move(item["src"], item["dst"])
count += 1
except Exception as e:
st.error(f"Erro ao mover {item['src']}: {e}")
st.success(f"{count} arquivos organizados com sucesso!")
time.sleep(2)
del st.session_state['renamer_preview']
del st.session_state['renamer_ignored']
st.rerun()
# Exibe ignorados se houver, para debug do usuário
if 'renamer_ignored' in st.session_state and st.session_state['renamer_ignored']:
with st.expander("⚠️ Arquivos ignorados (Padrão desconhecido)", expanded=False):
st.write(st.session_state['renamer_ignored'])
elif 'renamer_preview' in st.session_state and not st.session_state['renamer_preview']:
st.warning("Nenhum arquivo de vídeo encontrado.")