illustrate how lml can be used to construct a pure python api

This commit is contained in:
chfw 2017-05-10 01:29:43 +01:00
parent 8e935f2288
commit 7c52b6f7c4
46 changed files with 1275 additions and 18 deletions

View File

@ -162,7 +162,7 @@ Let's try it now::
$ robotchef "Jacket Potato"
I can bake Jacket Potato
Here is the code in `bake.py <https://github.com/chfw/lml/blob/master/examples/robotchef/robotchef_britishcuisine/robotchef_britishcuisine/bake.py>`_:
Here is the code in `bake.py <https://github.com/chfw/lml/blob/master/examples/robotchef_britishcuisine/robotchef_britishcuisine/bake.py>`_:
.. code-block:: python
:linenos:
@ -175,11 +175,10 @@ Here is the code in `bake.py <https://github.com/chfw/lml/blob/master/examples/r
def make(self, food=None):
print("I can bake " + food)
Nothing is special about `fry.py <https://github.com/chfw/lml/blob/master/examples/robotchef/robotchef_britishcuisine/robotchef_britishcuisine/fry.py>`_ either, so you can have a look at it by yourself.
Nothing is special about `fry.py <https://github.com/chfw/lml/blob/master/examples/robotchef_britishcuisine/robotchef_britishcuisine/fry.py>`_ either, so you can have a look at it by yourself.
Let me wrap up this section. All you will need to do, in order to make a standalone
plugin, is to provide a package installer(setup.py and other related package files)
for a built-in plugin.
plugin, is to provide a package installer(setup.py and other related package files) for a built-in plugin.
More standaline plugins
-------------------------

View File

@ -4,3 +4,9 @@ READ ME
A robot chef was created to master the cuisines around the world. It learns faster
than a human because it just requres a plugin to be installed. It consumes less
memory as it load the cuisine knowlege on demand.
Please note that there are two implementations of the robot chef. One is pure
command line interface(CLI) using lml directly; the other one is CLI using
robotchef_api package which uses lml. The former demonstrates how lml could
be used in a CLI package. The latter illustrates how to construct a pure
python library using lml.

View File

@ -1,7 +1 @@
from lml.loader import scan_plugins
BUILTINS = ['robotchef.robot_cuisine']
scan_plugins("robotchef_", __path__, white_list=BUILTINS)

View File

@ -1,23 +1,23 @@
import sys
import logging
import logging.config
from lml.loader import scan_plugins
from robotchef.plugin import CuisineManager
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.DEBUG)
BUILTINS = ['robotchef.robot_cuisine']
def main():
if len(sys.argv) < 2:
sys.exit(-1)
manager = CuisineManager()
cuisine_manager = CuisineManager()
scan_plugins("robotchef_", 'robotchef', white_list=BUILTINS)
food_name = sys.argv[1]
try:
knowledged_chef = manager.get_a_plugin(food_name)
print(knowledged_chef.make(food=food_name))
knowledged_chef = cuisine_manager.get_a_plugin(food_name)
knowledged_chef.make(food=food_name)
except Exception:
print("I do not know how to cook " + food_name)

95
examples/robotchef_api/.gitignore vendored Normal file
View File

@ -0,0 +1,95 @@
# April 2016
# reference: https://github.com/github/gitignore/blob/master/Python.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# 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/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
*~
commons/
commons
.moban.hashes

View File

@ -0,0 +1,33 @@
================================================================================
{{name}}
================================================================================
.. image:: https://api.travis-ci.org/{{organisation}}/{{name}}.svg?branch=master
:target: http://travis-ci.org/{{organisation}}/{{name}}
.. image:: https://codecov.io/github/{{organisation}}/{{name}}/coverage.png
:target: https://codecov.io/github/{{organisation}}/{{name}}
{%block documentation_link%}
.. image:: https://readthedocs.org/projects/{{name|lower}}/badge/?version=latest
:target: http://{{name|lower}}.readthedocs.org/en/latest/
{%endblock%}
Installation
================================================================================
You can install it via pip:
.. code-block:: bash
$ pip install {{name}}
or clone it and install it:
.. code-block:: bash
$ git clone http://github.com/{{organisation}}/{{name}}.git
$ cd {{name}}
$ python setup.py install

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
{%block additional_imports%}
{%endblock%}
DESCRIPTION = (
{% for i in range(0, description|length, 70) %}
'{{ description[i:(70+i)] }}' +
{% endfor %}
''
)
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
{%block SPHINX_EXTENSIONS%}
{%endblock%}
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'{{name}}'
copyright = u'{{copyright_year}} {{company}}'
version = '{{release}}'
release = '{{version}}'
exclude_patterns = []
pygments_style = 'sphinx'
{%block custom_doc_theme%}
html_theme = 'default'
{%endblock%}
html_static_path = ['_static']
htmlhelp_basename = '{{name}}doc'
latex_elements = {}
latex_documents = [
('index', '{{name}}.tex',
'{{name}} Documentation',
'{{company}}', 'manual'),
]
man_pages = [
('index', '{{name}}',
'{{name}} Documentation',
[u'{{company}}'], 1)
]
texinfo_documents = [
('index', '{{name}}',
'{{name}} Documentation',
'{{company}}', '{{name}}',
DESCRIPTION,
'Miscellaneous'),
]

View File

@ -0,0 +1,3 @@
{% for dependency in dependencies: %}
{{dependency}}
{% endfor %}

View File

@ -0,0 +1,172 @@
{% if external_module_library %}
from distutils.core import setup, Extension
{% else %}
try:
from setuptools import setup, find_packages
except ImportError:
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages
{%endif%}
{%block platform_block%}
from platform import python_implementation
{%endblock%}
{%block compat_block%}
import sys
PY2 = sys.version_info[0] == 2
PY26 = PY2 and sys.version_info[1] < 7
{%endblock%}
NAME = '{{name}}'
AUTHOR = '{{author}}'
VERSION = '{{version}}'
EMAIL = '{{contact}}'
LICENSE = '{{license}}'
{% if command_line_interface %}
ENTRY_POINTS = {
'console_scripts': [
'{{command_line_interface}} = {{ entry_point }}'
]
}
{% endif %}
DESCRIPTION = (
{% for i in range(0, description|length, 70) %}
'{{ description[i:(70+i)] }}' +
{% endfor %}
''
)
KEYWORDS = [
{%block additional_keywords%}
{%endblock%}
]
CLASSIFIERS = [
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
{%block additional_classifiers%}
{%endblock %}
]
{%macro handle_complex_dependency(complex_one) -%}
{%set dependency, condition = complex_one.split(';')%}
{% if condition == 'python_version<"3"'%}
if PY2:
{% endif %}
{% if condition == 'python_version>="3"'%}
if not PY2:
{% endif %}
{% if condition == 'python_version<"2.7"'%}
if PY26:
{% endif %}
{% if condition == 'platform_python_implementation=="PyPy"'%}
if python_implementation == "PyPy":
{%endif%}
INSTALL_REQUIRES.append('{{dependency}}')
{%- endmacro %}
INSTALL_REQUIRES = [
{% for dependency in dependencies: %}
{% if ';' not in dependency: %}
'{{dependency}}',
{% endif %}
{% endfor %}
]
{% for dependency in dependencies: %}
{% if ';' in dependency: %}
{{handle_complex_dependency(dependency)}}
{% endif %}
{% endfor %}
{% if external_module_library %}
PYMODULE = Extension(
'{{name}}',
sources=[
{% for source in sources: %}
'{{source}}',
{% endfor %}
],
libraries=INSTALL_REQUIRES
)
{% else %}
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
{% if extra_dependencies or dependencies: %}
EXTRAS_REQUIRE = {
{% for dependency in extra_dependencies: %}
{% for key, value in dependency.items(): %}
'{{key}}': {{value}},
{% endfor %}
{% endfor %}
}
{% else: %}
EXTRAS_REQUIRE = {}
{% endif %}
{% endif %}
def read_files(*files):
"""Read files into setup"""
text = ""
for single_file in files:
content = read(single_file)
text = text + content + "\n"
return text
def read(afile):
"""Read a file into setup"""
with open(afile, 'r') as opened_file:
content = filter_out_test_code(opened_file)
content = "".join(list(content))
return content
def filter_out_test_code(file_handle):
found_test_code = False
for line in file_handle.readlines():
if line.startswith('.. testcode:'):
found_test_code = True
continue
if found_test_code is True:
if line.startswith(' '):
continue
else:
empty_line = line.strip()
if len(empty_line) == 0:
continue
else:
found_test_code = False
yield line
else:
yield line
if __name__ == '__main__':
setup(
name=NAME,
author=AUTHOR,
version=VERSION,
author_email=EMAIL,
description=DESCRIPTION,
long_description=read_files('README.rst', 'CHANGELOG.rst'),
license=LICENSE,
keywords=KEYWORDS,
{% if external_module_library %}
ext_modules=[PYMODULE],
{% else %}
extras_require=EXTRAS_REQUIRE,
tests_require=['nose'],
install_requires=INSTALL_REQUIRES,
packages=PACKAGES,
include_package_data=True,
zip_safe=False,
{% if command_line_interface %}
entry_points=ENTRY_POINTS,
{% endif %}
{% endif%}
classifiers=CLASSIFIERS
)

View File

@ -0,0 +1,16 @@
{%block pretest%}
{%endblock%}
{%if external_module_library%}
{%set package=external_module_library%}
{%else%}
{%if command_line_interface%}
{%set package=command_line_interface + '_cli' %}
{%else%}
{%set package=name%}
{%endif%}
{%endif%}
pip freeze
nosetests --with-cov --cover-package {{package|lower}} --cover-package tests {%if not exclude_doctest%}--with-doctest --doctest-extension=.rst README.rst{%endif%} tests {%if not nodocs%}docs/source{%endif%} {%if not external_module_library%}{{package|lower}}{%endif%} && flake8 . --exclude=.moban.d {%block flake8_options%}--builtins=unicode,xrange,long{%endblock%}
{%block posttest%}
{%endblock%}

View File

@ -0,0 +1,6 @@
nose
codecov
coverage
flake8
{%block extras %}
{%endblock%}

View File

@ -0,0 +1,13 @@
configuration:
configuration_dir: "commons/config"
template_dir:
- "commons/templates"
- ".moban.d"
configuration: robotchef_api.yml
targets:
- README.rst: README.rst.jj2
- setup.py: setup.py.jj2
- requirements.txt: requirements.txt.jj2
- "tests/requirements.txt": "tests/requirements.txt.jj2"
- "docs/source/conf.py": "docs/source/conf.py.jj2"
- test.sh: test.sh.jj2

View File

@ -0,0 +1,18 @@
sudo: false
language: python
notifications:
email: false
python:
- 3.6
- 3.5
- 3.4
- 3.3
- 2.7
- 2.6
- pypy
before_install:
- pip install -r tests/requirements.txt
script:
- make test
after_success:
codecov

View File

@ -0,0 +1,2 @@
Change log
===========

View File

@ -0,0 +1,2 @@
include README.rst
include CHANGELOG.rst

View File

@ -0,0 +1,7 @@
all: test
test:
bash test.sh
document:
bash document.sh

View File

@ -0,0 +1,31 @@
================================================================================
robotchef_api
================================================================================
.. image:: https://api.travis-ci.org/chfw/robotchef_api.svg?branch=master
:target: http://travis-ci.org/chfw/robotchef_api
.. image:: https://codecov.io/github/chfw/robotchef_api/coverage.png
:target: https://codecov.io/github/chfw/robotchef_api
.. image:: https://readthedocs.org/projects/robotchef_api/badge/?version=latest
:target: http://robotchef_api.readthedocs.org/en/latest/
Installation
================================================================================
You can install it via pip:
.. code-block:: bash
$ pip install robotchef_api
or clone it and install it:
.. code-block:: bash
$ git clone http://github.com/chfw/robotchef_api.git
$ cd robotchef_api
$ python setup.py install

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
DESCRIPTION = (
'It provide the cusine knowledge to any library' +
''
)
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'robotchef_api'
copyright = u'2017 Onni Software Ltd.'
version = '0.0.1'
release = '0.0.1'
exclude_patterns = []
pygments_style = 'sphinx'
html_theme = 'default'
html_static_path = ['_static']
htmlhelp_basename = 'robotchef_apidoc'
latex_elements = {}
latex_documents = [
('index', 'robotchef_api.tex',
'robotchef_api Documentation',
'Onni Software Ltd.', 'manual'),
]
man_pages = [
('index', 'robotchef_api',
'robotchef_api Documentation',
[u'Onni Software Ltd.'], 1)
]
texinfo_documents = [
('index', 'robotchef_api',
'robotchef_api Documentation',
'Onni Software Ltd.', 'robotchef_api',
DESCRIPTION,
'Miscellaneous'),
]

View File

View File

@ -0,0 +1,11 @@
name: "robotchef_api"
organisation: "chfw"
author: "C.W."
contact: "wangc_2011 (at) hotmail.com"
company: "Onni Software Ltd."
version: "0.0.1"
release: "0.0.1"
copyright_year: 2017
license: MIT
dependencies: []
description: "It provide the cusine knowledge to any library"

View File

@ -0,0 +1,9 @@
from lml.loader import scan_plugins
from robotchef_api.plugin import CuisineManager
BUILTINS = ['robotchef.robot_cuisine']
scan_plugins("robotchef_", __path__, white_list=BUILTINS)
CUISINE_MANAGER = CuisineManager()

View File

@ -0,0 +1,15 @@
from lml.plugin import PluginManager
class CuisineManager(PluginManager):
def __init__(self):
PluginManager.__init__(self, "cuisine")
def get_a_plugin(self, food_name=None, **keywords):
return PluginManager.get_a_plugin(self, key=food_name, **keywords)
class Chef(object):
def make(self, **params):
print(self.name)

View File

@ -0,0 +1,96 @@
try:
from setuptools import setup, find_packages
except ImportError:
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages
from platform import python_implementation
import sys
PY2 = sys.version_info[0] == 2
PY26 = PY2 and sys.version_info[1] < 7
NAME = 'robotchef_api'
AUTHOR = 'C.W.'
VERSION = '0.0.1'
EMAIL = 'wangc_2011 (at) hotmail.com'
LICENSE = 'MIT'
DESCRIPTION = (
'It provide the cusine knowledge to any library' +
''
)
KEYWORDS = [
]
CLASSIFIERS = [
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
]
INSTALL_REQUIRES = [
]
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
EXTRAS_REQUIRE = {}
def read_files(*files):
"""Read files into setup"""
text = ""
for single_file in files:
content = read(single_file)
text = text + content + "\n"
return text
def read(afile):
"""Read a file into setup"""
with open(afile, 'r') as opened_file:
content = filter_out_test_code(opened_file)
content = "".join(list(content))
return content
def filter_out_test_code(file_handle):
found_test_code = False
for line in file_handle.readlines():
if line.startswith('.. testcode:'):
found_test_code = True
continue
if found_test_code is True:
if line.startswith(' '):
continue
else:
empty_line = line.strip()
if len(empty_line) == 0:
continue
else:
found_test_code = False
yield line
else:
yield line
if __name__ == '__main__':
setup(
name=NAME,
author=AUTHOR,
version=VERSION,
author_email=EMAIL,
description=DESCRIPTION,
long_description=read_files('README.rst', 'CHANGELOG.rst'),
license=LICENSE,
keywords=KEYWORDS,
extras_require=EXTRAS_REQUIRE,
tests_require=['nose'],
install_requires=INSTALL_REQUIRES,
packages=PACKAGES,
include_package_data=True,
zip_safe=False,
classifiers=CLASSIFIERS
)

View File

@ -0,0 +1,2 @@
pip freeze
nosetests --with-cov --cover-package robotchef_api --cover-package tests --with-doctest --doctest-extension=.rst README.rst tests docs/source robotchef_api && flake8 . --exclude=.moban.d --builtins=unicode,xrange,long

View File

@ -0,0 +1,4 @@
nose
codecov
coverage
flake8

95
examples/robotchef_v2/.gitignore vendored Normal file
View File

@ -0,0 +1,95 @@
# April 2016
# reference: https://github.com/github/gitignore/blob/master/Python.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# 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/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
*~
commons/
commons
.moban.hashes

View File

@ -0,0 +1,33 @@
================================================================================
{{name}}
================================================================================
.. image:: https://api.travis-ci.org/{{organisation}}/{{name}}.svg?branch=master
:target: http://travis-ci.org/{{organisation}}/{{name}}
.. image:: https://codecov.io/github/{{organisation}}/{{name}}/coverage.png
:target: https://codecov.io/github/{{organisation}}/{{name}}
{%block documentation_link%}
.. image:: https://readthedocs.org/projects/{{name|lower}}/badge/?version=latest
:target: http://{{name|lower}}.readthedocs.org/en/latest/
{%endblock%}
Installation
================================================================================
You can install it via pip:
.. code-block:: bash
$ pip install {{name}}
or clone it and install it:
.. code-block:: bash
$ git clone http://github.com/{{organisation}}/{{name}}.git
$ cd {{name}}
$ python setup.py install

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
{%block additional_imports%}
{%endblock%}
DESCRIPTION = (
{% for i in range(0, description|length, 70) %}
'{{ description[i:(70+i)] }}' +
{% endfor %}
''
)
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
{%block SPHINX_EXTENSIONS%}
{%endblock%}
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'{{name}}'
copyright = u'{{copyright_year}} {{company}}'
version = '{{release}}'
release = '{{version}}'
exclude_patterns = []
pygments_style = 'sphinx'
{%block custom_doc_theme%}
html_theme = 'default'
{%endblock%}
html_static_path = ['_static']
htmlhelp_basename = '{{name}}doc'
latex_elements = {}
latex_documents = [
('index', '{{name}}.tex',
'{{name}} Documentation',
'{{company}}', 'manual'),
]
man_pages = [
('index', '{{name}}',
'{{name}} Documentation',
[u'{{company}}'], 1)
]
texinfo_documents = [
('index', '{{name}}',
'{{name}} Documentation',
'{{company}}', '{{name}}',
DESCRIPTION,
'Miscellaneous'),
]

View File

@ -0,0 +1,3 @@
{% for dependency in dependencies: %}
{{dependency}}
{% endfor %}

View File

@ -0,0 +1,172 @@
{% if external_module_library %}
from distutils.core import setup, Extension
{% else %}
try:
from setuptools import setup, find_packages
except ImportError:
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages
{%endif%}
{%block platform_block%}
from platform import python_implementation
{%endblock%}
{%block compat_block%}
import sys
PY2 = sys.version_info[0] == 2
PY26 = PY2 and sys.version_info[1] < 7
{%endblock%}
NAME = '{{name}}'
AUTHOR = '{{author}}'
VERSION = '{{version}}'
EMAIL = '{{contact}}'
LICENSE = '{{license}}'
{% if command_line_interface %}
ENTRY_POINTS = {
'console_scripts': [
'{{command_line_interface}} = {{ entry_point }}'
]
}
{% endif %}
DESCRIPTION = (
{% for i in range(0, description|length, 70) %}
'{{ description[i:(70+i)] }}' +
{% endfor %}
''
)
KEYWORDS = [
{%block additional_keywords%}
{%endblock%}
]
CLASSIFIERS = [
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
{%block additional_classifiers%}
{%endblock %}
]
{%macro handle_complex_dependency(complex_one) -%}
{%set dependency, condition = complex_one.split(';')%}
{% if condition == 'python_version<"3"'%}
if PY2:
{% endif %}
{% if condition == 'python_version>="3"'%}
if not PY2:
{% endif %}
{% if condition == 'python_version<"2.7"'%}
if PY26:
{% endif %}
{% if condition == 'platform_python_implementation=="PyPy"'%}
if python_implementation == "PyPy":
{%endif%}
INSTALL_REQUIRES.append('{{dependency}}')
{%- endmacro %}
INSTALL_REQUIRES = [
{% for dependency in dependencies: %}
{% if ';' not in dependency: %}
'{{dependency}}',
{% endif %}
{% endfor %}
]
{% for dependency in dependencies: %}
{% if ';' in dependency: %}
{{handle_complex_dependency(dependency)}}
{% endif %}
{% endfor %}
{% if external_module_library %}
PYMODULE = Extension(
'{{name}}',
sources=[
{% for source in sources: %}
'{{source}}',
{% endfor %}
],
libraries=INSTALL_REQUIRES
)
{% else %}
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
{% if extra_dependencies or dependencies: %}
EXTRAS_REQUIRE = {
{% for dependency in extra_dependencies: %}
{% for key, value in dependency.items(): %}
'{{key}}': {{value}},
{% endfor %}
{% endfor %}
}
{% else: %}
EXTRAS_REQUIRE = {}
{% endif %}
{% endif %}
def read_files(*files):
"""Read files into setup"""
text = ""
for single_file in files:
content = read(single_file)
text = text + content + "\n"
return text
def read(afile):
"""Read a file into setup"""
with open(afile, 'r') as opened_file:
content = filter_out_test_code(opened_file)
content = "".join(list(content))
return content
def filter_out_test_code(file_handle):
found_test_code = False
for line in file_handle.readlines():
if line.startswith('.. testcode:'):
found_test_code = True
continue
if found_test_code is True:
if line.startswith(' '):
continue
else:
empty_line = line.strip()
if len(empty_line) == 0:
continue
else:
found_test_code = False
yield line
else:
yield line
if __name__ == '__main__':
setup(
name=NAME,
author=AUTHOR,
version=VERSION,
author_email=EMAIL,
description=DESCRIPTION,
long_description=read_files('README.rst', 'CHANGELOG.rst'),
license=LICENSE,
keywords=KEYWORDS,
{% if external_module_library %}
ext_modules=[PYMODULE],
{% else %}
extras_require=EXTRAS_REQUIRE,
tests_require=['nose'],
install_requires=INSTALL_REQUIRES,
packages=PACKAGES,
include_package_data=True,
zip_safe=False,
{% if command_line_interface %}
entry_points=ENTRY_POINTS,
{% endif %}
{% endif%}
classifiers=CLASSIFIERS
)

View File

@ -0,0 +1,16 @@
{%block pretest%}
{%endblock%}
{%if external_module_library%}
{%set package=external_module_library%}
{%else%}
{%if command_line_interface%}
{%set package=command_line_interface + '_cli' %}
{%else%}
{%set package=name%}
{%endif%}
{%endif%}
pip freeze
nosetests --with-cov --cover-package {{package|lower}} --cover-package tests {%if not exclude_doctest%}--with-doctest --doctest-extension=.rst README.rst{%endif%} tests {%if not nodocs%}docs/source{%endif%} {%if not external_module_library%}{{package|lower}}{%endif%} && flake8 . --exclude=.moban.d {%block flake8_options%}--builtins=unicode,xrange,long{%endblock%}
{%block posttest%}
{%endblock%}

View File

@ -0,0 +1,6 @@
nose
codecov
coverage
flake8
{%block extras %}
{%endblock%}

View File

@ -0,0 +1,13 @@
configuration:
configuration_dir: "commons/config"
template_dir:
- "commons/templates"
- ".moban.d"
configuration: robotchef_v2.yml
targets:
- README.rst: README.rst.jj2
- setup.py: setup.py.jj2
- requirements.txt: requirements.txt.jj2
- "tests/requirements.txt": "tests/requirements.txt.jj2"
- "docs/source/conf.py": "docs/source/conf.py.jj2"
- test.sh: test.sh.jj2

View File

@ -0,0 +1,18 @@
sudo: false
language: python
notifications:
email: false
python:
- 3.6
- 3.5
- 3.4
- 3.3
- 2.7
- 2.6
- pypy
before_install:
- pip install -r tests/requirements.txt
script:
- make test
after_success:
codecov

View File

@ -0,0 +1,2 @@
Change log
===========

View File

@ -0,0 +1,2 @@
include README.rst
include CHANGELOG.rst

View File

@ -0,0 +1,7 @@
all: test
test:
bash test.sh
document:
bash document.sh

View File

@ -0,0 +1,31 @@
================================================================================
robotchef_v2
================================================================================
.. image:: https://api.travis-ci.org/chfw/robotchef_v2.svg?branch=master
:target: http://travis-ci.org/chfw/robotchef_v2
.. image:: https://codecov.io/github/chfw/robotchef_v2/coverage.png
:target: https://codecov.io/github/chfw/robotchef_v2
.. image:: https://readthedocs.org/projects/robotchef_v2/badge/?version=latest
:target: http://robotchef_v2.readthedocs.org/en/latest/
Installation
================================================================================
You can install it via pip:
.. code-block:: bash
$ pip install robotchef_v2
or clone it and install it:
.. code-block:: bash
$ git clone http://github.com/chfw/robotchef_v2.git
$ cd robotchef_v2
$ python setup.py install

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
DESCRIPTION = (
'It understands world cuisine' +
''
)
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'robotchef_v2'
copyright = u'2017 Onni Software Ltd.'
version = '0.0.1'
release = '0.0.1'
exclude_patterns = []
pygments_style = 'sphinx'
html_theme = 'default'
html_static_path = ['_static']
htmlhelp_basename = 'robotchef_v2doc'
latex_elements = {}
latex_documents = [
('index', 'robotchef_v2.tex',
'robotchef_v2 Documentation',
'Onni Software Ltd.', 'manual'),
]
man_pages = [
('index', 'robotchef_v2',
'robotchef_v2 Documentation',
[u'Onni Software Ltd.'], 1)
]
texinfo_documents = [
('index', 'robotchef_v2',
'robotchef_v2 Documentation',
'Onni Software Ltd.', 'robotchef_v2',
DESCRIPTION,
'Miscellaneous'),
]

View File

View File

@ -0,0 +1,13 @@
name: "robotchef_v2"
organisation: "chfw"
author: "C.W."
contact: "wangc_2011 (at) hotmail.com"
company: "Onni Software Ltd."
version: "0.0.1"
release: "0.0.1"
copyright_year: 2017
command_line_interface: "robotchef_v2"
entry_point: "robotchef_v2.main:main"
license: MIT
dependencies: []
description: "It understands world cuisine"

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,15 @@
import sys
from robotchef_api import CUISINE_MANAGER
def main():
if len(sys.argv) < 2:
sys.exit(-1)
food_name = sys.argv[1]
try:
knowledged_chef = CUISINE_MANAGER.get_a_plugin(food_name)
knowledged_chef.make(food=food_name)
except Exception:
print("I do not know how to cook " + food_name)

View File

@ -0,0 +1,102 @@
try:
from setuptools import setup, find_packages
except ImportError:
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages
from platform import python_implementation
import sys
PY2 = sys.version_info[0] == 2
PY26 = PY2 and sys.version_info[1] < 7
NAME = 'robotchef_v2'
AUTHOR = 'C.W.'
VERSION = '0.0.1'
EMAIL = 'wangc_2011 (at) hotmail.com'
LICENSE = 'MIT'
ENTRY_POINTS = {
'console_scripts': [
'robotchef_v2 = robotchef_v2.main:main'
]
}
DESCRIPTION = (
'It understands world cuisine' +
''
)
KEYWORDS = [
]
CLASSIFIERS = [
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
]
INSTALL_REQUIRES = [
]
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
EXTRAS_REQUIRE = {}
def read_files(*files):
"""Read files into setup"""
text = ""
for single_file in files:
content = read(single_file)
text = text + content + "\n"
return text
def read(afile):
"""Read a file into setup"""
with open(afile, 'r') as opened_file:
content = filter_out_test_code(opened_file)
content = "".join(list(content))
return content
def filter_out_test_code(file_handle):
found_test_code = False
for line in file_handle.readlines():
if line.startswith('.. testcode:'):
found_test_code = True
continue
if found_test_code is True:
if line.startswith(' '):
continue
else:
empty_line = line.strip()
if len(empty_line) == 0:
continue
else:
found_test_code = False
yield line
else:
yield line
if __name__ == '__main__':
setup(
name=NAME,
author=AUTHOR,
version=VERSION,
author_email=EMAIL,
description=DESCRIPTION,
long_description=read_files('README.rst', 'CHANGELOG.rst'),
license=LICENSE,
keywords=KEYWORDS,
extras_require=EXTRAS_REQUIRE,
tests_require=['nose'],
install_requires=INSTALL_REQUIRES,
packages=PACKAGES,
include_package_data=True,
zip_safe=False,
entry_points=ENTRY_POINTS,
classifiers=CLASSIFIERS
)

View File

@ -0,0 +1,2 @@
pip freeze
nosetests --with-cov --cover-package robotchef_v2_cli --cover-package tests --with-doctest --doctest-extension=.rst README.rst tests docs/source robotchef_v2_cli && flake8 . --exclude=.moban.d --builtins=unicode,xrange,long

View File

@ -0,0 +1,4 @@
nose
codecov
coverage
flake8