pcdoido2 commited on
Commit
a6ab8b7
·
verified ·
1 Parent(s): 47612f1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -58
app.py CHANGED
@@ -5,6 +5,8 @@ import time
5
  import subprocess
6
  import random
7
  import string
 
 
8
  import mimetypes
9
 
10
  BASE_FOLDER = "uploaded_files"
@@ -46,43 +48,8 @@ else:
46
  st.title("📂 File Manager por Categoria")
47
 
48
  # --- Funções auxiliares ---
49
- def random_string(n=12):
50
- return ''.join(random.choices(string.ascii_letters + string.digits, k=n))
51
-
52
- def randomize_video_metadata(file_path):
53
- """FULL HARD REAL: remove LvMetaInfo/Aigc e reinsere metadados randômicos"""
54
- mime, _ = mimetypes.guess_type(file_path)
55
- if not mime or not mime.startswith("video"):
56
- return
57
-
58
- temp_path = file_path + ".tmp"
59
-
60
- cmd = [
61
- "ffmpeg", "-y", "-i", file_path,
62
- "-map", "0:v", "-map", "0:a", # ⚡ só vídeo e áudio
63
- "-map_metadata", "-1", # limpa tudo
64
- "-c:v", "libx264", "-preset", "fast", "-crf", "23",
65
- "-c:a", "aac", "-b:a", "128k",
66
- "-movflags", "use_metadata_tags+faststart",
67
- "-brand", random.choice(["mp42", "isom", "iso2", "avc1"]),
68
- "-metadata", f"encoder={random_string(10)}",
69
- "-metadata", f"title={random_string(12)}",
70
- "-metadata", f"comment={random_string(12)}",
71
- "-metadata", f"description={random_string(12)}",
72
- "-metadata", f"artist={random_string(10)}",
73
- "-metadata", f"album={random_string(10)}",
74
- temp_path
75
- ]
76
-
77
- try:
78
- subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
79
- os.replace(temp_path, file_path)
80
- print(f"✅ FULL HARD REAL aplicado em {file_path}")
81
- except Exception as e:
82
- print(f"⚠ Erro ao randomizar {file_path}: {e}")
83
-
84
  def remove_expired_files():
85
- """Remove arquivos vencidos automaticamente"""
86
  changed = False
87
  now = time.time()
88
  expired_files = []
@@ -103,6 +70,48 @@ def remove_expired_files():
103
  with open(EXPIRATION_FILE, "w") as f:
104
  json.dump(expirations, f)
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  # --- Apagar arquivos vencidos ao iniciar ---
107
  remove_expired_files()
108
 
@@ -112,12 +121,7 @@ st.subheader("Selecione uma categoria:")
112
 
113
  categoria = st.radio("Categoria:", CATEGORIES, index=None)
114
 
115
- # 🔀 Opções antes do upload
116
- randomize_meta = st.checkbox("🔀 Randomizar metadados de vídeos (e renomear)")
117
- auto_delete = st.checkbox("🕒 Excluir automaticamente após 24 horas")
118
-
119
- if "uploaded_once" not in st.session_state:
120
- st.session_state["uploaded_once"] = False
121
 
122
  if categoria:
123
  uploaded_files = st.file_uploader(
@@ -125,37 +129,44 @@ if categoria:
125
  accept_multiple_files=True,
126
  key=f"uploader_{categoria}"
127
  )
 
128
 
129
- if uploaded_files and not st.session_state["uploaded_once"]:
130
  for uploaded_file in uploaded_files:
131
  folder = os.path.join(BASE_FOLDER, categoria)
 
 
 
 
132
 
133
- # Renomear se randomização estiver ativa
134
- if randomize_meta:
135
- ext = os.path.splitext(uploaded_file.name)[1]
136
- new_name = random_string(16) + ext
 
 
 
 
 
 
 
 
 
137
  else:
138
  new_name = uploaded_file.name
139
 
140
  file_path = os.path.join(folder, new_name)
 
141
 
142
- # Salva arquivo
143
- with open(file_path, "wb") as f:
144
- f.write(uploaded_file.read())
145
-
146
- # Se marcado → randomizar metadados (apenas vídeos)
147
- if randomize_meta:
148
- randomize_video_metadata(file_path)
149
-
150
- # Salvar expiração se marcada
151
  if auto_delete:
152
  key = f"{categoria}|||{new_name}"
153
  expirations[key] = time.time() + 24 * 60 * 60
154
  with open(EXPIRATION_FILE, "w") as f:
155
  json.dump(expirations, f)
156
 
157
- st.session_state["uploaded_once"] = True
158
- st.success("✅ Arquivos enviados com sucesso!")
159
 
160
  # --- Lista de Arquivos agrupada por pasta ---
161
  st.header("📄 Arquivos Disponíveis")
@@ -200,6 +211,7 @@ for categoria in CATEGORIES:
200
  with open(EXPIRATION_FILE, "w") as f:
201
  json.dump(expirations, f)
202
  st.success(f"Arquivo '{file}' excluído.")
 
203
 
204
  with col3:
205
  with open(os.path.join(folder, file), "rb") as f_obj:
@@ -209,5 +221,6 @@ for categoria in CATEGORIES:
209
  with open(EXPIRATION_FILE, "w") as f:
210
  json.dump(expirations, f)
211
  st.success(f"Arquivo '{file}' baixado e removido.")
 
212
 
213
  st.markdown("</div>", unsafe_allow_html=True)
 
5
  import subprocess
6
  import random
7
  import string
8
+ import tempfile
9
+ import shutil
10
  import mimetypes
11
 
12
  BASE_FOLDER = "uploaded_files"
 
48
  st.title("📂 File Manager por Categoria")
49
 
50
  # --- Funções auxiliares ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  def remove_expired_files():
52
+ """Remove arquivos expirados automaticamente"""
53
  changed = False
54
  now = time.time()
55
  expired_files = []
 
70
  with open(EXPIRATION_FILE, "w") as f:
71
  json.dump(expirations, f)
72
 
73
+ def random_string(length=12):
74
+ return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
75
+
76
+ def process_video(file_path, hard_mode=False):
77
+ """Processa vídeo removendo metadados. Se hard_mode=True, usa FFmpeg + MP4Box"""
78
+ temp_fd, temp_out = tempfile.mkstemp(suffix=".mp4")
79
+ os.close(temp_fd)
80
+
81
+ if not hard_mode:
82
+ # Upload normal sem mexer
83
+ shutil.copy(file_path, temp_out)
84
+ return temp_out
85
+
86
+ # 1. Reencode básico com ffmpeg
87
+ temp_ffmpeg = temp_out + ".ffmpeg.mp4"
88
+ cmd_ffmpeg = [
89
+ "ffmpeg", "-y", "-i", file_path,
90
+ "-map", "0:v", "-map", "0:a?",
91
+ "-map_metadata", "-1",
92
+ "-c:v", "libx264", "-preset", "fast", "-crf", "23",
93
+ "-c:a", "aac", "-b:a", "128k",
94
+ "-movflags", "use_metadata_tags+faststart",
95
+ "-brand", random.choice(["mp42", "isom", "iso2", "avc1"]),
96
+ "-metadata", f"encoder={random_string(10)}",
97
+ "-metadata", f"title={random_string(12)}",
98
+ "-metadata", f"comment={random_string(12)}",
99
+ "-metadata", f"description={random_string(12)}",
100
+ "-metadata", f"artist={random_string(10)}",
101
+ "-metadata", f"album={random_string(10)}",
102
+ temp_ffmpeg
103
+ ]
104
+ subprocess.run(cmd_ffmpeg, check=True)
105
+
106
+ # 2. Remove UUID atoms (LvMetaInfo, AigcInfo) com MP4Box
107
+ cmd_mp4box = ["MP4Box", "-rem-uuid", temp_ffmpeg, "-out", temp_out]
108
+ subprocess.run(cmd_mp4box, check=True)
109
+
110
+ # 3. Apaga temporário
111
+ os.remove(temp_ffmpeg)
112
+
113
+ return temp_out
114
+
115
  # --- Apagar arquivos vencidos ao iniciar ---
116
  remove_expired_files()
117
 
 
121
 
122
  categoria = st.radio("Categoria:", CATEGORIES, index=None)
123
 
124
+ hard_mode = st.checkbox("Ativar randomização HARD (vídeos apenas)")
 
 
 
 
 
125
 
126
  if categoria:
127
  uploaded_files = st.file_uploader(
 
129
  accept_multiple_files=True,
130
  key=f"uploader_{categoria}"
131
  )
132
+ auto_delete = st.checkbox("Excluir automaticamente após 24 horas")
133
 
134
+ if uploaded_files:
135
  for uploaded_file in uploaded_files:
136
  folder = os.path.join(BASE_FOLDER, categoria)
137
+ os.makedirs(folder, exist_ok=True)
138
+
139
+ mime, _ = mimetypes.guess_type(uploaded_file.name)
140
+ is_video = mime and mime.startswith("video")
141
 
142
+ with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(uploaded_file.name)[1]) as tmp:
143
+ tmp.write(uploaded_file.read())
144
+ tmp_path = tmp.name
145
+
146
+ # Se for vídeo + hard_mode ativo → processa
147
+ if is_video and hard_mode:
148
+ final_tmp = process_video(tmp_path, hard_mode=True)
149
+ else:
150
+ final_tmp = tmp_path
151
+
152
+ # Renomeia com string aleatória se hard_mode
153
+ if hard_mode and is_video:
154
+ new_name = random_string(16) + ".mp4"
155
  else:
156
  new_name = uploaded_file.name
157
 
158
  file_path = os.path.join(folder, new_name)
159
+ shutil.move(final_tmp, file_path)
160
 
161
+ # Salvar expiração
 
 
 
 
 
 
 
 
162
  if auto_delete:
163
  key = f"{categoria}|||{new_name}"
164
  expirations[key] = time.time() + 24 * 60 * 60
165
  with open(EXPIRATION_FILE, "w") as f:
166
  json.dump(expirations, f)
167
 
168
+ st.success("Arquivos enviados com sucesso!")
169
+ st.rerun()
170
 
171
  # --- Lista de Arquivos agrupada por pasta ---
172
  st.header("📄 Arquivos Disponíveis")
 
211
  with open(EXPIRATION_FILE, "w") as f:
212
  json.dump(expirations, f)
213
  st.success(f"Arquivo '{file}' excluído.")
214
+ st.rerun()
215
 
216
  with col3:
217
  with open(os.path.join(folder, file), "rb") as f_obj:
 
221
  with open(EXPIRATION_FILE, "w") as f:
222
  json.dump(expirations, f)
223
  st.success(f"Arquivo '{file}' baixado e removido.")
224
+ st.rerun()
225
 
226
  st.markdown("</div>", unsafe_allow_html=True)