def extract_archives(folder_path): for file in...

Created on: May 8, 2025

Answered using O3 by Chat01

Question

def extract_archives(folder_path):
for file in os.listdir(folder_path):
full_path = os.path.join(folder_path, file)
if not os.path.isfile(full_path):
continue

text
if file.lower().endswith('.zip'): with zipfile.ZipFile(full_path, 'r') as zip_ref: extract_path = os.path.join(folder_path, f"extracted_{os.path.splitext(file)[0]}") os.makedirs(extract_path, exist_ok=True) zip_ref.extractall(extract_path) print(f"📦 Распакован ZIP: {file} → {extract_path}") os.remove(full_path) elif file.lower().endswith('.rar'): with rarfile.RarFile(full_path, 'r') as rar_ref: extract_path = os.path.join(folder_path, f"extracted_{os.path.splitext(file)[0]}") os.makedirs(extract_path, exist_ok=True) rar_ref.extractall(extract_path) print(f"📦 Распакован RAR: {file} → {extract_path}") os.remove(full_path) # Удаляем все пустые папки после распаковки for root, dirs, files in os.walk(folder_path, topdown=False): for dir_name in dirs: dir_path = os.path.join(root, dir_name) try: if not os.listdir(dir_path): os.rmdir(dir_path) print(f"🗑 Удалена пустая папка: {dir_path}") except OSError: pass

def collect_video_files(root_folder):
video_files = []
for dirpath, _, filenames in os.walk(root_folder):
if "FINAL" in dirpath:
continue # ⛔️ Пропускаем папку FINAL
for file in filenames:
if file.lower().endswith(('.mp4', '.mov', '.mkv', '.qt')):
video_files.append(os.path.join(dirpath, file))
return video_files

def process_videos_in_background(folder_path):
try:
extract_archives(folder_path)

text
# Удаляем все файлы кроме видео for root, _, files in os.walk(folder_path): for file in files: if not file.lower().endswith(('.mp4', '.mov', '.mkv', '.qt')): file_path = os.path.join(root, file) os.remove(file_path) print(f"🗑 Удален лишний файл: {file_path}") processor_script = r"C:\GENERATOR\PYTHON_FILES\ENVATO_RENDER.py" # Запускаем процесс с unbuffered выводом process = subprocess.Popen( ['python', '-u', processor_script, folder_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, encoding='utf-8', errors='replace', creationflags=subprocess.CREATE_NEW_PROCESS_GROUP ) # Мониторим вывод в реальном времени completion_flag = False while True: output_line = process.stdout.readline() if not output_line and process.poll() is not None: break if output_line: print(f"RENDER: {output_line.strip()}") if "🎉 Всё готово! Можно проверять папку FINAL" in output_line: completion_flag = True break # Проверяем статус завершения if completion_flag: print("✅ Рендеринг успешно завершен") else: print("⚠️ Рендеринг завершился без сигнала успеха") except Exception as e: print(f"⚠️ Ошибка в обработке видео: {e}") finally: # Гарантируем завершение процесса if process.poll() is None: process.terminate() process.wait()

def wait_for_downloads_browser_based(driver, batch_name, download_folder, timeout=1800):
print("🧭 Открываем chrome://downloads/ в новой вкладке")

text
original_window = driver.current_window_handle driver.execute_script("window.open('');") WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > 1) new_tab = [handle for handle in driver.window_handles if handle != original_window][0] driver.switch_to.window(new_tab) driver.get("chrome://downloads/") time.sleep(10) print("⏳ Ожидаем завершения загрузок...") def ensure_downloads_tab(): time.sleep(10) if driver.current_window_handle != new_tab: print("🔁 Chrome открыл другую вкладку — возвращаемся на downloads") try: driver.switch_to.window(new_tab) except Exception as e: print(f"⚠️ Не удалось переключиться обратно: {e}") threading.Thread(target=ensure_downloads_tab, daemon=True).start() start_time = time.time() stable_iterations = 0 while time.time() - start_time < timeout: try: items = driver.execute_script(""" const manager = document.querySelector('downloads-manager'); const items = manager.shadowRoot.querySelector('#downloadsList').items; return items ? JSON.stringify(items.map(item => ({ fileName: item.fileName, state: item.state, percent: item.percent }))) : null; """) if not items: print("📭 Список загрузок пуст или не найден.") time.sleep(2) continue downloads = json.loads(items) print(f"\n📦 Найдено {len(downloads)} загрузок:") for d in downloads: state_str = { 0: "⬇️ В процессе", 1: "❌ Отменено", 2: "✅ Завершено", 3: "⚠️ Прервано" }.get(d["state"], f"❓ Неизвестно ({d['state']})") percent = f"{d['percent']}%" if d["state"] == 0 else "—" print(f" ├─ 📄 {d['fileName']} — {state_str} — {percent}") in_progress = [d for d in downloads if d["state"] == 0] if not in_progress: stable_iterations += 1 if stable_iterations >= 3: print("✅ Все загрузки завершены (стабильное состояние)") try: driver.close() driver.switch_to.window(original_window) print("🔙 Вернулись на основную вкладку и закрыли downloads") except Exception as e: print(f"⚠️ Ошибка при закрытии вкладки или переключении: {e}") # 🔽 Начинаем файловое отслеживание и перемещение print("📂 Проверяем загруженные файлы в папке...") time.sleep(3) # дать системе записать файлы existing_files = os.listdir(download_folder) completed_files = [ f for f in existing_files if f.lower().endswith(('.mp4', '.mov', '.mkv', '.zip', '.rar', '.qt')) and not f.endswith('.crdownload') ] if completed_files: batch_folder = os.path.join(download_folder, batch_name) os.makedirs(batch_folder, exist_ok=True) for file_name in completed_files: src = os.path.join(download_folder, file_name) dst = os.path.join(batch_folder, file_name) if os.path.exists(src): shutil.move(src, dst) print(f"📁 Перемещён: {file_name} &rarr; {batch_folder}") return True else: print("⚠️ Не удалось найти завершённые файлы после загрузки.") return False else: stable_iterations = 0 except Exception as e: print(f"⚠️ Ошибка при получении данных: {e}") time.sleep(2) else: print("⏱ Время ожидания вышло. Некоторые файлы, возможно, не догрузились.") try: driver.close() driver.switch_to.window(original_window) print("🔙 Вернулись на основную вкладку") except Exception as e: print(f"⚠️ Ошибка при закрытии вкладки или переключении: {e}") return False

def wait_for_downloads(download_folder, batch_name, expected_count=3, max_wait=60, poll_interval=3):
print("⏳ Ожидание загрузки файлов...")

text
start_time = time.time() existing_files = set(os.listdir(download_folder)) tracked_files = set() # 1. Ожидаем появления новых файлов (до expected_count) while time.time() - start_time < max_wait: current_files = set(os.listdir(download_folder)) new_files = current_files - existing_files # Только завершённые файлы (не .crdownload) completed = {f for f in new_files if not f.endswith('.crdownload')} if completed: print(f"📥 Завершенные загрузки: {list(completed)}") tracked_files.update(completed) if len(tracked_files) >= expected_count: break print(f"🔄 Ожидаем ещё... Сейчас завершено: {len(tracked_files)}") time.sleep(poll_interval) if not tracked_files: print("⚠️ Не удалось отследить завершенные загрузки.") return [] print("⌛ Убеждаемся, что файлы не увеличиваются (стабилизировались)...") time.sleep(3) # немного подождать на всякий случай # Перемещение завершённых файлов batch_folder = os.path.join(download_folder, batch_name) os.makedirs(batch_folder, exist_ok=True) for file_name in tracked_files: src = os.path.join(download_folder, file_name) dst = os.path.join(batch_folder, file_name) if os.path.exists(src): shutil.move(src, dst) print(f"📁 Перемещён: {file_name} &rarr; {batch_folder}") return list(tracked_files)

def process_bulk_downloads(driver):
"""
Основной цикл: парсит *.txt с линками, разбитыми на секции вида general, waterfall
─ скачивает файлы пачками по 3‑шт;
─ после каждой успешной загрузки и распаковки перемещает итоговые ВИДЕО‑файлы в
C:\READY<имя‑txt><секция>;
─ в конце каждого .txt запускает рендер всего набора.
Файл .txt «обрезается» по мере обработки, чтобы можно было возобновиться с места сбоя.
"""
global current_account_index

text
ENVATO_TXT_FOLDER = r"C:\ENVATO" READY_ROOT_FOLDER = r"C:\ENVATO_DOWNLOAD" txt_files = [os.path.join(ENVATO_TXT_FOLDER, f) for f in os.listdir(ENVATO_TXT_FOLDER) if f.lower().endswith(".txt")] # ──────────────────────────────────────────────────────────────────────────── def _update_txt(path, sections_dict): """Перезаписать .txt, оставив только ещё не скачанные ссылки.""" with open(path, "w", encoding="utf-8") as f_out: out_lines = [] for sec, links in sections_dict.items(): if not links: continue out_lines.append(f"*{sec}*") out_lines.extend(links) f_out.write("\n".join(out_lines)) # ──────────────────────────────────────────────────────────────────────────── for txt_path in txt_files: batch_name = os.path.splitext(os.path.basename(txt_path))[0] # ── Читаем и парсим секции sections = {} current = None with open(txt_path, "r", encoding="utf-8") as f_in: for raw in f_in: line = raw.strip() if not line: continue if line.startswith("*") and line.endswith("*") and len(line) > 2: current = line.strip("*").strip() sections[current] = [] elif current: sections[current].append(line) if not sections: print(f"⚠️ В {txt_path} нет секций/ссылок – пропуск.") continue print(f"\n📂 Обработка набора: {batch_name}; ({len(sections)} секций)") # ──────────────────────────────────────────────────────────────────── for section_name, link_pool in sections.items(): if not link_pool: continue ready_folder = os.path.join(READY_ROOT_FOLDER, batch_name, section_name) os.makedirs(ready_folder, exist_ok=True) print(f"\n⭐ Секция *{section_name}* — осталось ссылок: {len(link_pool)}") # ── Цикл пакетных скачиваний внутри секции while link_pool: # ── Проверка лимита try: driver.get("https://www.filesta.com/envato") limit_elem = WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.ID, "remainingLimit")) ) remaining = int(limit_elem.text.split("/")[0].strip()) if remaining <= 0: raise RuntimeError("Лимит исчерпан") # критическая except TimeoutException: print("🔄 Страница не успела прогрузиться, пробуем ещё раз") continue # та же учётка, тот же драйвер except Exception as e: print(f"⚠️ {e} – переключаю аккаунт") driver.quit() current_account_index = (current_account_index + 1) % len(ACCOUNTS) driver = login(ACCOUNTS[current_account_index]) continue batch_links = link_pool[:3] try: # ── Вставляем ссылки в форму &laquo;Массовое скачивание&raquo; driver.get("https://www.filesta.com/envato") toggle = WebDriverWait(driver, 30).until( EC.element_to_be_clickable( (By.CSS_SELECTOR, "div.card-header[data-target='#bulkDownloadArea']"))) driver.execute_script( "arguments[0].scrollIntoView({behavior:'smooth',block:'center'});", toggle) driver.execute_script("window.scrollBy(0, 200);") toggle.click() textarea = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "bulkLinks"))) textarea.clear() textarea.send_keys("\n".join(batch_links)) WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "startBulkDownload"))).click() print(f"⬇️ Скачивание {len(batch_links)} файл(ов)…") # ── Ждём завершения через chrome://downloads ok = wait_for_downloads_browser_based( driver, batch_name=f"{batch_name}_{section_name}", download_folder=ready_folder ) if not ok: raise Exception("Скачивание не подтвердило успех") # Распаковка, удаление мусора extract_archives(ready_folder) for root, _, files in os.walk(ready_folder): for f in files: if not f.lower().endswith(('.mp4', '.mov', '.mkv', '.qt')): os.remove(os.path.join(root, f)) print("✅ Пакет успешно обработан") # ── Удаляем обработанные ссылки из пула и обновляем .txt link_pool = link_pool[3:] sections[section_name] = link_pool _update_txt(txt_path, sections) except TimeoutException: print("🔄 Страница не успела прогрузиться, пробуем ещё раз") continue # та же учётка, тот же драйвер except Exception as ex: print(f"⚠️ Ошибка внутри пакета: {ex}\n🔄 Повтор через 3 сек") time.sleep(3) continue # повторим пакет # ─────────────────────────────────────────────── # Когда ВСЕ секции .txt скачаны &rarr; рендер if all(not lst for lst in sections.values()): parent_ready = os.path.join(READY_ROOT_FOLDER, batch_name) print(f"\n🚀 Все секции {batch_name} готовы — запускаю рендер.") process_videos_in_background(parent_ready) else: print(f"⚠️ В {batch_name} остались необработанные ссылки – рендер пропущен") print("\n🔥 Все .txt обработаны!")

def login(account):
global current_account_index
extension_path = r"C:\GENERATOR\PYTHON_FILES\zencap"
download_folder = r"C:\ENVATO_DOWNLOAD"
proxy = "127.0.0.1:1081"

text
chrome_options = Options() chrome_options.add_argument(f"--load-extension={extension_path}") chrome_options.add_experimental_option("prefs", { "download.default_directory": download_folder, "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True, "profile.content_settings.exceptions.automatic_downloads.*.setting": 1, "profile.default_content_setting_values.automatic_downloads": 1, "credentials_enable_service": False, "profile.password_manager_enabled": False, "profile.default_content_settings.popups": 0 }) chrome_options.set_capability("pageLoadStrategy", "none") service = Service() driver = webdriver.Chrome(service=service, options=chrome_options) driver.set_page_load_timeout(10) # Максимальное время загрузки страницы — 10 секунд try: try: driver.get("https://www.filesta.com/login") except TimeoutException as e: print(f"Страница не загрузилась за 10 секунд") driver.execute_script("window.stop();") # <<< Останавливает загрузку вкладки pass WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.CSS_SELECTOR, "iframe[title='reCAPTCHA']")) ) print("Ожидание прохождения капчи...") WebDriverWait(driver, 300).until( lambda d: d.execute_script("return document.getElementById('g-recaptcha-response').value") != "" ) print("Капча пройдена!") driver.find_element(By.NAME, "InputEmail").send_keys(account['email']) time.sleep(0.5) driver.find_element(By.NAME, "InputPassword").send_keys(account['password']) time.sleep(0.5) driver.find_element(By.CSS_SELECTOR, "button.btn.btn-primary.btn-user.btn-block").click() WebDriverWait(driver, 10).until(EC.url_changes("https://www.filesta.com/login")) print("Вход выполнен!") time.sleep(3) return driver except Exception as e: print(f"❌ Ошибка при логине: {e}") driver.quit() current_account_index = (current_account_index + 1) % len(ACCOUNTS) raise

def main_loop():
global current_account_index
while True:
try:
print(f"\n🔁 Используем аккаунт: {ACCOUNTS[current_account_index]['email']}")
driver = login(ACCOUNTS[current_account_index])
process_bulk_downloads(driver)
print("✅ Загрузка завершена")
break
except Exception as e:
print(f"⚠️ Ошибка: {e}\n⏳ Перезапуск через 5 секунд...")
current_account_index = (current_account_index + 1) % len(ACCOUNTS)
time.sleep(5)
continue # Перезапуск

text
finally: try: driver.quit() print("🧹 Браузер закрыт") except: pass

if name == "main":
main_loop()

📂 Проверяем загруженные файлы в папке...
⚠️ Не удалось найти завершённые файлы после загрузки.
⚠️ Ошибка внутри пакета: Скачивание не подтвердило успех

помоги с этим кодом. я что-то напутал в директориях. и теперь код не видит завершенные файлы после загрузки, хотя они есть и успешно скачаны.
пиши полностью функцию

Thought

Evaluating code issue

The user is having trouble with a Python script that handles downloading, checking, and moving video files. Specifically, the script isn't detecting completed downloads in the folder, despite them being there. The core of the problem seems to center around directory handling. I'll need to take a look at the function that monitors the downloads and adjusts pathing to ensure it correctly targets the right folder. I should provide a complete function that addresses the issue with directory confusion and file detection.

Fixing directory path issue

The user specifically asks to write the full function that checks for completed downloads. The issue arises because the code checks the wrong folder: it looks at ready_folder, but the files are saved in C:\ENVATO_DOWNLOAD. The function should validate the download location correctly by first checking the main download folder, then moving the files to the intended destination. I'll correct the code to ensure that it checks in C:\ENVATO_DOWNLOAD initially, then moves files to ready_folder. I'll go ahead and write the corrected function.

Thought for 27 seconds

Answer

Ниже — полностью переписанная версия wait_for_downloads_browser_based.
Главные отличия:

  1. Разделены пути

    • base_download_folder — куда реально скачивает Chrome (у вас это C:\ENVATO_DOWNLOAD, задаётся в chrome_options).
    • dest_folder — конечная папка для текущей пачки (ready_folder = …\batch\section).
      Благодаря этому функция больше не «смотрит» в не-ту директорию.
  2. Более надёжная проверка завершения

    • Сначала ждём, пока в chrome://downloads все элементы получат state == 2 (завершено).
    • Затем убеждаемся, что рядом с файлами нет временных *.crdownload и что размер файлов стабилен 2 цикла подряд.
  3. Настраиваемый список расширений и количество «стабильных» повторов.

python
def wait_for_downloads_browser_based( driver, *, dest_folder: str, base_download_folder: str, timeout: int = 1_800, stable_checks: int = 3, poll: int = 2, exts: tuple = ('.mp4', '.mov', '.mkv', '.qt', '.zip', '.rar') ) -> bool: """ Ждём завершения загрузок через chrome://downloads, а затем перемещаем готовые файлы из base_download_folder &rarr; dest_folder. :param driver: Selenium-драйвер Chrome. :param dest_folder: Куда перемещать (…READY\\<batch>\\<section>). :param base_download_folder: Фактическая папка загрузок Chrome. :param timeout: Максимум ожидания (сек). :param stable_checks: Сколько раз подряд список/размеры файлов должны быть неизменны. :param poll: Период опроса chrome://downloads и диска (сек). :param exts: Допустимые расширения итоговых файлов. :return: True, если хоть один файл успешно перемещён. """ print("🧭 Открываем chrome://downloads/ в новой вкладке") orig_window = driver.current_window_handle driver.execute_script("window.open('');") WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > 1) downloads_tab = [h for h in driver.window_handles if h != orig_window][0] driver.switch_to.window(downloads_tab) driver.get("chrome://downloads/") time.sleep(5) start = time.time() stable_cnt = 0 last_snapshot = None while time.time() - start < timeout: # ── Читаем состояние загрузок через JS try: raw = driver.execute_script(""" const m = document.querySelector('downloads-manager'); const list = m.shadowRoot.querySelector('#downloadsList').items; return list ? JSON.stringify(list.map(x => ({ fileName: x.fileName, state: x.state, percent: x.percent }))) : null; """) except Exception as e: print(f"⚠️ Не удалось прочитать chrome://downloads: {e}") raw = None if raw: items = json.loads(raw) active = [it for it in items if it["state"] == 0] if not active: stable_cnt += 1 if stable_cnt >= stable_checks: print("✅ Все загрузки завершены в Chrome") break else: stable_cnt = 0 else: print("📭 Список загрузок пуст/недоступен") time.sleep(poll) else: print("⏱ Время ожиданияChrome истекло") return False # ── Завершаем работу с вкладкой downloads try: driver.close() driver.switch_to.window(orig_window) except Exception as e: print(f"⚠️ Ошибка при закрытии вкладки: {e}") # ── Проверяем сам диск: ждём, пока файлы &laquo;устаканятся&raquo; stable_cnt = 0 last_sizes = {} while stable_cnt < stable_checks and time.time() - start < timeout: current = { f: os.path.getsize(os.path.join(base_download_folder, f)) for f in os.listdir(base_download_folder) if f.lower().endswith(exts) and not f.endswith('.crdownload') } if current == last_sizes: stable_cnt += 1 else: stable_cnt = 0 last_sizes = current time.sleep(poll) if not last_sizes: print("⚠️ Не найдено завершённых файлов на диске") return False # ── Перемещаем os.makedirs(dest_folder, exist_ok=True) moved = 0 for fname in last_sizes: src = os.path.join(base_download_folder, fname) dst = os.path.join(dest_folder, fname) try: shutil.move(src, dst) print(f"📁 Перемещён: {fname} &rarr; {dest_folder}") moved += 1 except Exception as e: print(f"⚠️ Не удалось переместить {fname}: {e}") if moved: print(f"🎉 Перемещено файлов: {moved}") return True print("⚠️ Ни один файл не перемещён") return False

Как вызывать

В process_bulk_downloads измените вызов так, чтобы передавать обе папки:

python
ok = wait_for_downloads_browser_based( driver, dest_folder=ready_folder, # куда складывать именно эту пачку base_download_folder=r"C:\ENVATO_DOWNLOAD" # общий каталог Chrome )

И проверьте, что chrome_options.add_experimental_option("prefs", {"download.default_directory": r"C:\ENVATO_DOWNLOAD", …}) указывает ровно ту же папку.

После этих изменений скрипт должен находить файлы сразу после завершения загрузок и корректно их перемещать. Если будут вопросы — пишите!

Share this Q&A