diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5946f1b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,56 @@ +aiofiles==24.1.0 +aiohappyeyeballs==2.6.1 +aiohttp==3.11.13 +aiosignal==1.3.2 +annotated-types==0.7.0 +anyio==4.8.0 +attrs==25.3.0 +beautifulsoup4==4.13.3 +bidict==0.23.1 +certifi==2025.1.31 +chardet==5.2.0 +charset-normalizer==3.4.1 +click==8.1.8 +docutils==0.21.2 +fastapi==0.115.11 +frozenlist==1.5.0 +h11==0.14.0 +httpcore==1.0.7 +httptools==0.6.4 +httpx==0.28.1 +idna==3.10 +ifaddr==0.2.0 +iso8601==1.1.0 +itsdangerous==2.2.0 +Jinja2==3.1.6 +markdown2==2.5.3 +MarkupSafe==3.0.2 +multidict==6.1.0 +nhentai==0.5.25 +nicegui==2.12.1 +orjson==3.10.15 +propcache==0.3.0 +pscript==0.7.7 +pydantic==2.10.6 +pydantic_core==2.27.2 +Pygments==2.19.1 +python-dotenv==1.0.1 +python-engineio==4.11.2 +python-multipart==0.0.20 +python-socketio==5.12.1 +PyYAML==6.0.2 +requests==2.32.3 +simple-websocket==1.1.0 +sniffio==1.3.1 +soupsieve==2.6 +starlette==0.46.1 +tabulate==0.9.0 +typing_extensions==4.12.2 +urllib3==1.26.20 +uvicorn==0.34.0 +uvloop==0.21.0 +vbuild==0.8.2 +watchfiles==1.0.4 +websockets==15.0.1 +wsproto==1.2.0 +yarl==1.18.3 diff --git a/src/main.py b/src/main.py index 4c13c2c..4ec3327 100644 --- a/src/main.py +++ b/src/main.py @@ -9,12 +9,11 @@ ui.dark_mode().enable() # Configuration DOWNLOAD_DIR = os.path.expanduser("~/Downloads/doujinshi") -DOCKER_IMAGE = "ricterz/nhentai" # Official Docker image from DockerHub OUTPUT_FORMAT = "[%i]%s" # Default format for folder naming COOKIE = "" # For bypassing Cloudflare captcha USER_AGENT = "" # For bypassing Cloudflare captcha -HTML_VIEWER = True # Generate HTML viewer -GENERATE_CBZ = False # Generate Comic Book Archive +HTML_VIEWER = False # Generate HTML viewer +GENERATE_CBZ = True # Generate Comic Book Archive GENERATE_PDF = False # Generate PDF file THREAD_COUNT = 5 # Thread count for downloading TIMEOUT = 30 # Timeout in seconds @@ -48,15 +47,10 @@ def add_nhentai_id(): on_click=lambda: start_download(id_value, status), color='primary').classes('ml-2').props('size=sm') - complete_btn = ui.button('Mark Complete', - on_click=lambda: update_status(status, id_value, True), - color='green').classes('ml-2').props('size=sm') - def update_status(status_icon, id_value, success=True): if success: status_icon.name = 'check_circle' status_icon.classes('text-green-500', remove='text-yellow-500 text-red-500 text-blue-500') - ui.notify(f'ID {id_value} marked as complete', color='positive') else: status_icon.name = 'error' status_icon.classes('text-red-500', remove='text-yellow-500 text-green-500 text-blue-500') @@ -64,23 +58,30 @@ def update_status(status_icon, id_value, success=True): def download_doujinshi(id_value, status_icon): # This function runs in a background thread + global download_statuses + try: + # Try to check if nhentai CLI is installed + try: + subprocess.run(["nhentai", "--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) + except (subprocess.SubprocessError, FileNotFoundError): + download_statuses[id_value] = { + 'status': 'error', + 'message': 'nhentai CLI tool is not installed' + } + return + # Create download directory if it doesn't exist os.makedirs(DOWNLOAD_DIR, exist_ok=True) - # Build Docker command with all options - cmd = [ - "docker", "run", "--rm", - "-v", f"{DOWNLOAD_DIR}:/output", - "-v", f"{os.path.expanduser('~/.nhentai')}:/root/.nhentai", - DOCKER_IMAGE - ] + # Build command with all options + cmd = ["nhentai"] # Add the ID cmd.extend(["--id", str(id_value)]) # Add output directory - cmd.extend(["--output", "/output"]) + cmd.extend(["--output", DOWNLOAD_DIR]) # Add format option cmd.extend(["--format", OUTPUT_FORMAT]) @@ -148,7 +149,6 @@ def download_doujinshi(id_value, status_icon): stdout, stderr = process.communicate() # Use the global dict to track status - global download_statuses if process.returncode == 0: # Success download_statuses[id_value] = { @@ -217,12 +217,11 @@ def show_settings(): with ui.dialog() as dialog, ui.card().classes('w-96'): ui.label('Download Settings').classes('text-xl font-bold') - global DOWNLOAD_DIR, DOCKER_IMAGE, OUTPUT_FORMAT, COOKIE, USER_AGENT, HTML_VIEWER, GENERATE_CBZ, GENERATE_PDF, THREAD_COUNT, TIMEOUT, RETRY_COUNT + global DOWNLOAD_DIR, OUTPUT_FORMAT, COOKIE, USER_AGENT, HTML_VIEWER, GENERATE_CBZ, GENERATE_PDF, THREAD_COUNT, TIMEOUT, RETRY_COUNT # Basic Settings ui.label('Basic Settings').classes('text-lg font-semibold mt-4') download_dir_input = ui.input('Download Directory', value=DOWNLOAD_DIR).classes('w-full') - docker_image_input = ui.input('Docker Image', value=DOCKER_IMAGE).classes('w-full') output_format_input = ui.input('Output Format', value=OUTPUT_FORMAT, placeholder='e.g. [%i]%s').classes('w-full') ui.label('Supported: %i (ID), %s (subtitle), %t (title), %a (authors), %g (groups), %p (pretty name)').classes('text-xs text-gray-500') @@ -250,7 +249,6 @@ def show_settings(): ui.button('Cancel', on_click=dialog.close).props('outline') ui.button('Save', on_click=lambda: save_settings( download_dir_input.value, - docker_image_input.value, output_format_input.value, cookie_input.value, useragent_input.value, @@ -264,12 +262,11 @@ def show_settings(): )) dialog.open() -def save_settings(download_dir, docker_image, output_format, cookie, useragent, +def save_settings(download_dir, output_format, cookie, useragent, html_viewer, generate_cbz, generate_pdf, thread_count, timeout, retry_count, dialog): - global DOWNLOAD_DIR, DOCKER_IMAGE, OUTPUT_FORMAT, COOKIE, USER_AGENT, HTML_VIEWER, GENERATE_CBZ, GENERATE_PDF, THREAD_COUNT, TIMEOUT, RETRY_COUNT + global DOWNLOAD_DIR, OUTPUT_FORMAT, COOKIE, USER_AGENT, HTML_VIEWER, GENERATE_CBZ, GENERATE_PDF, THREAD_COUNT, TIMEOUT, RETRY_COUNT DOWNLOAD_DIR = download_dir - DOCKER_IMAGE = docker_image OUTPUT_FORMAT = output_format COOKIE = cookie USER_AGENT = useragent @@ -304,7 +301,7 @@ with history_container: # Add footer with help info with ui.footer().classes('bg-gray-100 dark:bg-gray-800 text-sm'): - ui.label('Using ricterz/nhentai Docker image. Need help? Check the GitHub page:') + ui.label('Using nhentai CLI tool. Need help? Check the GitHub page:') ui.link('https://github.com/RicterZ/nhentai', 'https://github.com/RicterZ/nhentai').classes('ml-1') ui.run()