def extract_archives(folder_path): for file in...
Created on: May 8, 2025
Created on: May 8, 2025
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
textif 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/ в новой вкладке")
textoriginal_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} → {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("⏳ Ожидание загрузки файлов...")
textstart_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} → {batch_folder}") return list(tracked_files)
def process_bulk_downloads(driver):
"""
Основной цикл: парсит *.txt с линками, разбитыми на секции вида general, waterfall …
─ скачивает файлы пачками по 3‑шт;
─ после каждой успешной загрузки и распаковки перемещает итоговые ВИДЕО‑файлы в
C:\READY<имя‑txt><секция>;
─ в конце каждого .txt запускает рендер всего набора.
Файл .txt «обрезается» по мере обработки, чтобы можно было возобновиться с места сбоя.
"""
global current_account_index
textENVATO_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: # ── Вставляем ссылки в форму «Массовое скачивание» 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 скачаны → рендер 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"
textchrome_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 # Перезапуск
textfinally: try: driver.quit() print("🧹 Браузер закрыт") except: pass
if name == "main":
main_loop()
📂 Проверяем загруженные файлы в папке...
⚠️ Не удалось найти завершённые файлы после загрузки.
⚠️ Ошибка внутри пакета: Скачивание не подтвердило успех
помоги с этим кодом. я что-то напутал в директориях. и теперь код не видит завершенные файлы после загрузки, хотя они есть и успешно скачаны.
пиши полностью функцию
Ниже — полностью переписанная версия wait_for_downloads_browser_based
.
Главные отличия:
Разделены пути
base_download_folder
— куда реально скачивает Chrome (у вас это C:\ENVATO_DOWNLOAD
, задаётся в chrome_options
).dest_folder
— конечная папка для текущей пачки (ready_folder = …\batch\section
).Более надёжная проверка завершения
state == 2
(завершено).*.crdownload
и что размер файлов стабилен 2 цикла подряд.Настраиваемый список расширений и количество «стабильных» повторов.
pythondef 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 → 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}") # ── Проверяем сам диск: ждём, пока файлы «устаканятся» 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} → {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
измените вызов так, чтобы передавать обе папки:
pythonok = 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", …})
указывает ровно ту же папку.
После этих изменений скрипт должен находить файлы сразу после завершения загрузок и корректно их перемещать. Если будут вопросы — пишите!