from tabulate import tabulate
import nhentai.constant as constant
+from nhentai.utils import request
from nhentai.logger import logger
-session = requests.Session()
-session.headers.update({
- 'Referer': constant.LOGIN_URL,
- 'User-Agent': 'nhentai command line client (https://github.com/RicterZ/nhentai)',
-})
-
-
-def request(method, url, **kwargs):
- global session
- if not hasattr(session, method):
- raise AttributeError('\'requests.Session\' object has no attribute \'{0}\''.format(method))
-
- session.headers.update({'Cookie': constant.COOKIE})
- return getattr(session, method)(url, proxies=constant.PROXY, verify=False, **kwargs)
-
-
def _get_csrf_token(content):
html = BeautifulSoup(content, 'html.parser')
csrf_token_elem = html.find('input', attrs={'name': 'csrfmiddlewaretoken'})
exit(2)
+def _get_title_and_id(response):
+ result = []
+ html = BeautifulSoup(response, 'html.parser')
+ doujinshi_search_result = html.find_all('div', attrs={'class': 'gallery'})
+ for doujinshi in doujinshi_search_result:
+ doujinshi_container = doujinshi.find('div', attrs={'class': 'caption'})
+ title = doujinshi_container.text.strip()
+ title = title if len(title) < 85 else title[:82] + '...'
+ id_ = re.search('/g/(\d+)/', doujinshi.a['href']).group(1)
+ result.append({'id': id_, 'title': title})
+
+ return result
+
+
def favorites_parser():
+ result = []
html = BeautifulSoup(request('get', constant.FAV_URL).content, 'html.parser')
count = html.find('span', attrs={'class': 'count'})
if not count:
if os.getenv('DEBUG'):
pages = 1
- ret = []
- doujinshi_id = re.compile('data-id="([\d]+)"')
-
for page in range(1, pages + 1):
try:
logger.info('Getting doujinshi ids of page %d' % page)
- resp = request('get', constant.FAV_URL + '?page=%d' % page).text
- ids = doujinshi_id.findall(resp)
- ret.extend(ids)
+ resp = request('get', constant.FAV_URL + '?page=%d' % page).content
+ result.extend(_get_title_and_id(resp))
except Exception as e:
logger.error('Error: %s, continue', str(e))
- return ret
+ return result
def doujinshi_parser(id_):
def search_parser(keyword, page):
logger.debug('Searching doujinshis of keyword {0}'.format(keyword))
- result = []
try:
response = request('get', url=constant.SEARCH_URL, params={'q': keyword, 'page': page}).content
except requests.ConnectionError as e:
logger.warn('If you are in China, please configure the proxy to fu*k GFW.')
raise SystemExit
- html = BeautifulSoup(response, 'html.parser')
- doujinshi_search_result = html.find_all('div', attrs={'class': 'gallery'})
- for doujinshi in doujinshi_search_result:
- doujinshi_container = doujinshi.find('div', attrs={'class': 'caption'})
- title = doujinshi_container.text.strip()
- title = title if len(title) < 85 else title[:82] + '...'
- id_ = re.search('/g/(\d+)/', doujinshi.a['href']).group(1)
- result.append({'id': id_, 'title': title})
+ result = _get_title_and_id(response)
if not result:
logger.warn('Not found anything of keyword {}'.format(keyword))
return result
-def __api_suspended_doujinshi_parser(id_):
- if not isinstance(id_, (int,)) and (isinstance(id_, (str,)) and not id_.isdigit()):
- raise Exception('Doujinshi id({0}) is not valid'.format(id_))
+def print_doujinshi(doujinshi_list):
+ if not doujinshi_list:
+ return
+ doujinshi_list = [(i['id'], i['title']) for i in doujinshi_list]
+ headers = ['id', 'doujinshi']
+ logger.info('Search Result\n' +
+ tabulate(tabular_data=doujinshi_list, headers=headers, tablefmt='rst'))
- id_ = int(id_)
- logger.log(15, 'Fetching information of doujinshi id {0}'.format(id_))
- doujinshi = dict()
- doujinshi['id'] = id_
- url = '{0}/{1}'.format(constant.DETAIL_URL, id_)
- i = 0
- while 5 > i:
- try:
- response = request('get', url).json()
- except Exception as e:
- i += 1
- if not i < 5:
- logger.critical(str(e))
- exit(1)
- continue
- break
- doujinshi['name'] = response['title']['english']
- doujinshi['subtitle'] = response['title']['japanese']
- doujinshi['img_id'] = response['media_id']
- doujinshi['ext'] = ''.join(map(lambda s: s['t'], response['images']['pages']))
- doujinshi['pages'] = len(response['images']['pages'])
+def tag_parser(tag_name, max_page=1):
+ result = []
+ tag_name = tag_name.lower()
+ tag_name = tag_name.replace(' ', '-')
- # gain information of the doujinshi
- needed_fields = ['character', 'artist', 'language', 'tag']
- for tag in response['tags']:
- tag_type = tag['type']
- if tag_type in needed_fields:
- if tag_type == 'tag':
- if tag_type not in doujinshi:
- doujinshi[tag_type] = {}
+ for p in range(1, max_page + 1):
+ logger.debug('Fetching page {0} for doujinshi with tag \'{1}\''.format(p, tag_name))
+ response = request('get', url='%s/%s?page=%d' % (constant.TAG_URL, tag_name, p)).content
- 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']
+ result = _get_title_and_id(response)
+ if not result:
+ logger.error('Cannot find doujinshi id of tag \'{0}\''.format(tag_name))
+ return
- return doujinshi
+ if not result:
+ logger.warn('No results for tag \'{}\''.format(tag_name))
+
+ return result
def __api_suspended_search_parser(keyword, page):
return result
-def print_doujinshi(doujinshi_list):
- if not doujinshi_list:
- return
- doujinshi_list = [(i['id'], i['title']) for i in doujinshi_list]
- headers = ['id', 'doujinshi']
- logger.info('Search Result\n' +
- tabulate(tabular_data=doujinshi_list, headers=headers, tablefmt='rst'))
-
-
def __api_suspended_tag_parser(tag_id, max_page=1):
logger.info('Searching for doujinshi with tag id {0}'.format(tag_id))
result = []
return result
-def tag_parser(tag_name, max_page=1):
- result = []
- tag_name = tag_name.lower()
- tag_name = tag_name.replace(' ', '-')
+def __api_suspended_doujinshi_parser(id_):
+ if not isinstance(id_, (int,)) and (isinstance(id_, (str,)) and not id_.isdigit()):
+ raise Exception('Doujinshi id({0}) is not valid'.format(id_))
- for p in range(1, max_page + 1):
- logger.debug('Fetching page {0} for doujinshi with tag \'{1}\''.format(p, tag_name))
- response = request('get', url='%s/%s?page=%d' % (constant.TAG_URL, tag_name, p)).content
+ id_ = int(id_)
+ logger.log(15, 'Fetching information of doujinshi id {0}'.format(id_))
+ doujinshi = dict()
+ doujinshi['id'] = id_
+ url = '{0}/{1}'.format(constant.DETAIL_URL, id_)
+ i = 0
+ while 5 > i:
+ try:
+ response = request('get', url).json()
+ except Exception as e:
+ i += 1
+ if not i < 5:
+ logger.critical(str(e))
+ exit(1)
+ continue
+ break
- html = BeautifulSoup(response, 'html.parser')
- doujinshi_items = html.find_all('div', attrs={'class': 'gallery'})
- if not doujinshi_items:
- logger.error('Cannot find doujinshi id of tag \'{0}\''.format(tag_name))
- return
+ doujinshi['name'] = response['title']['english']
+ doujinshi['subtitle'] = response['title']['japanese']
+ doujinshi['img_id'] = response['media_id']
+ doujinshi['ext'] = ''.join(map(lambda s: s['t'], response['images']['pages']))
+ doujinshi['pages'] = len(response['images']['pages'])
- for i in doujinshi_items:
- doujinshi_id = i.a.attrs['href'].strip('/g')
- doujinshi_title = i.a.text.strip()
- doujinshi_title = doujinshi_title if len(doujinshi_title) < 85 else doujinshi_title[:82] + '...'
- result.append({'title': doujinshi_title, 'id': doujinshi_id})
+ # gain information of the doujinshi
+ needed_fields = ['character', 'artist', 'language', 'tag']
+ for tag in response['tags']:
+ tag_type = tag['type']
+ if tag_type in needed_fields:
+ if tag_type == 'tag':
+ if tag_type not in doujinshi:
+ doujinshi[tag_type] = {}
- if not result:
- logger.warn('No results for tag \'{}\''.format(tag_name))
+ 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']
- return result
+ return doujinshi
if __name__ == '__main__':