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(