Add logging and new options to CLI
This commit is contained in:
37
README.md
37
README.md
@@ -4,40 +4,39 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<kbd>
|
<kbd>
|
||||||
<img src="https://raw.githubusercontent.com/Rdimo/images/master/pip-install-bitches/Roxy-pip-install-bitches.jpg"></img>
|
<img src="https://raw.githubusercontent.com/analgadgets/pip-install-traps/main/images/trap.jpg">
|
||||||
</kbd>
|
</kbd>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/pypi/v/bitches?style=flat-square">
|
<img src="https://img.shields.io/pypi/v/traps?style=flat-square">
|
||||||
<img src="https://img.shields.io/pypi/dm/bitches?style=flat-square">
|
<img src="https://img.shields.io/github/stars/analgadgets/pip-install-traps?label=Stars&style=flat-square">
|
||||||
<img src="https://sonarcloud.io/api/project_badges/measure?project=Rdimo_pip-install-bitches&metric=ncloc">
|
<img src="https://img.shields.io/github/forks/analgadgets/pip-install-traps?label=Forks&style=flat-square">
|
||||||
<img src="https://img.shields.io/github/stars/Rdimo/pip-install-bitches?label=Stars&style=flat-square">
|
|
||||||
<img src="https://img.shields.io/github/forks/Rdimo/pip-install-bitches?label=Forks&style=flat-square">
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 align="center">
|
<h2 align="center">
|
||||||
pip-install-bitches was made by
|
pip-install-traps was made with
|
||||||
|
|
||||||
Love ❌ code ✅
|
Cum ❌ code ✅
|
||||||
|
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 🎈・Code example
|
### Installation
|
||||||
|
```
|
||||||
Example of how you can use [traps](https://pypi.org/project/traps/)
|
pip install -U traps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
```python
|
```python
|
||||||
import traps
|
import traps
|
||||||
|
|
||||||
traps.get()
|
traps.get() # Download to `traps` directory.
|
||||||
|
traps.get("my_homework") # Or to another directory.
|
||||||
# or
|
|
||||||
|
|
||||||
traps.get(
|
|
||||||
"yes", # directory name (default: "traps")
|
|
||||||
5 # amount of traps (default: randint(5, 10))
|
|
||||||
)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Command-line interface
|
||||||
|
* `$ traps` to download 10 traps to `traps` directory
|
||||||
|
* `$ traps -n 20 my_homework` to download 20 traps to `my_homework` directory
|
||||||
|
* `$ traps --help` for more help
|
||||||
|
|||||||
BIN
images/trap.jpg
Normal file
BIN
images/trap.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 137 KiB |
36
poetry.lock
generated
36
poetry.lock
generated
@@ -62,6 +62,21 @@ docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
|
|||||||
perf = ["ipython"]
|
perf = ["ipython"]
|
||||||
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
|
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "loguru"
|
||||||
|
version = "0.6.0"
|
||||||
|
description = "Python logging made (stupidly) simple"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
|
||||||
|
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "black (>=19.10b0)", "isort (>=5.1.1)", "Sphinx (>=4.1.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.28.0"
|
version = "2.28.0"
|
||||||
@@ -101,6 +116,17 @@ brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
|
|||||||
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "win32-setctime"
|
||||||
|
version = "1.1.0"
|
||||||
|
description = "A small Python utility to set file creation time on Windows"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
version = "3.8.0"
|
version = "3.8.0"
|
||||||
@@ -116,7 +142,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
content-hash = "1d7efb30a6917067ee323aff51674a885542ec0ab42d54f1b3a07ea5e0aac6e2"
|
content-hash = "b10cf466f2fef3f183da66173a0f64e6aea107f54a3ab9c476c62548f3f798d0"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
certifi = [
|
certifi = [
|
||||||
@@ -143,6 +169,10 @@ importlib-metadata = [
|
|||||||
{file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
|
{file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
|
||||||
{file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
|
{file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
|
||||||
]
|
]
|
||||||
|
loguru = [
|
||||||
|
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
|
||||||
|
{file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
|
||||||
|
]
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.28.0-py3-none-any.whl", hash = "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f"},
|
{file = "requests-2.28.0-py3-none-any.whl", hash = "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f"},
|
||||||
{file = "requests-2.28.0.tar.gz", hash = "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"},
|
{file = "requests-2.28.0.tar.gz", hash = "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"},
|
||||||
@@ -155,6 +185,10 @@ urllib3 = [
|
|||||||
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
|
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
|
||||||
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
|
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
|
||||||
]
|
]
|
||||||
|
win32-setctime = [
|
||||||
|
{file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
|
||||||
|
{file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
|
||||||
|
]
|
||||||
zipp = [
|
zipp = [
|
||||||
{file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
|
{file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
|
||||||
{file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
|
{file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ classifiers = [
|
|||||||
python = "^3.7"
|
python = "^3.7"
|
||||||
requests = "^2.28.0"
|
requests = "^2.28.0"
|
||||||
click = "^8.1.3"
|
click = "^8.1.3"
|
||||||
|
loguru = "^0.6.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,50 @@
|
|||||||
import pathlib
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
|
import sys
|
||||||
|
from typing import Union
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from multiprocessing import Pool
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
from pathlib import Path
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
__version__ = "1.0.0"
|
__version__ = "1.0.0"
|
||||||
API_URL = "https://api.waifu.pics/nsfw/trap"
|
API_URL = "https://api.waifu.pics/nsfw/trap"
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.remove(0)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
def get_traps(params):
|
|
||||||
directory, url = params
|
def fetch_url(urls_list: list = None) -> str:
|
||||||
filename = urllib.parse.urlparse(url)
|
url = requests.get(API_URL).json()["url"]
|
||||||
filename = directory.joinpath(secrets.token_hex(8) + pathlib.Path(filename.path).suffix)
|
if urls_list is not None:
|
||||||
|
urls_list.append(url)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
def get(directory: Union[str, os.PathLike] = "traps", url: str = None,
|
||||||
|
create_dir: bool = True):
|
||||||
|
if url is None:
|
||||||
|
url = fetch_url()
|
||||||
|
directory = Path(directory)
|
||||||
|
if not directory.exists() and create_dir:
|
||||||
|
directory.mkdir()
|
||||||
|
filename = urllib.parse.urlparse(url).path
|
||||||
|
filename = directory.joinpath(secrets.token_hex(8) + Path(filename).suffix)
|
||||||
with open(filename, "wb") as f:
|
with open(filename, "wb") as f:
|
||||||
|
logger.debug(f"downloading {url}")
|
||||||
response = requests.get(url, stream=True)
|
response = requests.get(url, stream=True)
|
||||||
for block in response.iter_content(1024):
|
for block in response.iter_content(1024):
|
||||||
if not block:
|
if not block:
|
||||||
break
|
break
|
||||||
f.write(block)
|
f.write(block)
|
||||||
|
else:
|
||||||
|
logger.success(f"downloaded {url}")
|
||||||
def fetch_url(urls_list: list):
|
|
||||||
url = requests.get(API_URL).json()["url"]
|
|
||||||
urls_list.append(url)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="how about you pip install some traps")
|
@click.command(help="how about you pip install some traps")
|
||||||
@@ -38,33 +57,50 @@ def fetch_url(urls_list: list):
|
|||||||
show_default=True,
|
show_default=True,
|
||||||
help="number of traps to get"
|
help="number of traps to get"
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"-v",
|
||||||
|
"--verbose",
|
||||||
|
is_flag=True,
|
||||||
|
help="verbose output")
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"directory",
|
"directory",
|
||||||
default="traps",
|
default="traps",
|
||||||
type=click.Path(
|
type=click.Path(
|
||||||
dir_okay=True,
|
dir_okay=True,
|
||||||
file_okay=False,
|
file_okay=False,
|
||||||
path_type=pathlib.Path
|
path_type=Path
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def main(traps: int, directory: pathlib.Path):
|
def main(traps: int, directory: Path, verbose: bool):
|
||||||
|
if verbose:
|
||||||
|
loglevel = "DEBUG"
|
||||||
|
else:
|
||||||
|
loglevel = "INFO"
|
||||||
|
logger.add(
|
||||||
|
sys.stderr,
|
||||||
|
level=loglevel,
|
||||||
|
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>"
|
||||||
|
"{level: <8}</level> | <level>{message}</level>"
|
||||||
|
)
|
||||||
if not directory.exists():
|
if not directory.exists():
|
||||||
|
logger.debug(f"creating directory {directory}")
|
||||||
directory.mkdir()
|
directory.mkdir()
|
||||||
|
logger.debug("done")
|
||||||
urls = []
|
urls = []
|
||||||
threads = [
|
threads = [
|
||||||
Thread(target=fetch_url, args=(urls,))
|
Thread(target=fetch_url, args=(urls,))
|
||||||
for _ in range(traps)
|
for _ in range(traps)
|
||||||
]
|
]
|
||||||
|
logger.debug("fetching URLs")
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.start()
|
thread.start()
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join()
|
thread.join()
|
||||||
params = [
|
logger.debug("done")
|
||||||
(directory, url)
|
logger.info("downloading traps")
|
||||||
for url in urls
|
with ThreadPoolExecutor(max_workers=8) as p:
|
||||||
]
|
p.map(lambda url: get(directory, url, False), urls)
|
||||||
with Pool(8) as p:
|
logger.info(f"downloaded {traps} traps")
|
||||||
p.map(get_traps, params)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user