Skip to content

Commit

Permalink
feat: bulk download (#2)
Browse files Browse the repository at this point in the history
Bulk Download
  • Loading branch information
sinkaroid committed Aug 28, 2022
2 parents 9587094 + e6748a0 commit 84b835d
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ hentaifox:
tomoe --hentaifox 59026

hentai2read:
tomoe --hentai2read chaldea_life 1
tomoe --hentai2read chaldea_life:1

simply:
tomoe --simply "fate-grand-order/fgo-no-ashibon-fgo-foot-book/all-pages"
Expand Down
68 changes: 46 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
# Tomoe [![Testing](https://github.com/sinkaroid/tomoe/actions/workflows/api.yml/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/api.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/a729e38da1fe1ee520b1/maintainability)](https://codeclimate.com/github/sinkaroid/tomoe/maintainability)

<a href="https://github.com/sinkaroid/tomoe/wiki"><img align="right" src="https://cdn.discordapp.com/attachments/952117487166705747/954724094379708436/s.png" width="180"></a>

**A doujinshi downloader with ease**
**A doujinshi downloader with ease**

Tomoe is a CLI tool for downloading doujinshi from various doujinboards. It's also has built-in auto render into PDF for it's utility, hopefully will be reusable.
Tomoe is a CLI tool for downloading doujinshi from various doujinboards. It's also has built-in auto render into PDF for it's utility, hopefully will be reusable.

> 🚀 [Commands](#options)[Documentation](https://github.com/sinkaroid/tomoe/wiki)[Report Issues](https://github.com/sinkaroid/tomoe/issues/new/choose)
## Tomoe vs. the doujinboards

Some tests has high resolve time and rendering a bit longer,
because some source does not providing real extension of a images, tomoe should check and guessing it's format

| Site | Status | Average time | Downloaded contents |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---------------------- |
| `nhentai` | [![Nhentai download](https://github.com/sinkaroid/tomoe/workflows/nhentai/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/nhentai.yml) | ~0.52 minutes | ~10.39 MB (26 content) |
| `pururin` | [![Pururin download](https://github.com/sinkaroid/tomoe/workflows/pururin/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/pururin.yml) | ~0.63 minutes | ~15.55 MB (20 content) |
| `hentaifox` | [![Hentaifox download](https://github.com/sinkaroid/tomoe/workflows/hentaifox/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/hentaifox.yml) | ~0.33 minutes | ~8.18 MB (26 content) |
| `hentai2read` | [![Hentai2read download](https://github.com/sinkaroid/tomoe/workflows/hentai2read/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/hentai2read.yml) | ~0.10 minutes | ~7.78 MB (26 content) |
| `simply-hentai` | [![Simply-hentai download](https://github.com/sinkaroid/tomoe/workflows/simplyh/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/simply.yml) | ~0.29 minutes | ~42.61 MB (19 content) |
| `asmhentai` | [![Asmhentai download](https://github.com/sinkaroid/tomoe/workflows/asmhentai/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/asmhentai.yml) | ~0.23 minutes | ~4.96 MB (23 content) |
| Site | Status | Average time | Downloaded contents |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---------------------- |
| `nhentai` | [![Nhentai download](https://github.com/sinkaroid/tomoe/workflows/nhentai/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/nhentai.yml) | ~0.52 minutes | ~10.39 MB (26 content) |
| `pururin` | [![Pururin download](https://github.com/sinkaroid/tomoe/workflows/pururin/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/pururin.yml) | ~0.63 minutes | ~15.55 MB (20 content) |
| `hentaifox` | [![Hentaifox download](https://github.com/sinkaroid/tomoe/workflows/hentaifox/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/hentaifox.yml) | ~0.33 minutes | ~8.18 MB (26 content) |
| `hentai2read` | [![Hentai2read download](https://github.com/sinkaroid/tomoe/workflows/hentai2read/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/hentai2read.yml) | ~0.10 minutes | ~7.78 MB (26 content) |
| `simply-hentai` | [![Simply-hentai download](https://github.com/sinkaroid/tomoe/workflows/simplyh/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/simply.yml) | ~0.29 minutes | ~42.61 MB (19 content) |
| `asmhentai` | [![Asmhentai download](https://github.com/sinkaroid/tomoe/workflows/asmhentai/badge.svg)](https://github.com/sinkaroid/tomoe/actions/workflows/asmhentai.yml) | ~0.23 minutes | ~4.96 MB (23 content) |

## Features

- Plenty of sites coverage
- Built-in auto render into PDF
- Minimalist dependencies
Expand All @@ -29,7 +32,9 @@ because some source does not providing real extension of a images, tomoe should
<img src="https://cdn.discordapp.com/attachments/952117487166705747/955118232119955466/nh-tomoe.png" width="600" alt="tomoe">

## Site support

Currently tomoe support the following websites:

- [nhentai.net](https://nhentai.net/)
- [pururin.to](https://pururin.to/)
- [hentaifox.com](https://hentaifox.com/)
Expand All @@ -38,48 +43,65 @@ Currently tomoe support the following websites:
- [asmhentai.com](https://asmhentai.com/)

## Dependencies
tomoe depends on [requests](https://requests.readthedocs.io/en/master/) + [asyncio](https://docs.python.org/3/library/asyncio.html),

tomoe depends on [requests](https://requests.readthedocs.io/en/master/) + [asyncio](https://docs.python.org/3/library/asyncio.html),
and uses [janda](https://pypi.org/project/janda/) for it's doujin library client for Python.

## Prerequisites

<table>
<td><b>NOTE:</b> Python 3.7 or above</td>
</table>


## Installation

It's fairly simple to install tomoe

### 🚀from PyPI

`pip install tomoe`

### 🚀from pipenv

`pipenv install tomoe`

### 🚀from this repository

Clone this repository, and do `python setup.py install`

## Command usage

`tomoe --args <id|path>`

## Quick example
$ tomoe --nhentai 255369

$ tomoe --nhentai 255369

After that, you could see the download results or throw you an error if something went wrong.

## Options

Here are all the options it supports.

| **Argument** | **Description** | **Example** |
| -------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --nhentai, int | download from nhentai | [`tomoe --nhentai 255369`](https://nhentai.net/g/255369/) |
| --pururin, int | download from pururin | [`tomoe --pururin 47226`](https://pururin.to/gallery/47226/crot-sampe-lumpuh) |
| --hentaifox, int | download from hentaifox | [`tomoe --hentaifox 59026`](https://hentaifox.com/gallery/59026/) |
| --hentai2read, str chapter | download from hentai2read | [`tomoe --hentai2read chaldea_life 1`](https://hentai2read.com/chaldea_life/) |
| --simply, str | download from simply-hentai | [`tomoe --simply "fate-grand-order/fgo-no-ashibon-fgo-foot-book/all-pages"`](https://www.simply-hentai.com/fate-grand-order/fgo-no-ashibon-fgo-foot-book/all-pages) |
| --asmhentai, int | download from asmhentai | [`tomoe --asmhentai 311851`](https://asmhentai.com/g/311851/) |
| **Argument** | **Description** | **Example** |
| --------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --nhentai, int | download from nhentai | [`tomoe --nhentai 255369`](https://nhentai.net/g/255369/) |
| --pururin, int | download from pururin | [`tomoe --pururin 47226`](https://pururin.to/gallery/47226/crot-sampe-lumpuh) |
| --hentaifox, int | download from hentaifox | [`tomoe --hentaifox 59026`](https://hentaifox.com/gallery/59026/) |
| --hentai2read, str chapter:number | download from hentai2read | [`tomoe --hentai2read chaldea_life:1`](https://hentai2read.com/chaldea_life/) |
| --simply, str | download from simply-hentai | [`tomoe --simply "fate-grand-order/fgo-no-ashibon-fgo-foot-book/all-pages"`](https://www.simply-hentai.com/fate-grand-order/fgo-no-ashibon-fgo-foot-book/all-pages) |
| --asmhentai, int | download from asmhentai | [`tomoe --asmhentai 311851`](https://asmhentai.com/g/311851/) |

### Bulk Download

| **Sites** | **Description** | **Example** |
| ----------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| nhentai | place multiple id | `tomoe --nhentai 255369 417103 417119` |
| pururin | place multiple id | `tomoe --pururin 47226 64351 56175` |
| hentaifox | place multiple id | `tomoe --hentaifox 59026 61805` |
| hentai2read | place multiple `chapter:number` | `tomoe --hentai2read chaldea_life:1 watashitachi_producersan_ni_mechakucha:1` |
| simply | place multiple chapter | `tomoe --simply "fate-grand-order/fgo-no-ashibon-fgo-foot-book/all-pages" "original-work/kanchou-manga-cffc37a/all-pages"` |
| asmhentai | place multiple id | `tomoe --asmhentai 311851 210135 309068` |

## Todo

Expand All @@ -94,7 +116,9 @@ This tool can be freely copied, modified, altered, distributed without any attri
like this tool deserves an attribution, mention it. It won't hurt anybody

## Pronounciation

[`ja_JP`](https://www.localeplanet.com/java/ja-JP/index.html)**to-moe** — that resembles a comma or the usual form of a [magatama](#tomoe).

## EoF
All books from those doujinboards are definitely ilegal from original authors.

All books from those doujinboards are definitely ilegal from original authors.
2 changes: 1 addition & 1 deletion tomoe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "3.0.10"
__version__ = "3.0.12"
from .pururin import get_pur
from .nhentai import get_nh
from .hentaifox import get_hfox
Expand Down
17 changes: 11 additions & 6 deletions tomoe/asmhentai.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import janda
import requests
import os
Expand All @@ -16,13 +17,19 @@
)
from inputimeout import inputimeout, TimeoutOccurred

hfox = janda.Asmhentai()
asmh = janda.Asmhentai()
t: str = "tomoe.html"


async def get_asm(id: int = choose().asmhentai):
async def get_asm(ids=choose().asmhentai):
for id in ids:
await asyncio.gather(process_asmhentai(id))
print(f"Complete process {id}")


async def process_asmhentai(id: int):
initial = time.time()
data = await hfox.get(id)
data = await asmh.get(id)
parser = janda.resolve(data)

title = re.sub(r"[^\w\s]", "", parser["data"]["title"])
Expand Down Expand Up @@ -143,6 +150,4 @@ async def get_asm(id: int = choose().asmhentai):
return

except TimeoutOccurred:
print("Timeout occurred")
os.remove(neat_dir + "/" + t)
exit()
print(f"Timeout occurred, not rendering pdf {id}")
22 changes: 9 additions & 13 deletions tomoe/hentai2read.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import janda
import requests
import os
Expand All @@ -19,20 +20,17 @@
h2r = janda.Hentai2read()
t: str = "tomoe.html"

value = choose().hentai2read
if value is None:
par1 = ""
par2 = ""

else:
value.sort()
par1 = value[1]
par2 = value[0]
async def get_h2r(ids=choose().hentai2read):
for id in ids:
par = id.split(":")
await asyncio.gather(process_h2r(par[0], par[1]))
print(f"Complete process {par[0]}, chapter {par[1]}")


async def get_h2r(id: str = par1, chapter: int = par2):
async def process_h2r(id: str, chapter: int):
initial = time.time()
data = await h2r.get(id[0], chapter)
data = await h2r.get(id, chapter)
parser = janda.resolve(data)

title = re.sub(r"[^\w\s]", "", parser["data"]["title"])
Expand Down Expand Up @@ -123,6 +121,4 @@ async def get_h2r(id: str = par1, chapter: int = par2):
return

except TimeoutOccurred:
print("Timeout occurred")
os.remove(neat_dir + "/" + t)
exit()
print(f"Timeout occurred, not rendering pdf {id}, chapter: {chapter}")
13 changes: 9 additions & 4 deletions tomoe/hentaifox.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import janda
import requests
import os
Expand All @@ -20,7 +21,13 @@
t: str = "tomoe.html"


async def get_hfox(id: int = choose().hentaifox):
async def get_hfox(ids=choose().hentaifox):
for id in ids:
await asyncio.gather(process_hentaifox(id))
print(f"Complete process {id}")


async def process_hentaifox(id: int):
initial = time.time()
data = await hfox.get(id)
parser = janda.resolve(data)
Expand Down Expand Up @@ -143,6 +150,4 @@ async def get_hfox(id: int = choose().hentaifox):
return

except TimeoutOccurred:
print("Timeout occurred")
os.remove(neat_dir + "/" + t)
exit()
print(f"Timeout occurred, not rendering pdf {id}")
13 changes: 9 additions & 4 deletions tomoe/nhentai.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import janda
import requests
import os
Expand All @@ -20,7 +21,13 @@
t: str = "tomoe.html"


async def get_nh(id: int = choose().nhentai):
async def get_nh(ids=choose().nhentai):
for id in ids:
await asyncio.gather(process_nhentai(id))
print(f"Complete process {id}")


async def process_nhentai(id: int):
initial = time.time()
data = await nh.get(id)
parser = janda.resolve(data)
Expand Down Expand Up @@ -120,6 +127,4 @@ async def get_nh(id: int = choose().nhentai):
return

except TimeoutOccurred:
print("Timeout occurred")
os.remove(neat_dir + "/" + t)
exit()
print(f"Timeout occurred, not rendering pdf {id}")
13 changes: 9 additions & 4 deletions tomoe/pururin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import janda
import requests
import os
Expand All @@ -20,7 +21,13 @@
t: str = "tomoe.html"


async def get_pur(id: int = choose().pururin):
async def get_pur(ids=choose().pururin):
for id in ids:
await asyncio.gather(process_pururin(id))
print(f"Complete process {id}")


async def process_pururin(id: int):
initial = time.time()
data = await pururin.get(id)
parser = janda.resolve(data)
Expand Down Expand Up @@ -121,6 +128,4 @@ async def get_pur(id: int = choose().pururin):
return

except TimeoutOccurred:
print("Timeout occurred")
os.remove(neat_dir + "/" + t)
exit()
print(f"Timeout occurred, not rendering pdf {id}")
13 changes: 9 additions & 4 deletions tomoe/simplyh.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import janda
import requests
import os
Expand All @@ -21,7 +22,13 @@
t: str = "tomoe.html"


async def get_sim(id: str = choose().simply):
async def get_sim(ids=choose().simply):
for id in ids:
await asyncio.gather(process_simplyh(id))
print(f"Complete process {id}")


async def process_simplyh(id: str):
initial = time.time()
data = await simply.get(id)
parser = janda.resolve(data)
Expand Down Expand Up @@ -118,6 +125,4 @@ async def get_sim(id: str = choose().simply):
return

except TimeoutOccurred:
print("Timeout occurred")
os.remove(neat_dir + "/" + t)
exit()
print(f"Timeout occurred, not rendering pdf {id}")
17 changes: 6 additions & 11 deletions tomoe/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,22 @@ def choose():
my_parser = argparse.ArgumentParser()

my_parser.add_argument(
"--nhentai", "-nhentai", action="store", metavar=("ID"), type=int
"--nhentai", "-nhentai", action="store", nargs='+'
)
my_parser.add_argument(
"--pururin", "-pururin", action="store", metavar=("ID"), type=int
"--pururin", "-pururin", action="store", nargs='+'
)
my_parser.add_argument(
"--simply", "-simply", action="store", metavar=("PATH_AFTER_WWW"), type=str
"--simply", "-simply", action="store", nargs='+'
)
my_parser.add_argument(
"--hentaifox", "-hentaifox", action="store", metavar=("ID"), type=int
"--hentaifox", "-hentaifox", action="store", nargs='+'
)
my_parser.add_argument(
"--hentai2read",
"-hentai2read",
nargs=2,
action="store",
metavar=("PATH", "CHAPTER"),
type=str,
"--hentai2read", "-hentai2read", action="store", nargs='+',
)
my_parser.add_argument(
"--asmhentai", "-asmhentai", action="store", metavar=("ID"), type=int
"--asmhentai", "-asmhentai", action="store", nargs='+'
)

args = my_parser.parse_args()
Expand Down

0 comments on commit 84b835d

Please sign in to comment.