diff --git a/nhentai/cmdline.py b/nhentai/cmdline.py index bbdab63..f74a0e4 100644 --- a/nhentai/cmdline.py +++ b/nhentai/cmdline.py @@ -64,6 +64,8 @@ def cmd_parser(): help='page number of search results') parser.add_option('--max-page', type='int', dest='max_page', action='store', default=1, help='The max page when recursive download tagged doujinshi') + parser.add_option('--page-range', type='string', dest='page_range', action='store', + help='page range of favorites. e.g. 1,2-5,14') parser.add_option('--sorting', dest='sorting', action='store', default='date', help='sorting of doujinshi (date / popular)', choices=['date', 'popular']) diff --git a/nhentai/command.py b/nhentai/command.py index 41ba40e..40f924f 100644 --- a/nhentai/command.py +++ b/nhentai/command.py @@ -35,7 +35,7 @@ def main(): if not options.is_download: logger.warning('You do not specify --download option') - doujinshis = favorites_parser() + doujinshis = favorites_parser(options.page_range) print_doujinshi(doujinshis) if options.is_download and doujinshis: doujinshi_ids = [i['id'] for i in doujinshis] diff --git a/nhentai/parser.py b/nhentai/parser.py index 3c01af1..0c43882 100644 --- a/nhentai/parser.py +++ b/nhentai/parser.py @@ -65,7 +65,7 @@ def _get_title_and_id(response): return result -def favorites_parser(): +def favorites_parser(page_range=''): result = [] html = BeautifulSoup(request('get', constant.FAV_URL).content, 'html.parser') count = html.find('span', attrs={'class': 'count'}) @@ -89,7 +89,12 @@ def favorites_parser(): if os.getenv('DEBUG'): pages = 1 - for page in range(1, pages + 1): + page_range_list = range(1, pages + 1) + if page_range: + logger.info('page range is {0}'.format(page_range)) + page_range_list = page_range_parser(page_range, pages) + + for page in page_range_list: try: logger.info('Getting doujinshi ids of page %d' % page) resp = request('get', constant.FAV_URL + '?page=%d' % page).content @@ -100,6 +105,30 @@ def favorites_parser(): return result +def page_range_parser(page_range, max_page_num): + pages = set() + ranges = str.split(page_range, ',') + for range_str in ranges: + idx = range_str.find('-') + if idx == -1: + try: + page = int(range_str) + if page <= max_page_num: + pages.add(page) + except ValueError: + logger.error('page range({0}) is not valid'.format(page_range)) + else: + try: + left = int(range_str[:idx]) + right = int(range_str[idx+1:]) + if right > max_page_num: + right = max_page_num + for page in range(left, right+1): + pages.add(page) + except ValueError: + logger.error('page range({0}) is not valid'.format(page_range)) + + return list(pages) def doujinshi_parser(id_): if not isinstance(id_, (int,)) and (isinstance(id_, (str,)) and not id_.isdigit()): diff --git a/nhentai/viewer/scripts.js b/nhentai/viewer/scripts.js index 6fea1c2..e1301b0 100644 --- a/nhentai/viewer/scripts.js +++ b/nhentai/viewer/scripts.js @@ -1,81 +1,85 @@ -const pages = Array.from(document.querySelectorAll('img.image-item')); -let currentPage = 0; - -function changePage(pageNum) { - const previous = pages[currentPage]; - const current = pages[pageNum]; - - if (current == null) { - return; - } - - previous.classList.remove('current'); - current.classList.add('current'); - - currentPage = pageNum; - - const display = document.getElementById('dest'); - display.style.backgroundImage = `url("${current.src}")`; - - document.getElementById('page-num') - .innerText = [ - (pageNum + 1).toLocaleString(), - pages.length.toLocaleString() - ].join('\u200a/\u200a'); -} - -changePage(0); - -document.getElementById('list').onclick = event => { - if (pages.includes(event.target)) { - changePage(pages.indexOf(event.target)); - } -}; - -document.getElementById('image-container').onclick = event => { - const width = document.getElementById('image-container').clientWidth; - const clickPos = event.clientX / width; - - if (clickPos < 0.5) { - changePage(currentPage - 1); - } else { - changePage(currentPage + 1); - } -}; - -document.onkeypress = event => { - switch (event.key.toLowerCase()) { - // Previous Image - case 'w': - document.getElementById("dest").style.height = "200%"; - document.getElementById("list").style.height = "200%"; - break; - case 'a': - changePage(currentPage - 1); - break; - // Return to previous page - case 'q': - window.history.go(-1); - break; - // Next Image - case ' ': - case 's': - document.getElementById("dest").style.height = "100%"; - document.getElementById("list").style.height = "100%"; - break; - case 'd': - changePage(currentPage + 1); - break; - }// remove arrow cause it won't work -}; - -document.onkeydown = event =>{ - switch (event.keyCode) { - case 37: //left - changePage(currentPage - 1); - break; - case 39: //right - changePage(currentPage + 1); - break; - } +const pages = Array.from(document.querySelectorAll('img.image-item')); +let currentPage = 0; + +function changePage(pageNum) { + const previous = pages[currentPage]; + const current = pages[pageNum]; + + if (current == null) { + return; + } + + previous.classList.remove('current'); + current.classList.add('current'); + + currentPage = pageNum; + + const display = document.getElementById('dest'); + display.style.backgroundImage = `url("${current.src}")`; + + scroll(0,0) + + document.getElementById('page-num') + .innerText = [ + (pageNum + 1).toLocaleString(), + pages.length.toLocaleString() + ].join('\u200a/\u200a'); +} + +changePage(0); + +document.getElementById('list').onclick = event => { + if (pages.includes(event.target)) { + changePage(pages.indexOf(event.target)); + } +}; + +document.getElementById('image-container').onclick = event => { + const width = document.getElementById('image-container').clientWidth; + const clickPos = event.clientX / width; + + if (clickPos < 0.5) { + changePage(currentPage - 1); + } else { + changePage(currentPage + 1); + } +}; + +document.onkeypress = event => { + switch (event.key.toLowerCase()) { + // Previous Image + case 'w': + scrollBy(0, -40); + break; + case 'a': + changePage(currentPage - 1); + break; + // Return to previous page + case 'q': + window.history.go(-1); + break; + // Next Image + case ' ': + case 's': + scrollBy(0, 40); + break; + case 'd': + changePage(currentPage + 1); + break; + }// remove arrow cause it won't work +}; + +document.onkeydown = event =>{ + switch (event.keyCode) { + case 37: //left + changePage(currentPage - 1); + break; + case 38: //up + break; + case 39: //right + changePage(currentPage + 1); + break; + case 40: //down + break; + } }; \ No newline at end of file diff --git a/nhentai/viewer/styles.css b/nhentai/viewer/styles.css index 8246b36..62dfbe4 100644 --- a/nhentai/viewer/styles.css +++ b/nhentai/viewer/styles.css @@ -1,92 +1,70 @@ -*, *::after, *::before { - box-sizing: border-box; -} - -img { - vertical-align: middle; -} - -html, body { - display: flex; - background-color: #e8e6e6; - height: 100%; - width: 100%; - padding: 0; - margin: 0; - font-family: sans-serif; -} - -#list { - height: 100%; - overflow: auto; - width: 260px; - text-align: center; -} - -#list img { - width: 200px; - padding: 10px; - border-radius: 10px; - margin: 15px 0; - cursor: pointer; -} - -#list img.current { - background: #0003; -} - -#image-container { - flex: auto; - height: 100vh; - background: #000; - color: #fff; - text-align: center; - cursor: pointer; - -webkit-user-select: none; - user-select: none; - position: relative; -} - -#image-container #dest { - background: #000; - height: 100%; - width: 100%; - background-size: contain; - background-repeat: no-repeat; - background-position: center; -} - -#image-container #page-num { - position: absolute; - font-size: 18pt; - left: 10px; - bottom: 5px; - font-weight: bold; - opacity: 0.75; - text-shadow: /* Duplicate the same shadow to make it very strong */ - 0 0 2px #222, - 0 0 2px #222, - 0 0 2px #222; -} - -@media only screen and (max-width: 855px) { - nav { - display: none; - } -} - -@media only screen and (max-device-width: 855px) { - nav { - display: none; - } -} - -div { - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -:focus { - outline: 0; - border:none; - color: rgba(0, 0, 0, 0); + +*, *::after, *::before { + box-sizing: border-box; +} + +img { + vertical-align: middle; +} + +html, body { + display: flex; + background-color: #e8e6e6; + height: 100%; + width: 100%; + padding: 0; + margin: 0; + font-family: sans-serif; +} + +#list { + height: 2000px; + overflow: scroll; + width: 260px; + text-align: center; +} + +#list img { + width: 200px; + padding: 10px; + border-radius: 10px; + margin: 15px 0; + cursor: pointer; +} + +#list img.current { + background: #0003; +} + +#image-container { + flex: auto; + height: 2000px; + background: #222; + color: #fff; + text-align: center; + cursor: pointer; + -webkit-user-select: none; + user-select: none; + position: relative; +} + +#image-container #dest { + height: 2000px; + width: 100%; + background-size: contain; + background-repeat: no-repeat; + background-position: top; +} + +#image-container #page-num { + position: static; + font-size: 14pt; + left: 10px; + bottom: 5px; + font-weight: bold; + opacity: 0.75; + text-shadow: /* Duplicate the same shadow to make it very strong */ + 0 0 2px #222, + 0 0 2px #222, + 0 0 2px #222; } \ No newline at end of file