diff --git a/nhentai/__init__.py b/nhentai/__init__.py index 83be43f..8f1b7de 100644 --- a/nhentai/__init__.py +++ b/nhentai/__init__.py @@ -1,3 +1,3 @@ -__version__ = '0.4.18' +__version__ = '0.5.0' __author__ = 'RicterZ' __email__ = 'ricterzheng@gmail.com' diff --git a/nhentai/cmdline.py b/nhentai/cmdline.py index c7e61e7..744b2b1 100644 --- a/nhentai/cmdline.py +++ b/nhentai/cmdline.py @@ -17,7 +17,7 @@ from nhentai.logger import logger def banner(): - logger.debug(u'nHentai ver %s: あなたも変態。 いいね?' % __version__) + logger.debug(f'nHentai ver {__version__}: あなたも変態。 いいね?') def load_config(): @@ -40,11 +40,27 @@ def write_config(): f.write(json.dumps(constant.CONFIG)) +def callback(option, opt_str, value, parser): + if option == '--id': + pass + value = [] + + for arg in parser.rargs: + if arg.isdigit(): + value.append(int(arg)) + elif arg.startswith('-'): + break + else: + logger.warning(f'Ignore invalid id {arg}') + + setattr(parser.values, option.dest, value) + + def cmd_parser(): load_config() parser = OptionParser('\n nhentai --search [keyword] --download' - '\n NHENTAI=http://h.loli.club nhentai --id [ID ...]' + '\n NHENTAI=https://nhentai-mirror-url/ nhentai --id [ID ...]' '\n nhentai --file [filename]' '\n\nEnvironment Variable:\n' ' NHENTAI nhentai mirror url') @@ -54,7 +70,8 @@ def cmd_parser(): parser.add_option('--show', '-S', dest='is_show', action='store_true', help='just show the doujinshi information') # doujinshi options - parser.add_option('--id', type='string', dest='id', action='store', help='doujinshi ids set, e.g. 1,2,3') + parser.add_option('--id', dest='id', action='callback', callback=callback, + help='doujinshi ids set, e.g. 167680 167681 167682') parser.add_option('--search', '-s', type='string', dest='keyword', action='store', help='search doujinshi by keyword') parser.add_option('--favorites', '-F', action='store_true', dest='favorites', @@ -79,7 +96,7 @@ def cmd_parser(): parser.add_option('--delay', '-d', type='int', dest='delay', action='store', default=0, help='slow down between downloading every doujinshi') parser.add_option('--proxy', type='string', dest='proxy', action='store', - help='store a proxy, for example: -p \'http://127.0.0.1:1080\'') + help='store a proxy, for example: -p "http://127.0.0.1:1080"') parser.add_option('--file', '-f', type='string', dest='file', action='store', help='read gallery IDs from file.') parser.add_option('--format', type='string', dest='name_format', action='store', help='format the saved folder name', default='[%i][%a][%t]') @@ -121,13 +138,6 @@ def cmd_parser(): parser.add_option('--legacy', dest='legacy', action='store_true', default=False, help='use legacy searching method') - try: - sys.argv = [unicode(i.decode(sys.stdin.encoding)) for i in sys.argv] - except (NameError, TypeError): - pass - except UnicodeDecodeError: - exit(0) - args, _ = parser.parse_args(sys.argv[1:]) if args.html_viewer: @@ -159,21 +169,22 @@ def cmd_parser(): elif args.language is not None: constant.CONFIG['language'] = args.language write_config() - logger.info('Default language now set to \'{0}\''.format(args.language)) + logger.info(f'Default language now set to "{args.language}"') exit(0) # TODO: search without language if args.proxy is not None: proxy_url = urlparse(args.proxy) - if not args.proxy == '' and proxy_url.scheme not in ('http', 'https', 'socks5', 'socks5h', 'socks4', 'socks4a'): - logger.error('Invalid protocol \'{0}\' of proxy, ignored'.format(proxy_url.scheme)) + if not args.proxy == '' and proxy_url.scheme not in ('http', 'https', 'socks5', 'socks5h', + 'socks4', 'socks4a'): + logger.error(f'Invalid protocol "{proxy_url.scheme}" of proxy, ignored') exit(0) else: constant.CONFIG['proxy'] = { 'http': args.proxy, 'https': args.proxy, } - logger.info('Proxy now set to \'{0}\'.'.format(args.proxy)) + logger.info(f'Proxy now set to "{args.proxy}"') write_config() exit(0) @@ -182,8 +193,8 @@ def cmd_parser(): args.viewer_template = 'default' if not os.path.exists(os.path.join(os.path.dirname(__file__), - 'viewer/{}/index.html'.format(args.viewer_template))): - logger.error('Template \'{}\' does not exists'.format(args.viewer_template)) + f'viewer/{args.viewer_template}/index.html')): + logger.error(f'Template "{args.viewer_template}" does not exists') exit(1) else: constant.CONFIG['template'] = args.viewer_template @@ -196,10 +207,6 @@ def cmd_parser(): logger.warning('Cookie has not been set, please use `nhentai --cookie \'COOKIE\'` to set it.') exit(1) - if args.id: - _ = [i.strip() for i in args.id.split(',')] - args.id = set(int(i) for i in _ if i.isdigit()) - if args.file: with open(args.file, 'r') as f: _ = [i.strip() for i in f.readlines()] diff --git a/nhentai/utils.py b/nhentai/utils.py index f90f42f..452c708 100644 --- a/nhentai/utils.py +++ b/nhentai/utils.py @@ -36,11 +36,11 @@ def check_cookie(): logger.error('Blocked by Cloudflare captcha, please set your cookie and useragent') exit(-1) - username = re.findall('"/users/\d+/(.*?)"', response.text) + username = re.findall('"/users/[0-9]+/(.*?)"', response.text) if not username: logger.warning('Cannot get your username, please check your cookie or use `nhentai --cookie` to set your cookie') else: - logger.info('Login successfully! Your username: {}'.format(username[0])) + logger.info(f'Login successfully! Your username: {username[0]}') class _Singleton(type): @@ -82,7 +82,7 @@ def generate_html(output_dir='.', doujinshi_obj=None, template='default'): doujinshi_dir = '.' if not os.path.exists(doujinshi_dir): - logger.warning('Path \'{0}\' does not exist, creating.'.format(doujinshi_dir)) + logger.warning(f'Path "{doujinshi_dir}" does not exist, creating.') try: os.makedirs(doujinshi_dir) except EnvironmentError as e: @@ -94,9 +94,8 @@ def generate_html(output_dir='.', doujinshi_obj=None, template='default'): for image in file_list: if not os.path.splitext(image)[1] in ('.jpg', '.png'): continue + image_html += f'\n' - image_html += '\n' \ - .format(image) html = readfile('viewer/{}/index.html'.format(template)) css = readfile('viewer/{}/styles.css'.format(template)) js = readfile('viewer/{}/scripts.js'.format(template)) @@ -118,14 +117,14 @@ def generate_html(output_dir='.', doujinshi_obj=None, template='default'): with open(os.path.join(doujinshi_dir, 'index.html'), 'wb') as f: f.write(data.encode('utf-8')) - logger.log(15, 'HTML Viewer has been written to \'{0}\''.format(os.path.join(doujinshi_dir, 'index.html'))) + logger.log(15, f'HTML Viewer has been written to "{os.path.join(doujinshi_dir, "index.html")}"') except Exception as e: - logger.warning('Writing HTML Viewer failed ({})'.format(str(e))) + logger.warning(f'Writing HTML Viewer failed ({e})') def generate_main_html(output_dir='./'): """ - Generate a main html to show all the contain doujinshi. + Generate a main html to show all the contains doujinshi. With a link to their `index.html`. Default output folder will be the CLI path. """ @@ -154,7 +153,7 @@ def generate_main_html(output_dir='./'): files.sort() if 'index.html' in files: - logger.info('Add doujinshi \'{}\''.format(folder)) + logger.info(f'Add doujinshi "{folder}"') else: continue @@ -178,10 +177,9 @@ def generate_main_html(output_dir='./'): f.write(data.encode('utf-8')) shutil.copy(os.path.dirname(__file__) + '/viewer/logo.png', './') set_js_database() - logger.log( - 15, 'Main Viewer has been written to \'{0}main.html\''.format(output_dir)) + logger.log(15, f'Main Viewer has been written to "{output_dir}main.html"') except Exception as e: - logger.warning('Writing Main Viewer failed ({})'.format(str(e))) + logger.warning(f'Writing Main Viewer failed ({e})') def generate_cbz(output_dir='.', doujinshi_obj=None, rm_origin_dir=False, write_comic_info=True): @@ -206,7 +204,7 @@ def generate_cbz(output_dir='.', doujinshi_obj=None, rm_origin_dir=False, write_ if rm_origin_dir: shutil.rmtree(doujinshi_dir, ignore_errors=True) - logger.log(15, 'Comic Book CBZ file has been written to \'{0}\''.format(doujinshi_dir)) + logger.log(15, f'Comic Book CBZ file has been written to "{doujinshi_dir}"') def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False): @@ -218,7 +216,7 @@ def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False): doujinshi_dir = os.path.join(output_dir, doujinshi_obj.filename) pdf_filename = os.path.join( os.path.join(doujinshi_dir, '..'), - '{}.pdf'.format(doujinshi_obj.filename) + f'{doujinshi_obj.filename}.pdf' ) else: pdf_filename = './doujinshi.pdf' @@ -227,7 +225,7 @@ def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False): file_list = os.listdir(doujinshi_dir) file_list.sort() - logger.info('Writing PDF file to path: {}'.format(pdf_filename)) + logger.info(f'Writing PDF file to path: {pdf_filename}') with open(pdf_filename, 'wb') as pdf_f: full_path_list = ( [os.path.join(doujinshi_dir, image) for image in file_list] @@ -237,19 +235,12 @@ def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False): if rm_origin_dir: shutil.rmtree(doujinshi_dir, ignore_errors=True) - logger.log(15, 'PDF file has been written to \'{0}\''.format(doujinshi_dir)) + logger.log(15, f'PDF file has been written to "{doujinshi_dir}"') except ImportError: logger.error("Please install img2pdf package by using pip.") -def unicode_truncate(s, length, encoding='utf-8'): - """https://stackoverflow.com/questions/1809531/truncating-unicode-so-it-fits-a-maximum-size-when-encoded-for-wire-transfer - """ - encoded = s.encode(encoding)[:length] - return encoded.decode(encoding, 'ignore') - - def format_filename(s, length=MAX_FIELD_LENGTH, _truncate_only=False): """ It used to be a whitelist approach allowed only alphabet and a part of symbols. @@ -323,7 +314,7 @@ def generate_metadata_file(output_dir, table, doujinshi_obj=None): 'LANGUAGE', 'TAGS', 'URL', 'PAGES'] for i in range(len(fields)): - f.write('{}: '.format(fields[i])) + f.write(f'{fields[i]}: ') if fields[i] in special_fields: f.write(str(table[special_fields.index(fields[i])][1])) f.write('\n') diff --git a/setup.py b/setup.py index 8218604..38690cc 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,4 @@ # coding: utf-8 -from __future__ import print_function, unicode_literals -import sys import codecs from setuptools import setup, find_packages from nhentai import __version__, __author__, __email__ @@ -11,9 +9,8 @@ with open('requirements.txt') as f: def long_description(): - with codecs.open('README.rst', 'rb') as readme: - if not sys.version_info < (3, 0, 0): - return readme.read().decode('utf-8') + with codecs.open('README.rst', 'r') as readme: + return readme.read() setup(