mirror of
https://github.com/RicterZ/nhentai.git
synced 2026-04-08 18:50:21 +02:00
When check_if_need_download() returns False (CBZ/PDF file already exists), skip all post-processing steps that require doujinshi_dir to be present (serializer, generate_doc, generate_html, rm_origin_dir, etc.), as the directory may have been removed by --rm-origin-dir on a previous run. However, still write to the download history DB unconditionally so that records lost due to DB corruption/reset are recovered on the next run. Fixes #429 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
203 lines
6.8 KiB
Python
203 lines
6.8 KiB
Python
# coding: utf-8
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import signal
|
|
import platform
|
|
import urllib3.exceptions
|
|
|
|
from doujinshi_dl.cmdline import cmd_parser, banner, write_config
|
|
from doujinshi_dl.core.registry import get_first_plugin
|
|
from doujinshi_dl.core import config as core_config
|
|
from doujinshi_dl.downloader import Downloader, CompressedDownloader
|
|
from doujinshi_dl.logger import logger
|
|
from doujinshi_dl.utils import (
|
|
generate_html, generate_doc, generate_main_html,
|
|
paging, signal_handler, DB, move_to_folder,
|
|
)
|
|
|
|
|
|
def main():
|
|
banner()
|
|
|
|
if sys.version_info < (3, 0, 0):
|
|
logger.error('doujinshi-dl requires Python 3.x')
|
|
sys.exit(1)
|
|
|
|
plugin = get_first_plugin()
|
|
parser = plugin.create_parser()
|
|
serializer = plugin.create_serializer()
|
|
|
|
options = cmd_parser()
|
|
|
|
# Let the plugin configure its own CONFIG and register runtime values
|
|
# (this also sets core_config 'base_url' from env or plugin default)
|
|
plugin.configure(options)
|
|
|
|
# Read common config values registered by the plugin
|
|
plugin_config = core_config.get('plugin_config', {})
|
|
base_url = core_config.get('base_url', os.getenv('DOUJINSHI_DL_URL', ''))
|
|
if not base_url:
|
|
logger.error('No target URL configured. Set DOUJINSHI_DL_URL or install a plugin that provides a default URL.')
|
|
sys.exit(1)
|
|
logger.info(f'Using mirror: {base_url}')
|
|
|
|
# CONFIG['proxy'] may have been updated after cmd_parser()
|
|
proxy = plugin_config.get('proxy', '')
|
|
if proxy:
|
|
if isinstance(proxy, dict):
|
|
proxy = proxy.get('http', '')
|
|
plugin_config['proxy'] = proxy
|
|
logger.warning(f'Update proxy config to: {proxy}')
|
|
write_config()
|
|
logger.info(f'Using proxy: {proxy}')
|
|
|
|
if not plugin_config.get('template'):
|
|
plugin_config['template'] = 'default'
|
|
|
|
template = plugin_config.get('template', 'default')
|
|
language = plugin_config.get('language', '')
|
|
logger.info(f'Using viewer template "{template}"')
|
|
|
|
# Check authentication
|
|
plugin.check_auth()
|
|
|
|
doujinshis = []
|
|
doujinshi_ids = []
|
|
|
|
page_list = paging(options.page)
|
|
|
|
if options.favorites:
|
|
if not options.is_download:
|
|
logger.warning('You do not specify --download option')
|
|
|
|
doujinshis = parser.favorites(page=page_list) if options.page else parser.favorites()
|
|
|
|
elif options.keyword:
|
|
if language:
|
|
logger.info(f'Using default language: {language}')
|
|
options.keyword += f' language:{language}'
|
|
|
|
doujinshis = parser.search(
|
|
options.keyword,
|
|
sorting=options.sorting,
|
|
page=page_list,
|
|
is_page_all=options.page_all,
|
|
)
|
|
|
|
elif options.artist:
|
|
doujinshis = parser.search(
|
|
f'artist:{options.artist}',
|
|
sorting=options.sorting,
|
|
page=page_list,
|
|
is_page_all=options.page_all,
|
|
)
|
|
|
|
elif not doujinshi_ids:
|
|
doujinshi_ids = options.id
|
|
|
|
plugin.print_results(doujinshis)
|
|
if options.is_download and doujinshis:
|
|
doujinshi_ids = [i['id'] for i in doujinshis]
|
|
|
|
if options.is_save_download_history:
|
|
with DB() as db:
|
|
data = set(map(int, db.get_all()))
|
|
|
|
doujinshi_ids = list(set(map(int, doujinshi_ids)) - set(data))
|
|
logger.info(f'New doujinshis account: {len(doujinshi_ids)}')
|
|
|
|
if options.zip:
|
|
options.is_nohtml = True
|
|
|
|
if not options.is_show:
|
|
downloader = (CompressedDownloader if options.zip else Downloader)(
|
|
path=options.output_dir,
|
|
threads=options.threads,
|
|
timeout=options.timeout,
|
|
delay=options.delay,
|
|
exit_on_fail=options.exit_on_fail,
|
|
no_filename_padding=options.no_filename_padding,
|
|
)
|
|
|
|
for doujinshi_id in doujinshi_ids:
|
|
meta = parser.fetch(str(doujinshi_id))
|
|
if not meta:
|
|
continue
|
|
|
|
doujinshi_model = plugin.create_model(meta, name_format=options.name_format)
|
|
doujinshi = doujinshi_model.doujinshi
|
|
doujinshi.downloader = downloader
|
|
|
|
need_download = doujinshi.check_if_need_download(options)
|
|
if need_download:
|
|
doujinshi.download()
|
|
else:
|
|
logger.info(
|
|
f'Skip download doujinshi because a PDF/CBZ file exists of doujinshi {doujinshi.name}'
|
|
)
|
|
|
|
doujinshi_dir = os.path.join(options.output_dir, doujinshi.filename)
|
|
|
|
# If skipped (CBZ/PDF already exists), treat as already downloaded:
|
|
# - skip all post-processing that requires doujinshi_dir to exist
|
|
# - but still write to history DB in case the record was lost
|
|
if options.is_save_download_history:
|
|
with DB() as db:
|
|
db.add_one(doujinshi.id)
|
|
|
|
if not need_download:
|
|
continue
|
|
|
|
if options.generate_metadata:
|
|
serializer.write_all(meta, doujinshi_dir)
|
|
logger.log(16, f'Metadata files have been written to "{doujinshi_dir}"')
|
|
|
|
if not options.is_nohtml:
|
|
generate_html(options.output_dir, doujinshi, template=template)
|
|
|
|
if options.is_cbz:
|
|
# Write ComicInfo.xml metadata before packaging
|
|
serializer.write_all(meta, doujinshi_dir)
|
|
generate_doc('cbz', options.output_dir, doujinshi, options.regenerate)
|
|
|
|
if options.is_pdf:
|
|
generate_doc('pdf', options.output_dir, doujinshi, options.regenerate)
|
|
|
|
if options.move_to_folder:
|
|
if options.is_cbz:
|
|
move_to_folder(options.output_dir, doujinshi, 'cbz')
|
|
if options.is_pdf:
|
|
move_to_folder(options.output_dir, doujinshi, 'pdf')
|
|
|
|
if options.rm_origin_dir:
|
|
if options.move_to_folder:
|
|
logger.critical('You specified both --move-to-folder and --rm-origin-dir options, '
|
|
'you will not get anything :(')
|
|
shutil.rmtree(os.path.join(options.output_dir, doujinshi.filename), ignore_errors=True)
|
|
|
|
if options.main_viewer:
|
|
generate_main_html(options.output_dir)
|
|
serializer.finalize(options.output_dir)
|
|
|
|
if not platform.system() == 'Windows':
|
|
logger.log(16, '🍻 All done.')
|
|
else:
|
|
logger.log(16, 'All done.')
|
|
|
|
else:
|
|
for doujinshi_id in doujinshi_ids:
|
|
meta = parser.fetch(str(doujinshi_id))
|
|
if not meta:
|
|
continue
|
|
doujinshi_model = plugin.create_model(meta, name_format=options.name_format)
|
|
doujinshi = doujinshi_model.doujinshi
|
|
doujinshi.show()
|
|
|
|
|
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|