diff --git a/.dockerignore b/.dockerignore index 2dd3e3a..1343350 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,9 +1,10 @@ * +!business_logic +!docs/requirements.txt +!manage.py +!README.* !requirements.* !setup.* -!tests !sites -!business_logic -!README.* -!manage.py +!tests sites/dev/db.sqlite3 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..14bb654 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,44 @@ +name: build docker demo image + +on: + push: + branches: + - master + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Prepare build-args + id: build-args + run: | + echo BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` >> $GITHUB_OUTPUT + echo VCS_REF=`git rev-parse --short HEAD` >> $GITHUB_OUTPUT + echo VERSION=`python -c 'from __future__ import print_function; import business_logic; print(business_logic.__version__)'` >> $GITHUB_OUTPUT + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + build-args: | + VCS_REF=${{ steps.build-args.outputs.VCS_REF }} + BUILD_DATE=${{ steps.build-args.outputs.BUILD_DATE }} + VERSION=${{ steps.build-args.outputs.VERSION }} + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: dgksu/django-business-logic:demo diff --git a/.gitignore b/.gitignore index 9e0f610..eeb6221 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ dist/ tests/reports/*.xml .python-version +.aider* diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..aa758fc --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +sphinx: + configuration: docs/conf.py + +python: + install: + - requirements: requirements.dev.txt diff --git a/Dockerfile b/Dockerfile index e0ff08e..51871ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ RUN apk add --no-cache libxslt && \ ADD . /app -RUN pip install -r requirements.dev.txt && \ +RUN pip install --no-cache-dir -r requirements.dev.txt && \ python setup.py install && \ apk del .build-deps diff --git a/business_logic/models/node.py b/business_logic/models/node.py index f7b0c5d..b3ffb68 100644 --- a/business_logic/models/node.py +++ b/business_logic/models/node.py @@ -18,11 +18,11 @@ class Node(NS_Node): """ Derived from `treebeard.NS_Node `_. - Holds structure of syntax tree. All objects are linked using the + Holds the structure of the syntax tree. All objects are linked using the `django contenttypes framework `_. Interprets code using the :func:`business_logic.models.Node.interpret` method. - Can acts as parent of code block if not contains content_object. - Can contains comment. + Can act as a parent of a code block if it does not contain a content_object. + Can contain a comment. See Also: * :class:`business_logic.models.NodeCache` @@ -54,7 +54,7 @@ def ensure_content_object_saved(**kwargs): @classmethod def add_root(cls, **kwargs): """ - Adds a root node to the tree. Saves content_objects if needed. + Adds a root node to the tree. Saves content_objects if necessary. Args: **kwargs: kwargs for :class:`business_logic.models.Node` constructor @@ -66,7 +66,7 @@ def add_root(cls, **kwargs): def add_child(self, **kwargs): """ - Adds a child to the node. Saves content_objects if needed. + Adds a child to the node. Saves content_objects if necessary. Args: **kwargs: kwargs for :class:`business_logic.models.Node` constructor @@ -79,7 +79,7 @@ def add_child(self, **kwargs): def delete(self): """ - Removes a node and all it’s descendants, and content_objects if needed. + Removes a node and all its descendants, and content_objects if necessary. """ if (self.object_id and self.content_object and self.content_type.app_label == ContentType.objects.get_for_model(self.__class__).app_label): @@ -92,10 +92,10 @@ def delete(self): def clone(self): """ - Creates a clone of entire tree starting from self + Creates a clone of the entire tree starting from self. Returns: - :class:`business_logic.models.Node`: root node of cloned tree + :class:`business_logic.models.Node`: root node of the cloned tree. """ class CloneVisitor(NodeVisitor): @@ -133,7 +133,7 @@ def visit(self, node): def interpret(self, ctx): """ - Interprets the held code. + Interprets the code held. Args: ctx(:class:`business_logic.models.Context`): execution context @@ -204,7 +204,7 @@ def is_content_object_interpret_children_itself(self): def pprint(self): """ - Prints entire tree starting from self to stdout. + Prints the entire tree starting from self to stdout. Utility function for development purposes. """ @@ -223,10 +223,10 @@ def visit(self, node): class NodeCache: """ - Creates cache with preloaded content objects for entire tree - on first call of get_children(). + Creates a cache with preloaded content objects for the entire tree + on the first call of get_children(). - Uses `1 + n` SQL queries, where n is count of used content types. + Uses `1 + n` SQL queries, where n is the count of used content types. """ def __init__(self): @@ -234,7 +234,7 @@ def __init__(self): def get_children(self, node): """ - Returns cached child nodes + Returns the cached child nodes. Args: node(:class:`business_logic.models.Node`): parent node @@ -285,11 +285,11 @@ def _initialize(self, node): class NodeCacheHolder(object): """ - Implements get_children() function using :class:`business_logic.models.NodeCache` + Implements the get_children() function using :class:`business_logic.models.NodeCache`. """ def get_children(self, node): """ - Returns cached child nodes + Returns the cached child nodes. Args: node(:class:`business_logic.models.Node`): parent node @@ -306,8 +306,8 @@ class NodeVisitor(NodeCacheHolder): """ Utility class for tree traversal. - Derived class should implement the :func:`business_logic.models.NodeVisitor.visit` method. - Traversal is made by executing :func:`business_logic.models.NodeVisitor.preorder` + The derived class should implement the :func:`business_logic.models.NodeVisitor.visit` method. + Traversal is made by executing the :func:`business_logic.models.NodeVisitor.preorder` or :func:`business_logic.models.NodeVisitor.postorder` method. Examples: @@ -316,7 +316,7 @@ class NodeVisitor(NodeCacheHolder): """ def visit(self, node, *args, **kwargs): """ - Main method which should be realised in derived classes + Main method which should be implemented in derived classes. Args: node(:class:`business_logic.models.Node`): currently processed node @@ -332,7 +332,7 @@ def preorder(self, node, *args, **kwargs): Tree traversal from top to bottom. Args: - node(:class:`business_logic.models.Node`): node for starting tree traversal + node(:class:`business_logic.models.Node`): node for starting the tree traversal *args: arbitrary args which should be passed to :func:`business_logic.models.NodeVisitor.visit` **kwargs: arbitrary kwargs which should be passed to :func:`business_logic.models.NodeVisitor.visit` """ @@ -345,7 +345,7 @@ def postorder(self, node, *args, **kwargs): Tree traversal from bottom to top. Args: - node(:class:`business_logic.models.Node`): node for starting tree traversal + node(:class:`business_logic.models.Node`): node for starting the tree traversal *args: arbitrary args which should be passed to :func:`business_logic.models.NodeVisitor.visit` **kwargs: arbitrary kwargs which should be passed to :func:`business_logic.models.NodeVisitor.visit` """ diff --git a/docs/requirements.in b/docs/requirements.in new file mode 100644 index 0000000..25bc842 --- /dev/null +++ b/docs/requirements.in @@ -0,0 +1,3 @@ +Sphinx==7.1.2 +sphinx_rtd_theme +Markdown<=3.4.4 diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..b060257 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,59 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile docs/requirements.in +# +alabaster==0.7.13 + # via sphinx +babel==2.12.1 + # via sphinx +certifi==2023.7.22 + # via requests +charset-normalizer==3.2.0 + # via requests +docutils==0.18.1 + # via + # sphinx + # sphinx-rtd-theme +idna==3.4 + # via requests +imagesize==1.4.1 + # via sphinx +jinja2==3.1.2 + # via sphinx +markdown==3.4.4 + # via -r docs/requirements.in +markupsafe==2.1.3 + # via jinja2 +packaging==23.1 + # via sphinx +pygments==2.16.1 + # via sphinx +requests==2.31.0 + # via sphinx +snowballstemmer==2.2.0 + # via sphinx +sphinx==7.1.2 + # via + # -r docs/requirements.in + # sphinx-rtd-theme + # sphinxcontrib-jquery +sphinx-rtd-theme==1.3.0 + # via -r docs/requirements.in +sphinxcontrib-applehelp==1.0.4 + # via sphinx +sphinxcontrib-devhelp==1.0.2 + # via sphinx +sphinxcontrib-htmlhelp==2.0.1 + # via sphinx +sphinxcontrib-jquery==4.1 + # via sphinx-rtd-theme +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.3 + # via sphinx +sphinxcontrib-serializinghtml==1.1.5 + # via sphinx +urllib3==2.0.4 + # via requests diff --git a/requirements.dev.txt b/requirements.dev.txt index 84cb2a1..9a7e0e9 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -1,10 +1,9 @@ -r requirements.test.txt +-r docs/requirements.txt Django>=3,<5 django-bootstrap3==23.4 flake8 pluggy>=0.12.0 -Sphinx -sphinx_rtd_theme nox twine wheel diff --git a/requirements.txt b/requirements.txt index 915a801..3f0c575 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -Markdown<=3.4.4 django-ace-overlay==0.8.0 #django-admin-sortable2==2.1.9 django-admin-sortable2>=1.0.4 @@ -6,5 +5,5 @@ django-filter==23.2 django-nested-admin==4.0.2 django-polymorphic==3.1.0 django-treebeard==4.7 -djangorestframework>=3.14.0 +djangorestframework>=3.14.0,<3.15.0 lxml<5.0 diff --git a/setup.py b/setup.py index a68589a..e76bfc1 100644 --- a/setup.py +++ b/setup.py @@ -8,9 +8,7 @@ from setuptools import setup from pip._internal.req import parse_requirements -from pip._internal.req.constructors import ( - install_req_from_parsed_requirement, - ) + PACKAGE = "business_logic" NAME = "django-business-logic"