Compare commits

...

16 Commits

Author SHA1 Message Date
d9d2a6fb91 fix bug of proxy while downloading doujinshi 2021-06-02 23:20:56 +08:00
8cd4b948e7 0.4.15 2021-05-08 15:36:49 +08:00
f884384eb3 fix bug 2021-05-08 15:36:36 +08:00
87afab46c4 Merge pull request #211 from jwfiredragon/master 2021-04-25 09:56:49 +08:00
c7b1d7e6a8 Fix broken constant import 2021-04-24 16:39:54 -07:00
ad02371158 Update constant.py 2021-04-21 15:37:13 +08:00
7c9d55e0ee Merge pull request #208 from karamori77/master
Changed write_comic_info from False to True
2021-04-21 15:30:51 +08:00
00aad774ae Fixed potential re-download
Moved forward save-history check 1 indent so it works with download by id too
Mapped all ids to int since there are cases where its a string in the API
2021-04-20 11:04:52 +08:00
373086b459 Update serializer.py
changed Language to LanguageISO for ComicInfo.xml
Language will be displayed by the LanguageISO code, it also forgoes rare language tags like rewrite and speechless
2021-04-18 21:45:15 +08:00
3a83f99771 Update constant.py 2021-04-18 21:40:47 +08:00
00627ab36a Update utils.py 2021-04-03 23:11:33 +08:00
592e163891 Update requirements.txt 2021-03-26 22:25:49 +08:00
84523475b0 Merge pull request #206 from Un1Gfn/patch-1 2021-03-25 19:01:39 +08:00
5f5461c902 Instuctions on getting csrftoken & sessionid 2021-03-25 18:57:20 +08:00
05e6ceb3cd Merge pull request #205 from Nontre12/master 2021-03-25 09:22:13 +08:00
db59426503 FIX: Use of img2lib even if it is not installed 2021-03-24 21:49:45 +01:00
8 changed files with 66 additions and 45 deletions

View File

@ -67,6 +67,15 @@ Set your nhentai cookie against captcha:
**NOTE**: The format of the cookie is `"csrftoken=TOKEN; sessionid=ID"` **NOTE**: The format of the cookie is `"csrftoken=TOKEN; sessionid=ID"`
| To get csrftoken and sessionid, first login to your nhentai account in web browser, then:
| (Chrome) |ve| |ld| More tools |ld| Developer tools |ld| Application |ld| Storage |ld| Cookies |ld| https://nhentai.net
| (Firefox) |hv| |ld| Web Developer |ld| Web Developer Tools |ld| Storage |ld| Cookies |ld| https://nhentai.net
|
.. |hv| unicode:: U+2630 .. https://www.compart.com/en/unicode/U+2630
.. |ve| unicode:: U+22EE .. https://www.compart.com/en/unicode/U+22EE
.. |ld| unicode:: U+2014 .. https://www.compart.com/en/unicode/U+2014
Download specified doujinshi: Download specified doujinshi:
.. code-block:: bash .. code-block:: bash

View File

@ -1,3 +1,3 @@
__version__ = '0.4.14' __version__ = '0.4.15'
__author__ = 'RicterZ' __author__ = 'RicterZ'
__email__ = 'ricterzheng@gmail.com' __email__ = 'ricterzheng@gmail.com'

View File

@ -69,7 +69,7 @@ def main():
with DB() as db: with DB() as db:
data = map(int, db.get_all()) data = map(int, db.get_all())
doujinshi_ids = list(set(doujinshi_ids) - set(data)) doujinshi_ids = list(set(map(int, doujinshi_ids)) - set(data))
if doujinshi_ids: if doujinshi_ids:
for i, id_ in enumerate(doujinshi_ids): for i, id_ in enumerate(doujinshi_ids):

View File

@ -29,10 +29,16 @@ NHENTAI_HOME = os.path.join(os.getenv('HOME', tempfile.gettempdir()), '.nhentai'
NHENTAI_HISTORY = os.path.join(NHENTAI_HOME, 'history.sqlite3') NHENTAI_HISTORY = os.path.join(NHENTAI_HOME, 'history.sqlite3')
NHENTAI_CONFIG_FILE = os.path.join(NHENTAI_HOME, 'config.json') NHENTAI_CONFIG_FILE = os.path.join(NHENTAI_HOME, 'config.json')
CONFIG = { CONFIG = {
'proxy': {'http': '', 'https': ''}, 'proxy': {'http': '', 'https': ''},
'cookie': '', 'cookie': '',
'language': '', 'language': '',
'template': '', 'template': '',
} }
LANGUAGEISO ={
'english' : 'en',
'chinese' : 'zh',
'japanese' : 'ja',
'translated' : 'translated'
}

View File

@ -14,6 +14,7 @@ try:
except ImportError: except ImportError:
from urlparse import urlparse from urlparse import urlparse
from nhentai import constant
from nhentai.logger import logger from nhentai.logger import logger
from nhentai.parser import request from nhentai.parser import request
from nhentai.utils import Singleton from nhentai.utils import Singleton
@ -34,7 +35,7 @@ class Downloader(Singleton):
self.timeout = timeout self.timeout = timeout
self.delay = delay self.delay = delay
def download_(self, url, folder='', filename='', retried=0): def download_(self, url, folder='', filename='', retried=0, proxy=None):
if self.delay: if self.delay:
time.sleep(self.delay) time.sleep(self.delay)
logger.info('Starting to download {0} ...'.format(url)) logger.info('Starting to download {0} ...'.format(url))
@ -51,7 +52,7 @@ class Downloader(Singleton):
i = 0 i = 0
while i < 10: while i < 10:
try: try:
response = request('get', url, stream=True, timeout=self.timeout) response = request('get', url, stream=True, timeout=self.timeout, proxies=proxy)
if response.status_code != 200: if response.status_code != 200:
raise NHentaiImageNotExistException raise NHentaiImageNotExistException
@ -77,7 +78,8 @@ class Downloader(Singleton):
except (requests.HTTPError, requests.Timeout) as e: except (requests.HTTPError, requests.Timeout) as e:
if retried < 3: if retried < 3:
logger.warning('Warning: {0}, retrying({1}) ...'.format(str(e), retried)) logger.warning('Warning: {0}, retrying({1}) ...'.format(str(e), retried))
return 0, self.download_(url=url, folder=folder, filename=filename, retried=retried+1) return 0, self.download_(url=url, folder=folder, filename=filename,
retried=retried+1, proxy=proxy)
else: else:
return 0, None return 0, None
@ -128,7 +130,7 @@ class Downloader(Singleton):
else: else:
logger.warning('Path \'{0}\' already exist.'.format(folder)) logger.warning('Path \'{0}\' already exist.'.format(folder))
queue = [(self, url, folder) for url in queue] queue = [(self, url, folder, constant.CONFIG['proxy']) for url in queue]
pool = multiprocessing.Pool(self.size, init_worker) pool = multiprocessing.Pool(self.size, init_worker)
[pool.apply_async(download_wrapper, args=item) for item in queue] [pool.apply_async(download_wrapper, args=item) for item in queue]
@ -137,9 +139,9 @@ class Downloader(Singleton):
pool.join() pool.join()
def download_wrapper(obj, url, folder=''): def download_wrapper(obj, url, folder='', proxy=None):
if sys.platform == 'darwin' or semaphore.get_value(): if sys.platform == 'darwin' or semaphore.get_value():
return Downloader.download_(obj, url=url, folder=folder) return Downloader.download_(obj, url=url, folder=folder, proxy=proxy)
else: else:
return -3, None return -3, None

View File

@ -2,7 +2,7 @@
import json import json
import os import os
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
from nhentai.constant import LANGUAGEISO
def serialize_json(doujinshi, dir): def serialize_json(doujinshi, dir):
metadata = {'title': doujinshi.name, metadata = {'title': doujinshi.name,
@ -65,7 +65,8 @@ def serialize_comicxml(doujinshi, dir):
if doujinshi.info.languages: if doujinshi.info.languages:
languages = [i.strip() for i in doujinshi.info.languages.split(',')] languages = [i.strip() for i in doujinshi.info.languages.split(',')]
xml_write_simple_tag(f, 'Translated', 'Yes' if 'translated' in languages else 'No') xml_write_simple_tag(f, 'Translated', 'Yes' if 'translated' in languages else 'No')
[xml_write_simple_tag(f, 'Language', i) for i in languages if i != 'translated'] [xml_write_simple_tag(f, 'LanguageISO', LANGUAGEISO[i]) for i in languages \
if (i != 'translated' and i in LANGUAGEISO)]
f.write('</ComicInfo>') f.write('</ComicInfo>')

View File

@ -20,7 +20,11 @@ def request(method, url, **kwargs):
'User-Agent': 'nhentai command line client (https://github.com/RicterZ/nhentai)', 'User-Agent': 'nhentai command line client (https://github.com/RicterZ/nhentai)',
'Cookie': constant.CONFIG['cookie'] 'Cookie': constant.CONFIG['cookie']
}) })
return getattr(session, method)(url, proxies=constant.CONFIG['proxy'], verify=False, **kwargs)
if not kwargs.get('proxies', None):
kwargs['proxies'] = constant.CONFIG['proxy']
return getattr(session, method)(url, verify=False, **kwargs)
def check_cookie(): def check_cookie():
@ -166,7 +170,7 @@ def generate_main_html(output_dir='./'):
logger.warning('Writing Main Viewer failed ({})'.format(str(e))) logger.warning('Writing Main Viewer failed ({})'.format(str(e)))
def generate_cbz(output_dir='.', doujinshi_obj=None, rm_origin_dir=False, write_comic_info=False): def generate_cbz(output_dir='.', doujinshi_obj=None, rm_origin_dir=False, write_comic_info=True):
if doujinshi_obj is not None: if doujinshi_obj is not None:
doujinshi_dir = os.path.join(output_dir, doujinshi_obj.filename) doujinshi_dir = os.path.join(output_dir, doujinshi_obj.filename)
if write_comic_info: if write_comic_info:
@ -194,8 +198,6 @@ def generate_cbz(output_dir='.', doujinshi_obj=None, rm_origin_dir=False, write_
def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False): def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False):
try: try:
import img2pdf import img2pdf
except ImportError:
logger.error("Please install img2pdf package by using pip.")
"""Write images to a PDF file using img2pdf.""" """Write images to a PDF file using img2pdf."""
if doujinshi_obj is not None: if doujinshi_obj is not None:
@ -223,6 +225,8 @@ def generate_pdf(output_dir='.', doujinshi_obj=None, rm_origin_dir=False):
logger.log(15, 'PDF file has been written to \'{0}\''.format(doujinshi_dir)) logger.log(15, 'PDF file has been written to \'{0}\''.format(doujinshi_dir))
except ImportError:
logger.error("Please install img2pdf package by using pip.")
def unicode_truncate(s, length, encoding='utf-8'): 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 """https://stackoverflow.com/questions/1809531/truncating-unicode-so-it-fits-a-maximum-size-when-encoded-for-wire-transfer

View File

@ -1,7 +1,6 @@
requests>=2.5.0 requests>=2.5.0
soupsieve<2.0 soupsieve
BeautifulSoup4>=4.0.0 BeautifulSoup4>=4.0.0
threadpool>=1.2.7
tabulate>=0.7.5 tabulate>=0.7.5
future>=0.15.2 future>=0.15.2
iso8601 >= 0.1 iso8601 >= 0.1