added config
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
env
|
env
|
||||||
__pycache__
|
__pycache__
|
||||||
.coverage
|
.coverage
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
sample
|
||||||
15
yoink/cli.py
15
yoink/cli.py
@@ -5,17 +5,18 @@ import sys
|
|||||||
import click
|
import click
|
||||||
from click_default_group import DefaultGroup
|
from click_default_group import DefaultGroup
|
||||||
|
|
||||||
from yoink.common import app_root, library_path, config_path
|
from yoink.config import YoinkConfig, app_root, config_from_file, library_path, config_path
|
||||||
from yoink.comic import Comic
|
from yoink.comic import Comic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
queue = []
|
queue = []
|
||||||
|
config = config_from_file('yoink.json')
|
||||||
|
|
||||||
|
|
||||||
def download_comic(url, path, series):
|
def download_comic(url, series):
|
||||||
try:
|
try:
|
||||||
comic = Comic(url, path=path if path else None)
|
comic = Comic(url)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
click.echo(f'{url} is not supported or is not a valid URL')
|
click.echo(f'{url} is not supported or is not a valid URL')
|
||||||
return 1
|
return 1
|
||||||
@@ -32,7 +33,7 @@ def download_comic(url, path, series):
|
|||||||
click.echo('Success')
|
click.echo('Success')
|
||||||
|
|
||||||
if series and comic.next:
|
if series and comic.next:
|
||||||
download_comic(comic.next, path, series)
|
download_comic(comic.next, series)
|
||||||
|
|
||||||
|
|
||||||
@click.group(cls=DefaultGroup, default='download', default_if_no_args=True)
|
@click.group(cls=DefaultGroup, default='download', default_if_no_args=True)
|
||||||
@@ -45,21 +46,21 @@ def yoink():
|
|||||||
def init():
|
def init():
|
||||||
|
|
||||||
click.echo(f'Initializing for {sys.platform}')
|
click.echo(f'Initializing for {sys.platform}')
|
||||||
|
click.echo(config)
|
||||||
|
|
||||||
|
|
||||||
@yoink.command()
|
@yoink.command()
|
||||||
# @click.option('-c', '--comic', is_flag=True, help='Download a Comic file')
|
# @click.option('-c', '--comic', is_flag=True, help='Download a Comic file')
|
||||||
# @click.option('-t', '--torrent', is_flag=True, help='Download a Torrent')
|
# @click.option('-t', '--torrent', is_flag=True, help='Download a Torrent')
|
||||||
@click.option('-s', '--series', is_flag=True, help='Download the entire series')
|
@click.option('-s', '--series', is_flag=True, help='Download the entire series')
|
||||||
@click.option('-p', '--path', help='Change the download path')
|
|
||||||
@click.argument('url')
|
@click.argument('url')
|
||||||
def download(url, path, series):
|
def download(url, series):
|
||||||
# Account for whitespace/blank urls
|
# Account for whitespace/blank urls
|
||||||
if url.strip() == '':
|
if url.strip() == '':
|
||||||
click.echo('url cannot be blank')
|
click.echo('url cannot be blank')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
download_comic(url, path, series)
|
download_comic(url, series)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from yoink.common import required_comic_files, skippable_images, library_path
|
from yoink.config import required_archive_files, skippable_images, library_path, config
|
||||||
from yoink.scraper import Scrapable
|
from yoink.scraper import Scrapable
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -102,13 +102,13 @@ class Comic(Scrapable):
|
|||||||
|
|
||||||
|
|
||||||
def can_remove(self, filename : str) -> bool:
|
def can_remove(self, filename : str) -> bool:
|
||||||
return not filename.endswith(required_comic_files)
|
return not filename.endswith(config.skippable_images)
|
||||||
|
|
||||||
|
|
||||||
class ComicArchiver:
|
class ComicArchiver:
|
||||||
def __init__(self, comic : Comic, library=None) -> None:
|
def __init__(self, comic : Comic, library=None) -> None:
|
||||||
self.comic = comic
|
self.comic = comic
|
||||||
self.worktree = library if library else os.path.join(library_path, f'comics/{self.comic.title}')
|
self.worktree = library if library else os.path.join(config.library_path, f'comics/{self.comic.title}')
|
||||||
self.queue = []
|
self.queue = []
|
||||||
|
|
||||||
def add(self, link : str) -> None:
|
def add(self, link : str) -> None:
|
||||||
@@ -155,7 +155,7 @@ class ComicArchiver:
|
|||||||
|
|
||||||
def cleanup_worktree(self):
|
def cleanup_worktree(self):
|
||||||
for image in os.listdir(self.worktree):
|
for image in os.listdir(self.worktree):
|
||||||
if not image.endswith(required_comic_files):
|
if not image.endswith(required_archive_files):
|
||||||
os.remove(os.path.join(self.worktree, image))
|
os.remove(os.path.join(self.worktree, image))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
from pathlib import Path
|
|
||||||
# TODO replace os path with pathlib
|
|
||||||
import os
|
|
||||||
from enum import Enum, auto
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO replace expan user
|
|
||||||
home_folder = Path.home()
|
|
||||||
app_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
config_path = os.path.abspath(os.path.join(os.path.expanduser('~'), '.config/yoink'))
|
|
||||||
library_path = os.path.abspath(os.path.join(os.path.expanduser('~'), 'yoink/library'))
|
|
||||||
required_comic_files = ('.cbr', '.cbz', '000.jpg', '001.jpg')
|
|
||||||
skippable_images = ('logo-1.png', 'logo.png', 'report.png', 'request.png', 'prev.png', 'Next.png', 'Donate.png', '11.png', 'navbar.svg')
|
|
||||||
supported_sites = ['readallcomics.com', 'tpb.party', 'dragonballsupermanga.net', 'mangadex.tv']
|
|
||||||
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'}
|
|
||||||
87
yoink/config.py
Normal file
87
yoink/config.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
# TODO replace os path with pathlib
|
||||||
|
import os
|
||||||
|
from enum import Enum, auto
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class YoinkConfig:
|
||||||
|
home_path: str
|
||||||
|
config_path: str
|
||||||
|
app_root: str
|
||||||
|
library_path: str
|
||||||
|
skippable_images: set
|
||||||
|
supported_sites: set
|
||||||
|
headers: dict
|
||||||
|
plugins: list
|
||||||
|
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
'home_path': str(Path.home()),
|
||||||
|
'config_path': os.path.abspath(os.path.join(Path.home(), '.config/yoink')),
|
||||||
|
'app_root': os.path.abspath(os.path.join(os.path.dirname(__file__), '..')),
|
||||||
|
'library_path': os.path.abspath(os.path.join(Path.home(), 'yoink/library')),
|
||||||
|
'skippable_images': ('.cbr', '.cbz', '000.jpg', '001.jpg'),
|
||||||
|
'supported_sites': [
|
||||||
|
{
|
||||||
|
"name": 'readallcomics.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 'tpb.party',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 'dragonballsupermanga.net',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 'mangadex.tv'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'headers': {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'},
|
||||||
|
'plugins': []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def config_from_file(filepath: str) -> YoinkConfig:
|
||||||
|
if os.path.exists(filepath):
|
||||||
|
with open(filepath, 'r') as file:
|
||||||
|
|
||||||
|
data = json.load(file)
|
||||||
|
return YoinkConfig(**data)
|
||||||
|
else:
|
||||||
|
# TODO prompt user for prefered file locations and save yoink.json
|
||||||
|
return config_from_defaults()
|
||||||
|
|
||||||
|
|
||||||
|
def config_from_defaults() -> YoinkConfig:
|
||||||
|
return YoinkConfig(**defaults)
|
||||||
|
|
||||||
|
|
||||||
|
home_folder = Path.home()
|
||||||
|
|
||||||
|
|
||||||
|
app_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
|
|
||||||
|
config_path = os.path.abspath(os.path.join(home_folder, '.config/yoink'))
|
||||||
|
|
||||||
|
|
||||||
|
library_path = os.path.abspath(os.path.join(home_folder, 'yoink/library'))
|
||||||
|
|
||||||
|
|
||||||
|
required_archive_files = ('.cbr', '.cbz', '000.jpg', '001.jpg')
|
||||||
|
|
||||||
|
skippable_images = ('logo-1.png', 'logo.png', 'report.png', 'request.png', 'prev.png', 'Next.png', 'Donate.png', '11.png', 'navbar.svg')
|
||||||
|
|
||||||
|
_sites = ['readallcomics.com', 'tpb.party', 'dragonballsupermanga.net', 'mangadex.tv']
|
||||||
|
|
||||||
|
supported_sites = _sites
|
||||||
|
|
||||||
|
|
||||||
|
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'}
|
||||||
|
|
||||||
|
|
||||||
|
config = config_from_file('yoink.json')
|
||||||
24
yoink/factory.py
Normal file
24
yoink/factory.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from typing import Callable, Any
|
||||||
|
|
||||||
|
from yoink.scraper import Scrapable
|
||||||
|
|
||||||
|
|
||||||
|
downloader_creation_funcs: dict[str, Callable[..., Scrapable]] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def register(url: str, creation_function: Callable[..., Scrapable]):
|
||||||
|
downloader_creation_funcs[url] = creation_function
|
||||||
|
|
||||||
|
def unregister(url: str):
|
||||||
|
downloader_creation_funcs.pop(url, None)
|
||||||
|
|
||||||
|
def create(arguments: dict[str, Any]) -> Scrapable:
|
||||||
|
arguments_copy = arguments.copy()
|
||||||
|
|
||||||
|
url = arguments_copy.pop('url')
|
||||||
|
|
||||||
|
try:
|
||||||
|
creation_func = downloader_creation_funcs[url]
|
||||||
|
return creation_func(**arguments_copy)
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError(f'Unsupported website: {url}')
|
||||||
@@ -4,7 +4,7 @@ from bs4 import BeautifulSoup
|
|||||||
import os
|
import os
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
|
|
||||||
from yoink.common import supported_sites, library_path
|
from yoink.config import supported_sites, library_path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
62
yoink/yoink.json
Normal file
62
yoink/yoink.json
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"home_path": "",
|
||||||
|
"config_path": "",
|
||||||
|
"app_root": "",
|
||||||
|
"library_path": "/home/makubex/yoink/library",
|
||||||
|
"headers": {
|
||||||
|
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
|
||||||
|
},
|
||||||
|
"skippable_images": ["logo-1.png","logo.png","report.png","request.png","prev.png","Next.png","Donate.png","11.png","navbar.svg"],
|
||||||
|
"supported_sites": [
|
||||||
|
{
|
||||||
|
"name": "readallcomics",
|
||||||
|
"url": "http://readallcomics.com",
|
||||||
|
"search": {
|
||||||
|
"default": {
|
||||||
|
"element": "div",
|
||||||
|
"class": "separator",
|
||||||
|
"attrs": null
|
||||||
|
},
|
||||||
|
"no-div": {
|
||||||
|
"element": "img",
|
||||||
|
"class": null,
|
||||||
|
"attrs": {
|
||||||
|
"width": "1000px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"excaliber": {
|
||||||
|
"element": "img",
|
||||||
|
"class": null,
|
||||||
|
"attrs": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dragonballsupermanga",
|
||||||
|
"url": "https://www.dragonballsupermanga.net",
|
||||||
|
"search": {
|
||||||
|
"dbsuper": {
|
||||||
|
"element": "meta",
|
||||||
|
"class": null,
|
||||||
|
"attrs": {
|
||||||
|
"property": "twitter:image"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mangadex",
|
||||||
|
"url": "https://www.mangadex.tv",
|
||||||
|
"search": {
|
||||||
|
"mangadex": {
|
||||||
|
"element": "img",
|
||||||
|
"class": null,
|
||||||
|
"attrs": {
|
||||||
|
"draggable": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"plugins": []
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user