From ed0f2014b37ca8699615b156b332edab4f03f87e Mon Sep 17 00:00:00 2001 From: Martin Folkers Date: Thu, 13 May 2021 21:18:26 +0200 Subject: [PATCH] Add full CLI support This commit .. * Improves scripts * Updates dependencies * Supercharges .gitignore * Migrates it into an installable CLI utility .. and fixes #8 --- .gitignore | 135 ++++++++++++++++++++ README.md | 8 +- examples.py | 9 +- main.py | 93 -------------- requirements.txt | 5 - setup.py | 46 +++++++ setup.sh | 21 ++- we_love_colors/cli.py | 90 +++++++++++++ {lib => we_love_colors}/copic.py | 2 +- {lib => we_love_colors}/dulux.py | 2 +- {lib => we_love_colors}/helpers/nat_sort.py | 0 palette.py => we_love_colors/palette.py | 0 {lib => we_love_colors}/pantone.py | 4 +- {lib => we_love_colors}/prismacolor.py | 2 +- {lib => we_love_colors}/ral.py | 2 +- 15 files changed, 305 insertions(+), 114 deletions(-) delete mode 100644 main.py delete mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 we_love_colors/cli.py rename {lib => we_love_colors}/copic.py (98%) rename {lib => we_love_colors}/dulux.py (98%) rename {lib => we_love_colors}/helpers/nat_sort.py (100%) rename palette.py => we_love_colors/palette.py (100%) rename {lib => we_love_colors}/pantone.py (99%) rename {lib => we_love_colors}/prismacolor.py (98%) rename {lib => we_love_colors}/ral.py (99%) diff --git a/.gitignore b/.gitignore index 888bd1f..46def22 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,144 @@ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff +instance/ +.webassets-cache + +# Scrapy stuff +.scrapy + +# VSCode stuff +.vscode + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py # Environments .env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ # Gotta fetch 'em all! /palettes/*/**/* diff --git a/README.md b/README.md index a12cb24..26845b7 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ It's as easy as `pip install -r requirements.txt`, but you might want to make su Fetching color sets and processing them is really straightforward - for everything else, there's `--help`: ```bash -$ python main.py -Usage: main.py [OPTIONS] COMMAND [ARGS]... +$ colors +Usage: colors [OPTIONS] COMMAND [ARGS]... Options: -v, --version Show the version and exit. @@ -51,10 +51,10 @@ Using its commands `fetch` and `process` is fairly easy, like that: ```bash # Example 1 - Gotta fetch 'em `--all`: -$ python main.py fetch --all && python main.py process +$ colors fetch --all && colors process # Example 2 - Fetching specific sets & processing them: -$ python main.py fetch copic dulux && python main.py process copic dulux +$ colors fetch copic dulux && colors process copic dulux ``` ### FAQ diff --git a/examples.py b/examples.py index f1cd9b7..97e22d0 100644 --- a/examples.py +++ b/examples.py @@ -6,12 +6,13 @@ # For more information, see https://www.python.org/dev/peps/pep-0008/#imports ## -import os -import glob +from os import system +from os.path import basename, dirname +from glob import glob -for file in glob.glob('./examples/*/index.php'): +for file in glob('./examples/*/index.php'): html = file.replace('.php', '.html') - os.system('cd ' + os.path.dirname(file) + ' && php ' + os.path.basename(file) + ' > ' + os.path.basename(html)) + system('cd ' + dirname(file) + ' && php ' + basename(file) + ' > ' + basename(html)) print('Generating ' + html + ' .. done') diff --git a/main.py b/main.py deleted file mode 100644 index 011f588..0000000 --- a/main.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python3 - -## -# IMPORTS -# For more information, see https://www.python.org/dev/peps/pep-0008/#imports -## - -import click - -from lib.pantone import Pantone -from lib.ral import RAL -from lib.dulux import Dulux -from lib.copic import Copic -from lib.prismacolor import Prismacolor - - -CONTEXT_SETTINGS = dict( - help_option_names=['-h', '--help'], -) - - - -class_map = { - 'pantone': Pantone, - 'ral': RAL, - 'dulux': Dulux, - 'copic': Copic, - 'prismacolor': Prismacolor, -} - -@click.group(context_settings=CONTEXT_SETTINGS) -@click.version_option('1.0.0-beta.2', '-v', '--version') -def cli(): - pass - -@cli.command() -@click.argument('sets', nargs=-1) -@click.option('--all', 'fetch_all', flag_value=True, help='Fetch all available color sets & save as JSON.') -def fetch(sets, fetch_all): - """ - ARGS: - pantone | ral | dulux | copic | prismacolor - """ - valid_sets = list(class_map.keys()) - - if fetch_all == True: - sets = valid_sets - - for set in sets: - if set in valid_sets: - object = class_map[set]() - - try: - object.fetch_all() - except AttributeError: - object.fetch() - - object.save() - object.create_json() - else: - print('"' + set + '" isn\'t available. Please provide a valid color space,\nsuch as "pantone", "ral", "dulux", "copic" & "prismacolor".') - continue - - -@cli.command() -@click.argument('sets', nargs=-1) -@click.option('-f', '--format', type=click.Choice(['xml', 'gpl', 'acb', 'soc']), help='Only given format will be generated.') -def process(sets, format=''): - """ - ARGS: - pantone | ral | dulux | copic | prismacolor - """ - valid_sets = list(class_map.keys()) - - if len(sets) == 0: - sets = valid_sets - - for set in sets: - if set in valid_sets: - object = class_map[set]() - - if format != '': - make_palette = getattr(object, 'make_' + format, None) - make_palette() - else: - object.make_palettes() - else: - print('"' + set + '" isn\'t available. Please provide a valid color space,\nsuch as "pantone", "ral", "dulux", "copic" & "prismacolor".') - continue - - -if __name__ == '__main__': - cli() diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a3a2a7b..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -beautifulsoup4==4.7.1 -bs4==0.0.1 -lxml==4.3.3 -Pillow==6.2.0 -soupsieve==1.9.1 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..639cf59 --- /dev/null +++ b/setup.py @@ -0,0 +1,46 @@ +# ~*~ coding=utf-8 ~*~ + +import io +from os.path import abspath, dirname, join +from setuptools import find_packages, setup + + +VERSION = '1.0.0' + + +def long_description(): + readme_file = join(dirname(abspath(__file__)), 'README.md') + + with io.open(readme_file, encoding='utf8') as file: + return file.read() + + +setup( + name='we-love-colors', + description='PANTONE®, RAL®, Dulux®, Copic® and Prismacolor® color palettes for Scribus, GIMP & Inkscape, the Python way', + long_description=long_description(), + long_description_content_type='text/markdown', + version=VERSION, + license='MIT', + author='Martin Folkers', + author_email='hello@twobrain.io', + maintainer='Fundevogel', + maintainer_email='maschinenraum@fundevogel.de', + url='https://github.com/Fundevogel/we-love-colors', + project_urls={ + "Source code": "https://github.com/Fundevogel/we-love-colors", + "Issues": "https://github.com/Fundevogel/we-love-colors/issues", + }, + packages=find_packages(), + install_requires=[ + 'bs4', + 'click', + 'lxml', + 'pillow', + ], + entry_points=''' + [console_scripts] + colors=we_love_colors.cli:cli + ''', + python_requires='>=3.5', +) diff --git a/setup.sh b/setup.sh index c106c1e..8bd7e69 100755 --- a/setup.sh +++ b/setup.sh @@ -1,4 +1,21 @@ #!/bin/bash -# Setting up virtualenv & installing dependencies from `requirements.txt` -virtualenv -p python3 .env && source .env/bin/activate && pip install -r requirements.txt +# Setting up & activating virtualenv +virtualenv -p python3 .env +# shellcheck disable=SC1091 +source .env/bin/activate + +# Installing dependencies +pip install --editable . + +# Creating directory structure +cd palettes || exit + +for dir in copic \ + dulux \ + pantone \ + prismacolor \ + ral +do + mkdir -p "$dir" +done diff --git a/we_love_colors/cli.py b/we_love_colors/cli.py new file mode 100644 index 0000000..69ac52a --- /dev/null +++ b/we_love_colors/cli.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +## +# IMPORTS +# For more information, see https://www.python.org/dev/peps/pep-0008/#imports +## + +import click + +from .pantone import Pantone +from .ral import RAL +from .dulux import Dulux +from .copic import Copic +from .prismacolor import Prismacolor + + +CONTEXT_SETTINGS = dict( + help_option_names=['-h', '--help'], +) + + +class_map = { + 'pantone': Pantone, + 'ral': RAL, + 'dulux': Dulux, + 'copic': Copic, + 'prismacolor': Prismacolor, +} + + +@click.group(context_settings=CONTEXT_SETTINGS) +@click.version_option('1.0.0-beta.2', '-v', '--version') +def cli(): + pass + + +@cli.command() +@click.argument('brands', nargs=-1) +def fetch(brands): + """ + ARGS: + pantone | ral | dulux | copic | prismacolor + """ + all_sets = class_map.keys() + + if not brands: + brands = all_sets + + for brand in brands: + if brand in all_sets: + obj = class_map[brand]() + + try: + obj.fetch_all() + + except AttributeError: + obj.fetch() + + obj.save() + obj.create_json() + + else: + click.echo('"{}" not found. Please provide a valid brand name.'.format(brand)) + + +@cli.command() +@click.argument('brands', nargs=-1) +@click.option('-f', '--output-format', type=click.Choice(['xml', 'gpl', 'acb', 'soc']), help='Color palette format to be generated.') +def process(brands, output_format): + """ + ARGS: + pantone | ral | dulux | copic | prismacolor + """ + all_sets = class_map.keys() + + if not brands: + brands = all_sets + + for brand in brands: + if brand in all_sets: + obj = class_map[brand]() + + if output_format: + getattr(obj, 'make_' + output_format, None)() + + else: + obj.make_palettes() + + else: + click.echo('"{}" not found. Please provide a valid brand name.'.format(brand)) diff --git a/lib/copic.py b/we_love_colors/copic.py similarity index 98% rename from lib/copic.py rename to we_love_colors/copic.py index 6e9fd83..8496472 100644 --- a/lib/copic.py +++ b/we_love_colors/copic.py @@ -12,7 +12,7 @@ from urllib.request import urlopen from bs4 import BeautifulSoup -from palette import Palette +from .palette import Palette class Copic(Palette): diff --git a/lib/dulux.py b/we_love_colors/dulux.py similarity index 98% rename from lib/dulux.py rename to we_love_colors/dulux.py index 23ac671..57f3168 100644 --- a/lib/dulux.py +++ b/we_love_colors/dulux.py @@ -12,7 +12,7 @@ from urllib.request import urlopen from bs4 import BeautifulSoup -from palette import Palette +from .palette import Palette class Dulux(Palette): diff --git a/lib/helpers/nat_sort.py b/we_love_colors/helpers/nat_sort.py similarity index 100% rename from lib/helpers/nat_sort.py rename to we_love_colors/helpers/nat_sort.py diff --git a/palette.py b/we_love_colors/palette.py similarity index 100% rename from palette.py rename to we_love_colors/palette.py diff --git a/lib/pantone.py b/we_love_colors/pantone.py similarity index 99% rename from lib/pantone.py rename to we_love_colors/pantone.py index bf3689a..b5d05c7 100755 --- a/lib/pantone.py +++ b/we_love_colors/pantone.py @@ -12,8 +12,8 @@ from urllib.request import urlopen from bs4 import BeautifulSoup -from palette import Palette -from lib.helpers.nat_sort import natural_sort +from .palette import Palette +from .helpers.nat_sort import natural_sort class Pantone(Palette): diff --git a/lib/prismacolor.py b/we_love_colors/prismacolor.py similarity index 98% rename from lib/prismacolor.py rename to we_love_colors/prismacolor.py index 629e5f3..e5e2fa6 100644 --- a/lib/prismacolor.py +++ b/we_love_colors/prismacolor.py @@ -12,7 +12,7 @@ from urllib.request import urlopen from bs4 import BeautifulSoup -from palette import Palette +from .palette import Palette class Prismacolor(Palette): diff --git a/lib/ral.py b/we_love_colors/ral.py similarity index 99% rename from lib/ral.py rename to we_love_colors/ral.py index e35e640..74406bb 100755 --- a/lib/ral.py +++ b/we_love_colors/ral.py @@ -13,7 +13,7 @@ from bs4 import BeautifulSoup from PIL import ImageFile -from palette import Palette +from .palette import Palette class RAL(Palette):