diff --git a/past.py b/past.py index 962d522..89c124b 100644 --- a/past.py +++ b/past.py @@ -31,9 +31,9 @@ if __name__ == '__main__': # dt = datetime.datetime.strptime("2023-12-14 23:02:14", "%Y-%m-%d %H:%M:%S") - dt = datetime.datetime.strptime("2025-11-13 23:02:14", "%Y-%m-%d %H:%M:%S") + dt = datetime.datetime.strptime("2024-01-11 22:45:01", "%Y-%m-%d %H:%M:%S") tick = int(convert_sec_to_ticks(convert_date_to_sec(dt), TIMESCALE)) - # print(tick) + print(tick) # # 1280x720, 3000 # track_id = "0_1_390" @@ -43,16 +43,19 @@ if __name__ == '__main__': # track_id = "0_1_3525" # # not found - # # 1920x1080, 4800 - video_track_id = "0_1_3524" - video_base1 = 153232896150968 + # # # 1920x1080, 4800 + # video_track_id = "0_1_3524" + # video_base1 = 153232896150968 - # audio fra_main - audio_track_id = "0_1_384" - audio_base2 = 153232896097804 + # # audio fra_main + # audio_track_id = "0_1_384" + # audio_base2 = 153232896097804 + + # # 1920x1080, 4800 France 2 + video_track_id = "0_1_3566" - asyncio.run(bruteforce(audio_track_id, tick)) + asyncio.run(bruteforce(video_track_id, tick)) # # https://catalogue.ina.fr/doc/TV-RADIO/TV_8165000.001/Bordeaux_%2Bchampagne%2B_%2Bquand%2Bles%2Bescrocs%2Bs_attaquent%2Ba%2Bnos%2Bbouteilles%2B_ diff --git a/pyproject.toml b/pyproject.toml index 55c1ce4..91dcd84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,8 @@ dependencies = [ "python-dotenv>=1.2.1", "pywidevine>=1.9.0", "requests>=2.32.5", + "tabulate>=0.9.0", + "tqdm>=4.67.1", ] [project.scripts] diff --git a/requirements.txt b/requirements.txt index 49a4fc9..9886943 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,5 @@ InquirerPy==0.3.4 python-dotenv==1.2.1 pywidevine==1.9.0 Requests==2.32.5 +tabulate==0.9.0 +tqdm==4.67.1 diff --git a/utils/stream.py b/utils/stream.py index 35ac8f1..9f428db 100644 --- a/utils/stream.py +++ b/utils/stream.py @@ -383,12 +383,9 @@ async def fetch_segment(session, ticks, track_id): try: async with session.get(url, headers=headers) as resp: if resp.status == 200: - print(f"✅ {ticks} → 200 OK") return ticks - print(f"❌ {ticks} → {resp.status}") return None - except aiohttp.ClientError as e: - print(f"⚠️ {ticks} → {e}") + except aiohttp.ClientError: return None def get_init(track_id): diff --git a/utils/times.py b/utils/times.py index 144b692..06903bb 100644 --- a/utils/times.py +++ b/utils/times.py @@ -4,6 +4,7 @@ import datetime import time import aiohttp +from tqdm import tqdm from utils.stream import fetch_segment @@ -49,57 +50,61 @@ def future(rep, base, duration): async def bruteforce(track_id, date): """Bruteforce segments to find valid ticks.""" valid_ticks = [] - total_requests = 288000 - pas = 20000 - - for i in range(total_requests // pas): - debut = pas * i - fin = debut + pas - - segment_num = i + 1 - total_segments = total_requests // pas - print(f"\n🚀 Starting bruteforce segment {segment_num}/{total_segments} " - f"(ticks {debut} to {fin})...") - - checked_ticks = set() - ticks_to_check = list(range(debut, fin)) - start_time = time.time() - try: - async with aiohttp.ClientSession() as session: - tasks = [fetch_segment(session, t+date, track_id) for t in ticks_to_check] - results = await asyncio.gather(*tasks, return_exceptions=True) + batch_size = 20000 + checked_count = 0 + + print(f"\n🚀 Starting bruteforce...") + print(f"📦 Track ID: {track_id}") + print(f"🎯 Total ticks to check: {total_requests}") + print(f"{'='*50}\n") + + start_time = time.time() + + total_batches = (total_requests + batch_size - 1) // batch_size + + try: + async with aiohttp.ClientSession() as session: + for batch_num, batch_start in enumerate(range(0, total_requests, batch_size), 1): + batch_end = min(batch_start + batch_size, total_requests) + ticks_to_check = list(range(batch_start, batch_end)) + + print(f"\n📦 Batch {batch_num}/{total_batches} (ticks {batch_start} to {batch_end})") + + tasks = [fetch_segment(session, t + date, track_id) for t in ticks_to_check] + + results = [] + for coro in tqdm(asyncio.as_completed(tasks), total=len(tasks), + desc=f"Batch {batch_num}", unit="req"): + result = await coro + results.append(result) + new_valid = [r for r in results if r and not isinstance(r, Exception)] valid_ticks.extend(new_valid) - - # Mark all checked ticks - checked_ticks.update(ticks_to_check) - except KeyboardInterrupt: - print("\n\n🛑 Interrupted by user (Ctrl+C)") - # Save progress even if interrupted - checked_ticks.update(list(ticks_to_check)) # Mark attempted as checked - end_time = time.time() - elapsed = end_time - start_time - req_per_sec = len(ticks_to_check) / elapsed if elapsed > 0 else 0 - - print(f"\n{'='*50}") - print(f"✅ Completed in {elapsed:.2f}s") - print(f"⚡ Speed: {req_per_sec:.2f} req/s") - print(f"📊 Total checked: {len(checked_ticks)}/{total_requests}") - print(f"🎯 Valid ticks found: {len(valid_ticks)}") - # print(f"💾 Progress saved to {PROGRESS_FILE}") - print(f"{'='*50}") - if valid_ticks: - checked_ticks.update(list(ticks_to_check)) - end_time = time.time() - elapsed = end_time - start_time - req_per_sec = len(ticks_to_check) / elapsed if elapsed > 0 else 0 - print(f"✅ Completed in {elapsed:.2f}s") - print(f"⚡ Speed: {req_per_sec:.2f} req/s") - print(f"📊 Total checked: {len(checked_ticks)}/{total_requests}") - print("Ticks valides :", valid_ticks) - # break from the for loop if valid ticks found - break + + checked_count += len(ticks_to_check) + + # Stop if we found valid ticks + if valid_ticks: + print(f"\n✅ Found {len(valid_ticks)} valid tick(s)!") + break + + except KeyboardInterrupt: + print("\n\n🛑 Interrupted by user (Ctrl+C)") + + end_time = time.time() + elapsed = end_time - start_time + req_per_sec = checked_count / elapsed if elapsed > 0 else 0 + + print(f"\n{'='*50}") + print(f"✅ Completed in {elapsed:.2f}s") + print(f"⚡ Speed: {req_per_sec:.2f} req/s") + print(f"📊 Total checked: {checked_count}/{total_requests}") + if valid_ticks: + print(f"📍 Valid ticks: {valid_ticks}") + print(f"{'='*50}") + + return valid_ticks def find_nearest_tick_by_hour(base_tick, datetime_str, timescale, duration, offset_hours=1): diff --git a/uv.lock b/uv.lock index c5cfd58..6764fe5 100644 --- a/uv.lock +++ b/uv.lock @@ -762,6 +762,8 @@ dependencies = [ { name = "python-dotenv" }, { name = "pywidevine" }, { name = "requests" }, + { name = "tabulate" }, + { name = "tqdm" }, ] [package.dev-dependencies] @@ -777,6 +779,8 @@ requires-dist = [ { name = "python-dotenv", specifier = ">=1.2.1" }, { name = "pywidevine", specifier = ">=1.9.0" }, { name = "requests", specifier = ">=2.32.5" }, + { name = "tabulate", specifier = ">=0.9.0" }, + { name = "tqdm", specifier = ">=4.67.1" }, ] [package.metadata.requires-dev] @@ -1190,6 +1194,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] +[[package]] +name = "tabulate" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090, upload-time = "2022-10-06T17:21:48.54Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, +] + [[package]] name = "tomli" version = "2.3.0" @@ -1248,6 +1261,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, +] + [[package]] name = "typing-extensions" version = "4.15.0"