diff --git a/src/prep.py b/src/prep.py index 98f793b9..f3f86c23 100644 --- a/src/prep.py +++ b/src/prep.py @@ -635,7 +635,7 @@ async def process_tracker(tracker_name, meta): elif meta['is_disc'] == "DVD": if meta.get('edit', False) is False: try: - ds = multiprocessing.Process(target=self.dvd_screenshots, args=(meta, 0, None)) + ds = multiprocessing.Process(target=self.dvd_screenshots, args=(meta, 0, None, None)) ds.start() while ds.is_alive() is True: await asyncio.sleep(1) @@ -1334,12 +1334,12 @@ def capture_disc_task(self, task): console.print(f"[red]Error capturing screenshot: {e}[/red]") return None - def dvd_screenshots(self, meta, disc_num, num_screens=None): + def dvd_screenshots(self, meta, disc_num, num_screens=None, retry_cap=None): if 'image_list' not in meta: meta['image_list'] = [] existing_images = [img for img in meta['image_list'] if isinstance(img, dict) and img.get('img_url', '').startswith('http')] - if len(existing_images) >= meta.get('cutoff'): + if len(existing_images) >= meta.get('cutoff') and not retry_cap: console.print("[yellow]There are already at least {} images in the image list. Skipping additional screenshots.".format(meta.get('cutoff'))) return @@ -1542,7 +1542,6 @@ def screenshots(self, path, filename, folder_id, base_dir, meta, num_screens=Non capture_results = [] task_limit = int(meta.get('task_limit', os.cpu_count())) - capture_tasks = [] for i in range(num_screens + 1): image_path = os.path.abspath(f"{base_dir}/tmp/{folder_id}/{filename}-{i}.png") if not os.path.exists(image_path) or meta.get('retake', False): @@ -1559,7 +1558,7 @@ def screenshots(self, path, filename, folder_id, base_dir, meta, num_screens=Non desc="Capturing Screenshots"): capture_results.append(result) - if capture_results and len(capture_results) > num_screens: + if capture_results and len(capture_results) > num_screens and not force_screenshots: smallest = min(capture_results, key=os.path.getsize) if meta['debug']: console.print(f"[yellow]Removing smallest image: {smallest} ({os.path.getsize(smallest)} bytes)[/yellow]") @@ -1646,21 +1645,34 @@ def valid_ss_time(self, ss_times, num_screens, length, manual_frames=None): def capture_screenshot(self, args): path, ss_time, image_path, width, height, w_sar, h_sar, loglevel = args try: - ff = ffmpeg.input(path, ss=ss_time) + # Validate inputs + if width <= 0 or height <= 0: + return "Error: Invalid width or height for scaling" + + if ss_time < 0: + return f"Error: Invalid timestamp {ss_time}" + ff = ffmpeg.input(path, ss=ss_time) if w_sar != 1 or h_sar != 1: ff = ff.filter('scale', int(round(width * w_sar)), int(round(height * h_sar))) - ( + command = ( ff .output(image_path, vframes=1, pix_fmt="rgb24") .overwrite_output() .global_args('-loglevel', loglevel) - .run() ) + + command.run() + + if not os.path.exists(image_path) or os.path.getsize(image_path) == 0: + return f"Error: Screenshot not generated or is empty at {image_path}" + return image_path + except ffmpeg.Error as e: + return f"FFmpeg Error: {e.stderr.decode()}" except Exception as e: - return f"Error: {e}" + return f"Error: {str(e)}" def optimize_image_task(self, args): image, config = args @@ -2893,6 +2905,7 @@ def upload_image_task(self, args): img_url = response_data['data']['medium']['url'] raw_url = response_data['data']['image']['url'] web_url = response_data['data']['url_viewer'] + if meta['debug']: console.print(f"[green]Image URLs: img_url={img_url}, raw_url={raw_url}, web_url={web_url}") @@ -2929,7 +2942,7 @@ def upload_image_task(self, args): console.print("[yellow]ptscreens failed, trying next image host") return {'status': 'failed', 'reason': 'ptscreens upload failed'} - img_url = response_data['image']['thumb']['url'] + img_url = response_data['image']['medium']['url'] raw_url = response_data['image']['url'] web_url = response_data['image']['url_viewer'] if meta['debug']: @@ -2957,7 +2970,7 @@ def upload_image_task(self, args): console.print(f"[yellow]Response content: {response.content.decode('utf-8')}") response_data = response.json() - if response_data.get('status_code') != 200: + if response.status_code != 200 or not response_data.get('success'): console.print("[yellow]OEimg failed, trying next image host") return {'status': 'failed', 'reason': 'OEimg upload failed'} diff --git a/src/trackers/BHD.py b/src/trackers/BHD.py index c34d2d4e..4c4ef1fb 100644 --- a/src/trackers/BHD.py +++ b/src/trackers/BHD.py @@ -155,7 +155,7 @@ async def upload_with_retry(self, meta, common, img_host_index=1): async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts=None, file=None): if approved_image_hosts is None: - approved_image_hosts = ['ptpimg', 'imgbox'] + approved_image_hosts = ['ptpimg', 'imgbox', 'imgbb', 'pixhost'] retry_mode = False images_reuploaded = False @@ -163,6 +163,7 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts discs = meta.get('discs', []) # noqa F841 filelist = meta.get('video', []) filename = meta['filename'] + path = meta['path'] if isinstance(filelist, str): filelist = [filelist] @@ -179,14 +180,15 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts for i, file in enumerate(filelist): filename_pattern = f"{filename}*.png" - dvd_screens = (glob.glob(f"{meta['base_dir']}/tmp/{meta['uuid']}/{meta['discs'][0]['name']}-*.png")) + if meta['is_disc'] == "DVD": - existing_screens = dvd_screens + existing_screens = glob.glob(f"{meta['base_dir']}/tmp/{meta['uuid']}/{meta['discs'][0]['name']}-*.png") else: existing_screens = glob.glob(os.path.join(screenshots_dir, filename_pattern)) + if len(existing_screens) < multi_screens: if meta.get('debug'): - console.print("[yellow]The image host of exsting images is not supported.") + console.print("[yellow]The image host of existing images is not supported.") console.print(f"[yellow]Insufficient screenshots found: generating {multi_screens} screenshots.") if meta['is_disc'] == "BDMV": @@ -198,12 +200,12 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts elif meta['is_disc'] == "DVD": s = multiprocessing.Process( target=prep.dvd_screenshots, - args=(meta, 0, None) + args=(meta, 0, None, True) ) else: s = multiprocessing.Process( target=prep.screenshots, - args=(file, f"{filename}", meta['uuid'], base_dir, + args=(path, f"{filename}", meta['uuid'], base_dir, meta, multi_screens + 1, True, None) ) @@ -211,41 +213,54 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts while s.is_alive(): await asyncio.sleep(1) - existing_screens = glob.glob(os.path.join(screenshots_dir, filename_pattern)) + if meta['is_disc'] == "DVD": + existing_screens = glob.glob(f"{meta['base_dir']}/tmp/{meta['uuid']}/{meta['discs'][0]['name']}-*.png") + else: + existing_screens = glob.glob(os.path.join(screenshots_dir, filename_pattern)) all_screenshots.extend(existing_screens) - if all_screenshots: - while True: - current_img_host_key = f'img_host_{img_host_index}' - current_img_host = self.config.get('DEFAULT', {}).get(current_img_host_key) + if not all_screenshots: + console.print("[red]No screenshots were generated or found. Please check the screenshot generation process.") + return [], True, images_reuploaded + + uploaded_images = [] + while True: + current_img_host_key = f'img_host_{img_host_index}' + current_img_host = self.config.get('DEFAULT', {}).get(current_img_host_key) + + if not current_img_host: + console.print("[red]No more image hosts left to try.") + raise Exception("No valid image host found in the config.") + + if current_img_host not in approved_image_hosts: + console.print(f"[red]Your preferred image host '{current_img_host}' is not supported at BHD, trying next host.") + retry_mode = True + images_reuploaded = True + img_host_index += 1 + continue + else: + meta['imghost'] = current_img_host + console.print(f"[green]Uploading to approved host '{current_img_host}'.") + break - if not current_img_host: - console.print("[red]No more image hosts left to try.") - raise Exception("No valid image host found in the config.") + uploaded_images, _ = prep.upload_screens( + meta, multi_screens, img_host_index, 0, multi_screens, + all_screenshots, {new_images_key: meta[new_images_key]}, retry_mode + ) - if current_img_host not in approved_image_hosts: - console.print(f"[red]Your preferred image host '{current_img_host}' is not supported at BHD, trying next host.") - retry_mode = True - images_reuploaded = True - img_host_index += 1 - continue - else: - meta['imghost'] = current_img_host - console.print(f"[green]Uploading to approved host '{current_img_host}'.") - break - uploaded_images, _ = prep.upload_screens(meta, multi_screens, img_host_index, 0, multi_screens, all_screenshots, {new_images_key: meta[new_images_key]}, retry_mode) + if uploaded_images: + meta[new_images_key] = uploaded_images - if uploaded_images: - meta[new_images_key] = uploaded_images if meta['debug']: for image in uploaded_images: console.print(f"[debug] Response in upload_image_task: {image['img_url']}, {image['raw_url']}, {image['web_url']}") + if not all(any(x in image['raw_url'] for x in approved_image_hosts) for image in meta.get(new_images_key, [])): console.print("[red]Unsupported image host detected, please use one of the approved image hosts") return meta[new_images_key], True, images_reuploaded # Trigger retry_mode if switching hosts - return meta[new_images_key], False, images_reuploaded # Return retry_mode and images_reuploaded + return meta[new_images_key], False, images_reuploaded async def get_cat_id(self, category_name): category_id = { diff --git a/src/trackers/COMMON.py b/src/trackers/COMMON.py index 2247348b..94c03278 100644 --- a/src/trackers/COMMON.py +++ b/src/trackers/COMMON.py @@ -164,7 +164,7 @@ async def unit3d_edit_desc(self, meta, tracker, signature, comparison=False, des await asyncio.sleep(1) new_screens = glob.glob1(f"{meta['base_dir']}/tmp/{meta['uuid']}", f"FILE_{i}-*.png") elif each['type'] == "DVD": - s = multiprocessing.Process(target=prep.dvd_screenshots, args=(meta, i, multi_screens)) + s = multiprocessing.Process(target=prep.dvd_screenshots, args=(meta, i, multi_screens, True)) s.start() while s.is_alive() is True: await asyncio.sleep(1) diff --git a/src/trackers/MTV.py b/src/trackers/MTV.py index 11c2d646..1e569110 100644 --- a/src/trackers/MTV.py +++ b/src/trackers/MTV.py @@ -187,6 +187,7 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts discs = meta.get('discs', []) # noqa F841 filelist = meta.get('video', []) filename = meta['filename'] + path = meta['path'] if isinstance(filelist, str): filelist = [filelist] @@ -203,14 +204,15 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts for i, file in enumerate(filelist): filename_pattern = f"{filename}*.png" - dvd_screens = (glob.glob(f"{meta['base_dir']}/tmp/{meta['uuid']}/{meta['discs'][0]['name']}-*.png")) + if meta['is_disc'] == "DVD": - existing_screens = dvd_screens + existing_screens = glob.glob(f"{meta['base_dir']}/tmp/{meta['uuid']}/{meta['discs'][0]['name']}-*.png") else: existing_screens = glob.glob(os.path.join(screenshots_dir, filename_pattern)) + if len(existing_screens) < multi_screens: if meta.get('debug'): - console.print("[yellow]The image host of exsting images is not supported.") + console.print("[yellow]The image host of existing images is not supported.") console.print(f"[yellow]Insufficient screenshots found: generating {multi_screens} screenshots.") if meta['is_disc'] == "BDMV": @@ -222,12 +224,12 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts elif meta['is_disc'] == "DVD": s = multiprocessing.Process( target=prep.dvd_screenshots, - args=(meta, 0, None) + args=(meta, 0, None, True) ) else: s = multiprocessing.Process( target=prep.screenshots, - args=(file, f"{filename}", meta['uuid'], base_dir, + args=(path, f"{filename}", meta['uuid'], base_dir, meta, multi_screens + 1, True, None) ) @@ -235,41 +237,54 @@ async def handle_image_upload(self, meta, img_host_index=1, approved_image_hosts while s.is_alive(): await asyncio.sleep(1) - existing_screens = glob.glob(os.path.join(screenshots_dir, filename_pattern)) + if meta['is_disc'] == "DVD": + existing_screens = glob.glob(f"{meta['base_dir']}/tmp/{meta['uuid']}/{meta['discs'][0]['name']}-*.png") + else: + existing_screens = glob.glob(os.path.join(screenshots_dir, filename_pattern)) all_screenshots.extend(existing_screens) - if all_screenshots: - while True: - current_img_host_key = f'img_host_{img_host_index}' - current_img_host = self.config.get('DEFAULT', {}).get(current_img_host_key) + if not all_screenshots: + console.print("[red]No screenshots were generated or found. Please check the screenshot generation process.") + return [], True, images_reuploaded + + uploaded_images = [] + while True: + current_img_host_key = f'img_host_{img_host_index}' + current_img_host = self.config.get('DEFAULT', {}).get(current_img_host_key) + + if not current_img_host: + console.print("[red]No more image hosts left to try.") + raise Exception("No valid image host found in the config.") + + if current_img_host not in approved_image_hosts: + console.print(f"[red]Your preferred image host '{current_img_host}' is not supported at MTV, trying next host.") + retry_mode = True + images_reuploaded = True + img_host_index += 1 + continue + else: + meta['imghost'] = current_img_host + console.print(f"[green]Uploading to approved host '{current_img_host}'.") + break - if not current_img_host: - console.print("[red]No more image hosts left to try.") - raise Exception("No valid image host found in the config.") + uploaded_images, _ = prep.upload_screens( + meta, multi_screens, img_host_index, 0, multi_screens, + all_screenshots, {new_images_key: meta[new_images_key]}, retry_mode + ) - if current_img_host not in approved_image_hosts: - console.print(f"[red]Your preferred image host '{current_img_host}' is not supported at MTV, trying next host.") - retry_mode = True - images_reuploaded = True - img_host_index += 1 - continue - else: - meta['imghost'] = current_img_host - console.print(f"[green]Uploading to approved host '{current_img_host}'.") - break - uploaded_images, _ = prep.upload_screens(meta, multi_screens, img_host_index, 0, multi_screens, all_screenshots, {new_images_key: meta[new_images_key]}, retry_mode) + if uploaded_images: + meta[new_images_key] = uploaded_images - if uploaded_images: - meta[new_images_key] = uploaded_images if meta['debug']: for image in uploaded_images: console.print(f"[debug] Response in upload_image_task: {image['img_url']}, {image['raw_url']}, {image['web_url']}") + if not all(any(x in image['raw_url'] for x in approved_image_hosts) for image in meta.get(new_images_key, [])): console.print("[red]Unsupported image host detected, please use one of the approved image hosts") return meta[new_images_key], True, images_reuploaded # Trigger retry_mode if switching hosts - return meta[new_images_key], False, images_reuploaded # Return retry_mode and images_reuploaded + return meta[new_images_key], False, images_reuploaded async def edit_desc(self, meta): base = open(f"{meta['base_dir']}/tmp/{meta['uuid']}/DESCRIPTION.txt", 'r', encoding='utf-8').read() diff --git a/src/trackers/PTP.py b/src/trackers/PTP.py index 5d530781..772633c1 100644 --- a/src/trackers/PTP.py +++ b/src/trackers/PTP.py @@ -741,7 +741,7 @@ async def edit_desc(self, meta): meta[new_images_key] = [] new_screens = glob.glob1(f"{meta['base_dir']}/tmp/{meta['uuid']}", f"{meta['discs'][i]['name']}-*.png") if not new_screens: - ds = multiprocessing.Process(target=prep.dvd_screenshots, args=(meta, i, multi_screens)) + ds = multiprocessing.Process(target=prep.dvd_screenshots, args=(meta, i, multi_screens, True)) ds.start() while ds.is_alive() is True: await asyncio.sleep(1)