diff --git a/.travis.yml b/.travis.yml index 698dfa8..21c1028 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,3 +14,4 @@ script: - NHENTAI=https://nhentai.net nhentai --search umaru - NHENTAI=https://nhentai.net nhentai --id=152503,146134 -t 10 --output=/tmp/ - NHENTAI=https://nhentai.net nhentai -l nhentai_test:nhentai --output=/tmp/ + - NHENTAI=https://nhentai.net nhentai --tag lolicon \ No newline at end of file diff --git a/nhentai/cmdline.py b/nhentai/cmdline.py index d3453d2..51b541f 100644 --- a/nhentai/cmdline.py +++ b/nhentai/cmdline.py @@ -42,7 +42,7 @@ def cmd_parser(): parser.add_option('--search', type='string', dest='keyword', action='store', help='search doujinshi by keyword') parser.add_option('--page', type='int', dest='page', action='store', default=1, help='page number of search result') - parser.add_option('--tags', type='string', dest='tags', action='store', help='download doujinshi by tags') + parser.add_option('--tag', type='string', dest='tag', action='store', help='download doujinshi by tag') parser.add_option('--output', type='string', dest='output_dir', action='store', default='', help='output dir') parser.add_option('--threads', '-t', type='int', dest='threads', action='store', default=5, @@ -86,20 +86,17 @@ def cmd_parser(): if not args.is_download: logger.warning('YOU DO NOT SPECIFY `--download` OPTION !!!') - if args.tags: - logger.warning('`--tags` is under construction') - exit(1) - if args.id: _ = map(lambda id: id.strip(), args.id.split(',')) args.id = set(map(int, filter(lambda id_: id_.isdigit(), _))) - if (args.is_download or args.is_show) and not args.id and not args.keyword and not args.login: + if (args.is_download or args.is_show) and not args.id and not args.keyword and \ + not args.login and not args.tag: logger.critical('Doujinshi id(s) are required for downloading') parser.print_help() exit(1) - if not args.keyword and not args.id and not args.login: + if not args.keyword and not args.id and not args.login and not args.tag: parser.print_help() exit(1) diff --git a/nhentai/command.py b/nhentai/command.py index 5f08cef..b1492a6 100644 --- a/nhentai/command.py +++ b/nhentai/command.py @@ -5,7 +5,7 @@ import signal import platform from nhentai.cmdline import cmd_parser, banner -from nhentai.parser import doujinshi_parser, search_parser, print_doujinshi, login_parser +from nhentai.parser import doujinshi_parser, search_parser, print_doujinshi, login_parser, tag_guessing, tag_parser from nhentai.doujinshi import Doujinshi from nhentai.downloader import Downloader from nhentai.logger import logger @@ -27,13 +27,19 @@ def main(): for doujinshi_info in login_parser(username=username, password=password): doujinshi_list.append(Doujinshi(**doujinshi_info)) + if options.tag: + tag_id = tag_guessing(options.tag) + if tag_id: + doujinshis = tag_parser(tag_id) + print_doujinshi(doujinshis) + if options.is_download: + doujinshi_ids = map(lambda d: d['id'], doujinshis) + if options.keyword: doujinshis = search_parser(options.keyword, options.page) print_doujinshi(doujinshis) if options.is_download: doujinshi_ids = map(lambda d: d['id'], doujinshis) - else: - doujinshi_ids = options.id if doujinshi_ids: for id_ in doujinshi_ids: diff --git a/nhentai/constant.py b/nhentai/constant.py index 55e2fa4..efd5022 100644 --- a/nhentai/constant.py +++ b/nhentai/constant.py @@ -7,6 +7,8 @@ BASE_URL = os.getenv('NHENTAI', 'https://nhentai.net') DETAIL_URL = '%s/api/gallery' % BASE_URL SEARCH_URL = '%s/api/galleries/search' % BASE_URL +TAG_URL = '%s/tag' % BASE_URL +TAG_API_URL = '%s/api/galleries/tagged' % BASE_URL LOGIN_URL = '%s/login/' % BASE_URL FAV_URL = '%s/favorites/' % BASE_URL diff --git a/nhentai/parser.py b/nhentai/parser.py index bef5730..1517e72 100644 --- a/nhentai/parser.py +++ b/nhentai/parser.py @@ -110,11 +110,18 @@ def doujinshi_parser(id_): doujinshi['pages'] = len(response['images']['pages']) # gain information of the doujinshi - needed_fields = ['character', 'artist', 'language'] + needed_fields = ['character', 'artist', 'language', 'tag'] for tag in response['tags']: tag_type = tag['type'] if tag_type in needed_fields: - if tag_type not in doujinshi: + if tag_type == 'tag': + if tag_type not in doujinshi: + doujinshi[tag_type] = {} + + tag['name'] = tag['name'].replace(' ', '-') + tag['name'] = tag['name'].lower() + doujinshi[tag_type][tag['name']] = tag['id'] + elif tag_type not in doujinshi: doujinshi[tag_type] = tag['name'] else: doujinshi[tag_type] += tag['name'] @@ -154,5 +161,48 @@ def print_doujinshi(doujinshi_list): tabulate(tabular_data=doujinshi_list, headers=headers, tablefmt='rst')) +def tag_parser(tag_id): + logger.info('Get doujinshi of tag id: {0}'.format(tag_id)) + result = [] + response = request('get', url=constant.TAG_API_URL, params={'sort': 'popular', 'tag_id': tag_id}).json() + + for row in response['result']: + title = row['title']['english'] + title = title[:85] + '..' if len(title) > 85 else title + result.append({'id': row['id'], 'title': title}) + + if not result: + logger.warn('Not found anything of tag id {}'.format(tag_id)) + + return result + + +def tag_guessing(tag_name): + tag_name = tag_name.lower() + tag_name = tag_name.replace(' ', '-') + logger.info('Trying to get tag_id of tag \'{0}\''.format(tag_name)) + response = request('get', url='%s/%s' % (constant.TAG_URL, tag_name)).content + html = BeautifulSoup(response, 'html.parser') + first_item = html.find('div', attrs={'class': 'gallery'}) + if not first_item: + logger.error('Cannot find doujinshi id of tag \'{0}\''.format(tag_name)) + return + + doujinshi_id = re.findall('(\d+)', first_item.a.attrs['href']) + if not doujinshi_id: + logger.error('Cannot find doujinshi id of tag \'{0}\''.format(tag_name)) + return + + ret = doujinshi_parser(doujinshi_id[0]) + if 'tag' in ret and tag_name in ret['tag']: + tag_id = ret['tag'][tag_name] + logger.info('Tag id of tag \'{0}\' is {1}'.format(tag_name, tag_id)) + else: + logger.error('Cannot find doujinshi id of tag \'{0}\''.format(tag_name)) + return + + return tag_id + + if __name__ == '__main__': print(doujinshi_parser("32271"))