Skip to content

Commit

Permalink
Merge pull request #2335 from mkurek/async-transitions-2
Browse files Browse the repository at this point in the history
Added async fields to transition model
  • Loading branch information
mkurek committed Apr 1, 2016
2 parents 165af3b + 1684c08 commit edbfd52
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/ralph/lib/transitions/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ class CurrentTransitionsView(RalphDetailView):

def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
status_filter = dict(status__in=[JobStatus.FAILED, JobStatus.FINISHED])
jobs = TransitionJob.objects.filter(
content_type=ContentType.objects.get_for_model(self.object),
object_id=self.object.pk,
).exclude(status__in=[JobStatus.FAILED, JobStatus.FINISHED])
context['jobs'] = jobs
)
jobs_in_progress = jobs.exclude(**status_filter)
jobs_ended = jobs.filter(**status_filter)
context['jobs_in_progress'] = jobs_in_progress
context['jobs_ended'] = jobs_ended
context['are_jobs_running'] = any([j.is_running for j in jobs])
return context

Expand Down
41 changes: 40 additions & 1 deletion src/ralph/lib/transitions/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from django.utils.html import strip_tags
from django.utils.text import mark_safe
from django.utils.translation import ugettext_lazy as _
Expand All @@ -13,6 +14,9 @@


def wrap_action_name(action):
"""
Add additional information to action name (infotip, async icon).
"""
verbose_name = action.verbose_name
help_text = action.help_text
if help_text:
Expand All @@ -24,6 +28,13 @@ def wrap_action_name(action):
""".format(
txt=strip_tags(str(help_text)),
)
if action.is_async:
verbose_name = verbose_name + """
&nbsp;<i
data-tooltip
class="has-tip async fa fa-hourglass-half"
title='Asynchronous'></i>
"""
return mark_safe(verbose_name)


Expand All @@ -43,6 +54,13 @@ def __init__(self, *args, **kwargs):
TRANSITION_ORIGINAL_STATUS,
)
)
async_services = list(settings.RALPH_INTERNAL_SERVICES.keys())
self.fields['async_service_name'] = forms.ChoiceField(
choices=(
(('', '-------'),) + tuple(zip(async_services, async_services))
),
required=False,
)
actions_choices = [
(i.id, wrap_action_name(getattr(self.model, i.name)))
for i in Action.objects.filter(
Expand All @@ -60,6 +78,7 @@ def clean(self):
attachment_counter = 0
one_action = False
one_action_name = ''
any_async_action = False
actions_items = actions.items()
for k, v in actions_items:
action = getattr(self.model, v.name)
Expand All @@ -68,6 +87,7 @@ def clean(self):
if getattr(action, 'only_one_action', False):
one_action = True
one_action_name = getattr(action, 'verbose_name', '')
any_async_action |= action.is_async

if attachment_counter > 1:
msg = _(
Expand All @@ -82,8 +102,27 @@ def clean(self):
)
) % {'name': one_action_name}
self.add_error('actions', msg)
# check async options
if any_async_action and not cleaned_data['run_asynchronously']:
cleaned_data['run_asynchronously'] = True
if (
cleaned_data['run_asynchronously'] and
not cleaned_data.get('async_service_name')
):
msg = _(
'Please provide async service name for asynchronous transition'
)
if any_async_action:
msg = '{}{}'.format(
msg, _(' (At least one of chosen actions is asynchronous)')
)
self.add_error('async_service_name', msg)

return cleaned_data

class Meta:
model = Transition
fields = ['name', 'source', 'target', 'actions']
fields = [
'name', 'source', 'target', 'run_asynchronously',
'async_service_name', 'actions',
]
24 changes: 24 additions & 0 deletions src/ralph/lib/transitions/migrations/0006_auto_20160401_0842.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('transitions', '0005_auto_20160325_0817'),
]

operations = [
migrations.AddField(
model_name='transition',
name='run_asynchronously',
field=models.BooleanField(default=False, help_text='Run this transition in the background (this could be enforced if you choose at least one asynchronous action)'),
),
migrations.AlterField(
model_name='transition',
name='async_service_name',
field=models.CharField(max_length=100, default='ASYNC_TRANSITIONS', blank=True, help_text='Name of asynchronous (internal) service to run this transition. Fill this field only if you want to run this transition in the background.', null=True),
),
]
21 changes: 19 additions & 2 deletions src/ralph/lib/transitions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,21 @@ def __str__(self):
class Transition(models.Model):
name = models.CharField(max_length=50)
model = models.ForeignKey(TransitionModel)
async_service_name = models.CharField(max_length=100, blank=True, null=True)
run_asynchronously = models.BooleanField(
default=False,
help_text=_(
'Run this transition in the background (this could be enforced if '
'you choose at least one asynchronous action)'
)
)
async_service_name = models.CharField(
max_length=100, blank=True, null=True,
default=DEFAULT_ASYNC_TRANSITION_SERVICE_NAME, help_text=_(
'Name of asynchronous (internal) service to run this transition. '
'Fill this field only if you want to run this transition in the '
'background.'
)
)
source = JSONField()
target = models.CharField(max_length=50)
actions = models.ManyToManyField('Action')
Expand All @@ -437,7 +451,10 @@ def model_cls(self):

@property
def is_async(self):
return any([func.is_async for func in self.get_pure_actions()])
return (
self.run_asynchronously or
any([func.is_async for func in self.get_pure_actions()])
)

@classmethod
def transitions_for_model(cls, model, user=None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<thead>
<tr>
<th>{% trans "Job" %}</th>
<th>{% trans "User" %}</th>
{% if for_many_objects %}
<th>{% trans "Object" %}</th>
{% endif %}
Expand All @@ -14,7 +15,8 @@
<tbody>
{% for job in jobs %}
<tr>
<td>{{ job.transition.name }} [{{ job }}]</td>
<td>{{ job.transition.name }}</td>
<td>{{ job.user }}</td>
{% if for_many_objects %}
<td><a href="{{ job.obj.get_absolute_url }}">{{ job.obj }}</a></td>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
{% extends BASE_TEMPLATE %}
{% load i18n transitions_tags %}

{% block extrahead %}
{{ block.super }}
{% if are_jobs_running %}
<meta http-equiv="refresh" content="5">
{% endif %}
{% endblock %}

{% block view_content %}
{% include "transitions/_transition_jobs_table.html" %}
<h1>{% trans "Current transitions" %}</h1>
{% include "transitions/_transition_jobs_table.html" with jobs=job_in_progress %}

<h1>{% trans "Finished transitions" %}</h1>
{# TODO: add pagination etc #}
{% include "transitions/_transition_jobs_table.html" with jobs=jobs_ended %}

{% endblock %}
6 changes: 5 additions & 1 deletion src/ralph/lib/transitions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _

from ralph.admin.helpers import get_admin_url
from ralph.admin.mixins import RalphTemplateView
from ralph.admin.sites import ralph_site
from ralph.admin.widgets import AutocompleteWidget
Expand Down Expand Up @@ -207,7 +208,7 @@ def post(self, request, *args, **kwargs):

def get_async_transitions_awaiter_url(self, job_ids):
return '{}?{}'.format(
reverse('async_transitions_awaiter'),
reverse('async_bulk_transitions_awaiter'),
urlencode(MultiValueDict({'jobid': job_ids}))
)

Expand Down Expand Up @@ -251,6 +252,9 @@ def dispatch(
def get_success_url(self):
return self.objects[0].get_absolute_url()

def get_async_transitions_awaiter_url(self, job_ids):
return get_admin_url(self.objects[0], 'current_transitions')


class AsyncBulkTransitionsAwaiterView(RalphTemplateView):
template_name = 'transitions/async_transitions_awaiter.html'
Expand Down

0 comments on commit edbfd52

Please sign in to comment.