Skip to content
This repository has been archived by the owner on May 28, 2018. It is now read-only.

Commit

Permalink
Extend docs
Browse files Browse the repository at this point in the history
  • Loading branch information
kmmbvnr committed Nov 3, 2016
1 parent 627bc12 commit 086fc37
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 65 deletions.
73 changes: 52 additions & 21 deletions viewflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@


class ThisObject(object):

"""Helper for forward references on flow tasks."""

def __init__(self, name):
def __init__(self, name): # noqa D102
self.name = name

@property
def owner(self):
"""Return same process finished task owner."""
"""Return user that was assogned to the task."""
def get_task_owner(activation):
flow_class = activation.process.flow_class
task_node = flow_class._meta.node(self.name)
Expand All @@ -26,41 +25,76 @@ def get_task_owner(activation):


class This(object):
"""Helper for building forward referenced flow task."""
"""Helper for building forward referenced flow task.
Therationaly is ability to specify referencies to the class
attribute and methods before they declated.
`this` is like a `self` but for the class body.
The referencies are resolved by the metaclass at the end of the
flow construction.
Example::
class MyFlow(Flow):
start = (
flow.StartFunction(this.start_flow)
.Next(this.task)
)
task = (
flow.View(MyView)
.Assign(this.start.owner)
.Next(this.end)
)
end = flow.End()
def start_flow(self, activation):
activation.prepare()
activation.done()
"""

def __getattr__(self, name):
return ThisObject(name)


class Edge(object):
"""Edge of the Flow graph."""

__slots__ = ('_src', '_dst', '_edge_class', '_label')

def __init__(self, src, dst, edge_class, label=None):
def __init__(self, src, dst, edge_class): # noqa D102
self._src = src
self._dst = dst
self._edge_class = edge_class
self._label = label

@property
def src(self):
"""Edge source node."""
return self._src

@property
def dst(self):
"""Edge destination node."""
return self._dst

@property
def edge_class(self):
return self._edge_class
"""Type of the edge.
@property
def label(self):
return self._label
Viewfow uses `next`, 'cond_true', `cond_false` and `defailt`
edge classes.
Edge class could be used as a hint for edge visualization.
"""
return self._edge_class

def __str__(self):
edge = "[%s] %s ---> %s" % (self._edge_class, self._src, self._dst)
if self._label:
edge += " (%s)" % self._label
return edge
return "[%s] %s ---> %s".format(
self._edge_class, self._src, self._dst)


class Node(object):
Expand All @@ -70,10 +104,11 @@ class Node(object):
:keyword task_type: Human readable task type
:keyword activation_class: Activation implementation specific for this node
"""

task_type = None
activation_class = None

def __init__(self, activation_class=None, **kwargs):
def __init__(self, activation_class=None, **kwargs): # noqa D102
self._incoming_edges = []

self.flow_class = None
Expand Down Expand Up @@ -115,21 +150,17 @@ def get_task_url(self, task, url_type, **kwargs):
"""Return url for the task."""

def activate(self, prev_activation, token):
"""Creates task activation."""
"""Create task activation."""
return self.activation_class.activate(self, prev_activation, token)


class Event(Node):

"""Base class for event-based tasks."""


class Task(Node):

"""Base class for tasks."""


class Gateway(Node):
"""
Base class for task gateways
"""
"""Base class for task gateways."""
2 changes: 2 additions & 0 deletions viewflow/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@


class ViewflowConfig(AppConfig):
"""Default Viewflow application config."""

icon = '<i class="material-icons">assignment</i>'
name = 'viewflow'
verbose_name = 'Workflow'
42 changes: 20 additions & 22 deletions viewflow/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
"""
Flow definition
"""
import re
from collections import defaultdict
from textwrap import dedent
Expand All @@ -12,10 +9,9 @@


class _Resolver(object):
"""
Resolver of task inter-links
"""
def __init__(self, nodes):
"""Resolver this-references over flow nodes."""

def __init__(self, nodes): # noqa
self.nodes = nodes # map name -> node instance

def get_implementation(self, link):
Expand All @@ -36,16 +32,16 @@ def get_implementation(self, link):


class FlowMeta(object):
"""
Flow options
"""
def __init__(self, app_label, flow_class, nodes):
"""Flow meta options."""

def __init__(self, app_label, flow_class, nodes): # noqa D102
self.app_label = app_label
self.flow_class = flow_class
self._nodes_by_name = nodes

@property
def flow_label(self):
"""Unique flow label."""
module = "{}.{}".format(self.flow_class.__module__, self.flow_class.__name__)
app_label, app_package = get_containing_app_data(module)

Expand All @@ -58,20 +54,18 @@ def flow_label(self):
return subpath.lower().replace('.', '/')

def nodes(self):
"""
Nodes iterator
"""
"""Iterator over all flow nodes."""
return self._nodes_by_name.values()

def node(self, name):
"""
Get node by name
"""
"""Get node by name."""
return self._nodes_by_name.get(name, None)


class FlowInstanceDescriptor(object):
def __init__(self):
"""Singleton flow instance descriptior."""

def __init__(self): # noqa D102
self.flow_instance = None

def __get__(self, instance=None, owner=None):
Expand All @@ -81,7 +75,10 @@ def __get__(self, instance=None, owner=None):


class FlowMetaClass(type):
"""Metaclass for all flows."""

def __new__(cls, class_name, bases, attrs):
"""Construct new flow class."""
new_class = super(FlowMetaClass, cls).__new__(cls, class_name, bases, attrs)

# singleton instance
Expand Down Expand Up @@ -164,14 +161,15 @@ def __new__(cls, class_name, bases, attrs):

class Flow(object, metaclass=FlowMetaClass):
"""
Base class for flow definition
Base class for flow definition.
:keyword process_class: Defines model class for Process
:keyword task_class: Defines model class for Task
:keyword management_form_class: Defines form class for task state tracking over GET requests
:keyword lock_impl: Locking implementation for flow
"""

process_class = models.Process
task_class = models.Task
management_form_class = forms.ActivationDataForm
Expand All @@ -184,9 +182,7 @@ class Flow(object, metaclass=FlowMetaClass):

@property
def urls(self):
"""
Provides ready to include urlpatterns required for this flow
"""
"""Buold urlpatterns list for all flow nodes."""
node_urls = []
for node in self._meta.nodes():
node_urls += node.urls()
Expand All @@ -195,11 +191,13 @@ def urls(self):

@property
def view_permission_name(self):
"""Name of the permission to view flow instances."""
opts = self.process_class._meta
return "{}.view_{}".format(opts.app_label, opts.model_name)

@property
def manage_permission_name(self):
"""Name of the permission to administer flow instances."""
opts = self.process_class._meta
return "{}.manage_{}".format(opts.app_label, opts.model_name)

Expand Down
Loading

0 comments on commit 086fc37

Please sign in to comment.