pcdoido2 commited on
Commit
b770ad2
·
verified ·
1 Parent(s): 4a15ecd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -40
app.py CHANGED
@@ -31,11 +31,11 @@ st.markdown("""
31
  </style>
32
  """, unsafe_allow_html=True)
33
 
34
- # Cria pastas
35
  for cat in CATEGORIES:
36
  os.makedirs(os.path.join(BASE_FOLDER, cat), exist_ok=True)
37
 
38
- # Carrega expirações
39
  if os.path.exists(EXPIRATION_FILE):
40
  with open(EXPIRATION_FILE, "r") as f:
41
  expirations = json.load(f)
@@ -44,11 +44,12 @@ else:
44
 
45
  st.title("📂 File Manager por Categoria")
46
 
47
- # --- Função remover expirados ---
48
  def remove_expired_files():
49
  changed = False
50
  now = time.time()
51
  expired_files = []
 
52
  for file_full, expire_time in list(expirations.items()):
53
  cat, file = file_full.split("|||")
54
  file_path = os.path.join(BASE_FOLDER, cat, file)
@@ -57,16 +58,19 @@ def remove_expired_files():
57
  os.remove(file_path)
58
  expired_files.append(file_full)
59
  changed = True
 
60
  for file_full in expired_files:
61
  expirations.pop(file_full)
 
62
  if changed:
63
  with open(EXPIRATION_FILE, "w") as f:
64
  json.dump(expirations, f)
65
 
 
66
  remove_expired_files()
67
 
68
- # --- Função aleatorizar metadados com ffmpeg ---
69
- def randomize_video_metadata(input_path, output_path, progress_placeholder):
70
  major_brands = ["isom", "mp42", "iso5", "avc1"]
71
  compatible_sets = [
72
  ["isom", "iso2", "avc1", "mp41"],
@@ -77,10 +81,12 @@ def randomize_video_metadata(input_path, output_path, progress_placeholder):
77
  major = random.choice(major_brands)
78
  compatible = ",".join(random.choice(compatible_sets))
79
 
80
- # Gera datas aleatórias
81
  start_date = datetime.datetime.now() - datetime.timedelta(days=180)
82
- random_date = start_date + datetime.timedelta(days=random.randint(0, 180),
83
- seconds=random.randint(0, 86400))
 
 
84
  date_str = random_date.strftime("%Y-%m-%d %H:%M:%S")
85
 
86
  def randstr(n=12):
@@ -96,33 +102,36 @@ def randomize_video_metadata(input_path, output_path, progress_placeholder):
96
  "publisher": randstr(10),
97
  "encoded_by": randstr(10),
98
  "creation_time": date_str,
99
- "major_brand": major,
100
- "compatible_brands": compatible,
101
  }
102
 
103
- # Monta comando ffmpeg
104
- cmd = ["ffmpeg", "-i", input_path, "-map_metadata", "-1"]
 
 
 
 
 
105
  for k, v in metadata.items():
106
  cmd += ["-metadata", f"{k}={v}"]
107
 
108
- # Mantém qualidade alta
109
- cmd += ["-c:v", "libx264", "-preset", "fast", "-crf", "18",
110
- "-c:a", "aac", "-b:a", "192k", output_path]
 
 
111
 
112
- # Executa com barra de progresso
113
- progress = 0
114
- with subprocess.Popen(cmd, stderr=subprocess.PIPE, universal_newlines=True) as proc:
115
- for line in proc.stderr:
116
- if "time=" in line:
117
- progress = min(progress + 5, 100) # fake progress
118
- progress_placeholder.progress(progress)
119
- proc.wait()
120
- progress_placeholder.progress(100)
121
 
122
  # --- Upload ---
 
123
  st.header("📤 Upload de Arquivos")
 
 
 
124
  categoria = st.radio("Categoria:", CATEGORIES, index=None)
125
- aleatorizar = st.checkbox("🔀 Aleatorizar metadados de vídeos")
 
 
126
 
127
  if categoria:
128
  uploaded_files = st.file_uploader(
@@ -137,19 +146,23 @@ if categoria:
137
  folder = os.path.join(BASE_FOLDER, categoria)
138
  file_path = os.path.join(folder, uploaded_file.name)
139
 
140
- with open(file_path, "wb") as f:
 
 
141
  f.write(uploaded_file.read())
142
 
143
- # Se for vídeo e checkbox ativo → processa metadados
144
- if aleatorizar and uploaded_file.type == "video/mp4":
145
- progress_placeholder = st.empty()
146
- st.info(f"🔄 Processando metadados de {uploaded_file.name}...")
147
- randomized_path = os.path.join(folder, f"rnd_{uploaded_file.name}")
148
- randomize_video_metadata(file_path, randomized_path, progress_placeholder)
149
- os.remove(file_path) # remove original
150
- os.rename(randomized_path, file_path)
151
- st.success(f"✅ {uploaded_file.name} processado com metadados aleatórios!")
152
-
 
 
153
  if auto_delete:
154
  key = f"{categoria}|||{uploaded_file.name}"
155
  expirations[key] = time.time() + 24 * 60 * 60
@@ -159,31 +172,42 @@ if categoria:
159
  st.success("Arquivos enviados com sucesso!")
160
  st.rerun()
161
 
162
- # --- Lista de Arquivos ---
163
  st.header("📄 Arquivos Disponíveis")
 
164
  for categoria in CATEGORIES:
165
  folder = os.path.join(BASE_FOLDER, categoria)
166
  files = os.listdir(folder)
 
167
  st.subheader(f"📁 {categoria}")
 
168
  if not files:
169
  st.info("Nenhum arquivo na categoria.")
170
  else:
171
  for file in files:
172
  st.markdown(f"<div class='file-box'>", unsafe_allow_html=True)
173
  st.markdown(f"<div class='file-name'>{file}</div>", unsafe_allow_html=True)
 
174
  key = f"{categoria}|||{file}"
 
175
  expira = expirations.get(key)
176
  if expira:
177
  restante = int(expira - time.time())
178
  if restante > 0:
179
- h = restante // 3600
180
- m = (restante % 3600) // 60
181
- st.markdown(f"<div class='expire-text'>⏳ Expira em {h}h {m}min</div>", unsafe_allow_html=True)
 
 
 
 
182
 
183
  col1, col2, col3 = st.columns(3)
 
184
  with col1:
185
  with open(os.path.join(folder, file), "rb") as f_obj:
186
  st.download_button("⬇ Download", f_obj, file_name=file, key=f"down_{categoria}_{file}")
 
187
  with col2:
188
  if st.button("🗑 Excluir", key=f"delete_{categoria}_{file}"):
189
  os.remove(os.path.join(folder, file))
@@ -192,6 +216,7 @@ for categoria in CATEGORIES:
192
  json.dump(expirations, f)
193
  st.success(f"Arquivo '{file}' excluído.")
194
  st.rerun()
 
195
  with col3:
196
  with open(os.path.join(folder, file), "rb") as f_obj:
197
  if st.download_button("⬇ Baixar & Apagar", f_obj, file_name=file, key=f"download_delete_{categoria}_{file}"):
@@ -201,4 +226,5 @@ for categoria in CATEGORIES:
201
  json.dump(expirations, f)
202
  st.success(f"Arquivo '{file}' baixado e removido.")
203
  st.rerun()
 
204
  st.markdown("</div>", unsafe_allow_html=True)
 
31
  </style>
32
  """, unsafe_allow_html=True)
33
 
34
+ # Cria as pastas se não existirem
35
  for cat in CATEGORIES:
36
  os.makedirs(os.path.join(BASE_FOLDER, cat), exist_ok=True)
37
 
38
+ # Carrega dados de expiração
39
  if os.path.exists(EXPIRATION_FILE):
40
  with open(EXPIRATION_FILE, "r") as f:
41
  expirations = json.load(f)
 
44
 
45
  st.title("📂 File Manager por Categoria")
46
 
47
+ # --- Função: apagar arquivos expirados ---
48
  def remove_expired_files():
49
  changed = False
50
  now = time.time()
51
  expired_files = []
52
+
53
  for file_full, expire_time in list(expirations.items()):
54
  cat, file = file_full.split("|||")
55
  file_path = os.path.join(BASE_FOLDER, cat, file)
 
58
  os.remove(file_path)
59
  expired_files.append(file_full)
60
  changed = True
61
+
62
  for file_full in expired_files:
63
  expirations.pop(file_full)
64
+
65
  if changed:
66
  with open(EXPIRATION_FILE, "w") as f:
67
  json.dump(expirations, f)
68
 
69
+ # --- Apagar arquivos vencidos ao iniciar ---
70
  remove_expired_files()
71
 
72
+ # --- Função: randomizar metadados de vídeo ---
73
+ def randomize_video_metadata_ffmpeg(input_path, output_path):
74
  major_brands = ["isom", "mp42", "iso5", "avc1"]
75
  compatible_sets = [
76
  ["isom", "iso2", "avc1", "mp41"],
 
81
  major = random.choice(major_brands)
82
  compatible = ",".join(random.choice(compatible_sets))
83
 
84
+ # Data aleatória nos últimos 6 meses
85
  start_date = datetime.datetime.now() - datetime.timedelta(days=180)
86
+ random_date = start_date + datetime.timedelta(
87
+ days=random.randint(0, 180),
88
+ seconds=random.randint(0, 86400)
89
+ )
90
  date_str = random_date.strftime("%Y-%m-%d %H:%M:%S")
91
 
92
  def randstr(n=12):
 
102
  "publisher": randstr(10),
103
  "encoded_by": randstr(10),
104
  "creation_time": date_str,
 
 
105
  }
106
 
107
+ cmd = [
108
+ "ffmpeg", "-i", input_path,
109
+ "-map_metadata", "-1", # remove metadados antigos
110
+ "-metadata", f"major_brand={major}",
111
+ "-metadata", f"compatible_brands={compatible}",
112
+ ]
113
+
114
  for k, v in metadata.items():
115
  cmd += ["-metadata", f"{k}={v}"]
116
 
117
+ cmd += [
118
+ "-c:v", "libx264", "-preset", "fast", "-crf", "18",
119
+ "-c:a", "aac", "-b:a", "192k",
120
+ output_path
121
+ ]
122
 
123
+ subprocess.run(cmd, check=True)
 
 
 
 
 
 
 
 
124
 
125
  # --- Upload ---
126
+
127
  st.header("📤 Upload de Arquivos")
128
+
129
+ st.subheader("Selecione uma categoria:")
130
+
131
  categoria = st.radio("Categoria:", CATEGORIES, index=None)
132
+
133
+ # Checkbox para randomização
134
+ apply_metadata = st.checkbox("🔀 Aleatorizar metadados de vídeos")
135
 
136
  if categoria:
137
  uploaded_files = st.file_uploader(
 
146
  folder = os.path.join(BASE_FOLDER, categoria)
147
  file_path = os.path.join(folder, uploaded_file.name)
148
 
149
+ # Salva temporário
150
+ temp_path = file_path + ".tmp"
151
+ with open(temp_path, "wb") as f:
152
  f.write(uploaded_file.read())
153
 
154
+ # Se for vídeo e checkbox marcado, randomiza
155
+ if apply_metadata and uploaded_file.name.lower().endswith((".mp4", ".mov", ".mkv")):
156
+ try:
157
+ randomize_video_metadata_ffmpeg(temp_path, file_path)
158
+ os.remove(temp_path)
159
+ except Exception as e:
160
+ st.error(f"Erro ao processar metadados: {e}")
161
+ os.rename(temp_path, file_path)
162
+ else:
163
+ os.rename(temp_path, file_path)
164
+
165
+ # Salvar expiração se marcada
166
  if auto_delete:
167
  key = f"{categoria}|||{uploaded_file.name}"
168
  expirations[key] = time.time() + 24 * 60 * 60
 
172
  st.success("Arquivos enviados com sucesso!")
173
  st.rerun()
174
 
175
+ # --- Lista de Arquivos agrupada por pasta ---
176
  st.header("📄 Arquivos Disponíveis")
177
+
178
  for categoria in CATEGORIES:
179
  folder = os.path.join(BASE_FOLDER, categoria)
180
  files = os.listdir(folder)
181
+
182
  st.subheader(f"📁 {categoria}")
183
+
184
  if not files:
185
  st.info("Nenhum arquivo na categoria.")
186
  else:
187
  for file in files:
188
  st.markdown(f"<div class='file-box'>", unsafe_allow_html=True)
189
  st.markdown(f"<div class='file-name'>{file}</div>", unsafe_allow_html=True)
190
+
191
  key = f"{categoria}|||{file}"
192
+
193
  expira = expirations.get(key)
194
  if expira:
195
  restante = int(expira - time.time())
196
  if restante > 0:
197
+ restante_horas = restante // 3600
198
+ restante_min = (restante % 3600) // 60
199
+ st.markdown(
200
+ f"<div class='expire-text'>⏳ Expira em {restante_horas}h {restante_min}min</div>",
201
+ unsafe_allow_html=True)
202
+ else:
203
+ st.markdown("<div class='expire-text'>⚠ Expiração iminente</div>", unsafe_allow_html=True)
204
 
205
  col1, col2, col3 = st.columns(3)
206
+
207
  with col1:
208
  with open(os.path.join(folder, file), "rb") as f_obj:
209
  st.download_button("⬇ Download", f_obj, file_name=file, key=f"down_{categoria}_{file}")
210
+
211
  with col2:
212
  if st.button("🗑 Excluir", key=f"delete_{categoria}_{file}"):
213
  os.remove(os.path.join(folder, file))
 
216
  json.dump(expirations, f)
217
  st.success(f"Arquivo '{file}' excluído.")
218
  st.rerun()
219
+
220
  with col3:
221
  with open(os.path.join(folder, file), "rb") as f_obj:
222
  if st.download_button("⬇ Baixar & Apagar", f_obj, file_name=file, key=f"download_delete_{categoria}_{file}"):
 
226
  json.dump(expirations, f)
227
  st.success(f"Arquivo '{file}' baixado e removido.")
228
  st.rerun()
229
+
230
  st.markdown("</div>", unsafe_allow_html=True)