]> git.lizzy.rs Git - nhentai.git/blob - nhentai/cmdline.py
move ComicInfo.xml behind the --comic-info flag
[nhentai.git] / nhentai / cmdline.py
1 # coding: utf-8
2 from __future__ import print_function
3 import os
4 import sys
5 from optparse import OptionParser
6 try:
7     from itertools import ifilter as filter
8 except ImportError:
9     pass
10
11 import nhentai.constant as constant
12 from nhentai import __version__
13 from nhentai.utils import urlparse, generate_html, generate_main_html, DB
14 from nhentai.logger import logger
15
16 try:
17     if sys.version_info < (3, 0, 0):
18         import codecs
19         import locale
20         sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
21         sys.stderr = codecs.getwriter(locale.getpreferredencoding())(sys.stderr)
22
23 except NameError:
24     # python3
25     pass
26
27
28 def banner():
29     logger.info(u'''nHentai ver %s: あなたも変態。 いいね?
30        _   _            _        _
31  _ __ | | | | ___ _ __ | |_ __ _(_)
32 | '_ \| |_| |/ _ \ '_ \| __/ _` | |
33 | | | |  _  |  __/ | | | || (_| | |
34 |_| |_|_| |_|\___|_| |_|\__\__,_|_|
35 ''' % __version__)
36
37
38 def cmd_parser():
39     parser = OptionParser('\n  nhentai --search [keyword] --download'
40                           '\n  NHENTAI=http://h.loli.club nhentai --id [ID ...]'
41                           '\n  nhentai --file [filename]'
42                           '\n\nEnvironment Variable:\n'
43                           '  NHENTAI                 nhentai mirror url')
44     # operation options
45     parser.add_option('--download', '-D', dest='is_download', action='store_true',
46                       help='download doujinshi (for search results)')
47     parser.add_option('--show', '-S', dest='is_show', action='store_true', help='just show the doujinshi information')
48
49     # doujinshi options
50     parser.add_option('--id', type='string', dest='id', action='store', help='doujinshi ids set, e.g. 1,2,3')
51     parser.add_option('--search', '-s', type='string', dest='keyword', action='store',
52                       help='search doujinshi by keyword')
53     parser.add_option('--tag', type='string', dest='tag', action='store', help='download doujinshi by tag')
54     parser.add_option('--artist', type='string', dest='artist', action='store', help='download doujinshi by artist')
55     parser.add_option('--character', type='string', dest='character', action='store',
56                       help='download doujinshi by character')
57     parser.add_option('--parody', type='string', dest='parody', action='store', help='download doujinshi by parody')
58     parser.add_option('--group', type='string', dest='group', action='store', help='download doujinshi by group')
59     parser.add_option('--language', type='string', dest='language', action='store',
60                       help='download doujinshi by language')
61     parser.add_option('--favorites', '-F', action='store_true', dest='favorites',
62                       help='list or download your favorites.')
63
64     # page options
65     parser.add_option('--page', type='int', dest='page', action='store', default=1,
66                       help='page number of search results')
67     parser.add_option('--max-page', type='int', dest='max_page', action='store', default=1,
68                       help='The max page when recursive download tagged doujinshi')
69     parser.add_option('--page-range', type='string', dest='page_range', action='store',
70                       help='page range of favorites.  e.g. 1,2-5,14')
71     parser.add_option('--sorting', dest='sorting', action='store', default='date',
72                       help='sorting of doujinshi (date / popular)', choices=['date', 'popular'])
73
74     # download options
75     parser.add_option('--output', '-o', type='string', dest='output_dir', action='store', default='',
76                       help='output dir')
77     parser.add_option('--threads', '-t', type='int', dest='threads', action='store', default=5,
78                       help='thread count for downloading doujinshi')
79     parser.add_option('--timeout', '-T', type='int', dest='timeout', action='store', default=30,
80                       help='timeout for downloading doujinshi')
81     parser.add_option('--delay', '-d', type='int', dest='delay', action='store', default=0,
82                       help='slow down between downloading every doujinshi')
83     parser.add_option('--proxy', '-p', type='string', dest='proxy', action='store', default='',
84                       help='store a proxy, for example: -p \'http://127.0.0.1:1080\'')
85     parser.add_option('--file',  '-f', type='string', dest='file', action='store', help='read gallery IDs from file.')
86     parser.add_option('--format', type='string', dest='name_format', action='store',
87                       help='format the saved folder name', default='[%i][%a][%t]')
88
89     # generate options
90     parser.add_option('--html', dest='html_viewer', action='store_true',
91                       help='generate a html viewer at current directory')
92     parser.add_option('--no-html', dest='is_nohtml', action='store_true',
93                       help='don\'t generate HTML after downloading')
94     parser.add_option('--gen-main', dest='main_viewer', action='store_true',
95                       help='generate a main viewer contain all the doujin in the folder')
96     parser.add_option('--cbz', '-C', dest='is_cbz', action='store_true',
97                       help='generate Comic Book CBZ File')
98     parser.add_option('--comic-info', dest='write_comic_info', action='store_true',
99                       help='when generating Comic Book CBZ File, also write ComicInfo.xml')
100     parser.add_option('--rm-origin-dir', dest='rm_origin_dir', action='store_true', default=False,
101                       help='remove downloaded doujinshi dir when generated CBZ file.')
102
103     # nhentai options
104     parser.add_option('--cookie', type='str', dest='cookie', action='store',
105                       help='set cookie of nhentai to bypass Google recaptcha')
106     parser.add_option('--save-download-history', dest='is_save_download_history', action='store_true',
107                       default=False, help='save downloaded doujinshis, whose will be skipped if you re-download them')
108     parser.add_option('--clean-download-history', action='store_true', default=False, dest='clean_download_history',
109                       help='clean download history')
110
111     try:
112         sys.argv = [unicode(i.decode(sys.stdin.encoding)) for i in sys.argv]
113         print()
114     except (NameError, TypeError):
115         pass
116     except UnicodeDecodeError:
117         exit(0)
118
119     args, _ = parser.parse_args(sys.argv[1:])
120
121     if args.html_viewer:
122         generate_html()
123         exit(0)
124
125     if args.main_viewer and not args.id and not args.keyword and \
126             not args.tag and not args.artist and not args.character and \
127             not args.parody and not args.group and not args.language and not args.favorites:
128         generate_main_html()
129         exit(0)
130
131     if args.clean_download_history:
132         with DB() as db:
133             db.clean_all()
134
135         logger.info('Download history cleaned.')
136         exit(0)
137
138     if os.path.exists(constant.NHENTAI_COOKIE):
139         with open(constant.NHENTAI_COOKIE, 'r') as f:
140             constant.COOKIE = f.read()
141
142     if args.cookie:
143         try:
144             if not os.path.exists(constant.NHENTAI_HOME):
145                 os.mkdir(constant.NHENTAI_HOME)
146
147             with open(constant.NHENTAI_COOKIE, 'w') as f:
148                 f.write(args.cookie)
149         except Exception as e:
150             logger.error('Cannot create NHENTAI_HOME: {}'.format(str(e)))
151             exit(1)
152
153         logger.info('Cookie saved.')
154         exit(0)
155
156     if os.path.exists(constant.NHENTAI_PROXY):
157         with open(constant.NHENTAI_PROXY, 'r') as f:
158             link = f.read()
159             constant.PROXY = {'http': link, 'https': link}
160
161     if args.proxy:
162         try:
163             if not os.path.exists(constant.NHENTAI_HOME):
164                 os.mkdir(constant.NHENTAI_HOME)
165
166             proxy_url = urlparse(args.proxy)
167             if proxy_url.scheme not in ('http', 'https'):
168                 logger.error('Invalid protocol \'{0}\' of proxy, ignored'.format(proxy_url.scheme))
169             else:
170                 with open(constant.NHENTAI_PROXY, 'w') as f:
171                     f.write(args.proxy)
172
173         except Exception as e:
174             logger.error('Cannot create NHENTAI_HOME: {}'.format(str(e)))
175             exit(1)
176
177         logger.info('Proxy \'{0}\' saved.'.format(args.proxy))
178         exit(0)
179
180     if args.favorites:
181         if not constant.COOKIE:
182             logger.warning('Cookie has not been set, please use `nhentai --cookie \'COOKIE\'` to set it.')
183             exit(1)
184
185     if args.id:
186         _ = [i.strip() for i in args.id.split(',')]
187         args.id = set(int(i) for i in _ if i.isdigit())
188
189     if args.file:
190         with open(args.file, 'r') as f:
191             _ = [i.strip() for i in f.readlines()]
192             args.id = set(int(i) for i in _ if i.isdigit())
193
194     if (args.is_download or args.is_show) and not args.id and not args.keyword and \
195             not args.tag and not args.artist and not args.character and \
196             not args.parody and not args.group and not args.language and not args.favorites:
197         logger.critical('Doujinshi id(s) are required for downloading')
198         parser.print_help()
199         exit(1)
200
201     if not args.keyword and not args.id and not args.tag and not args.artist and \
202             not args.character and not args.parody and not args.group and not args.language and not args.favorites:
203         parser.print_help()
204         exit(1)
205
206     if args.threads <= 0:
207         args.threads = 1
208
209     elif args.threads > 15:
210         logger.critical('Maximum number of used threads is 15')
211         exit(1)
212
213     return args