import textwrap from django.contrib import messages from django.core.mail import mail_admins from django.core.urlresolvers import reverse, NoReverseMatch from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.translation import ungettext, ugettext_lazy as _ from orchestra import settings as orchestra_settings from orchestra.admin.utils import change_url def get_backends_help_text(backends): help_texts = {} for backend in backends: help_text = backend.__doc__ or '' context = { 'model': backend.model, 'related_models': str(backend.related_models), 'script_executable': backend.script_executable, 'script_method': '.'.join((backend.script_method.__module__, backend.script_method.__name__)), 'function_method': '.'.join((backend.function_method.__module__, backend.function_method.__name__)), 'actions': str(backend.actions), } help_text += textwrap.dedent(""" - Model: '%(model)s' - Related models: %(related_models)s - Script executable: %(script_executable)s - Script method: %(script_method)s - Function method: %(function_method)s - Actions: %(actions)s """ ) % context help_text = help_text.lstrip().splitlines() help_settings = [''] if backend.doc_settings: module, names = backend.doc_settings for name in names: value = getattr(module, name) if isinstance(value, str): help_settings.append("%s = '%s'" % (name, value)) else: help_settings.append("%s = %s" % (name, str(value))) help_text += help_settings help_texts[backend.get_name()] = '
'.join(help_text) return help_texts def get_instance_url(operation): try: url = change_url(operation.instance) except NoReverseMatch: alt_repr = '%s-%i' % (operation.content_type, operation.object_id) return _("Deleted {0}").format(operation.instance_repr or alt_repr) return orchestra_settings.ORCHESTRA_SITE_URL + url def send_report(method, args, log): server = args[0] backend = method.__self__.__class__.__name__ subject = '[Orchestra] %s execution %s on %s' % (backend, log.state, server) separator = "\n%s\n\n" % ('~ '*40,) operations = '\n'.join([' '.join((op.action, get_instance_url(op))) for op in log.operations.all()]) log_url = reverse('admin:orchestration_backendlog_change', args=(log.pk,)) log_url = orchestra_settings.ORCHESTRA_SITE_URL + log_url message = separator.join([ "[EXIT CODE] %s" % log.exit_code, "[STDERR]\n%s" % log.stderr, "[STDOUT]\n%s" % log.stdout, "[SCRIPT]\n%s" % log.script, "[TRACEBACK]\n%s" % log.traceback, "[OPERATIONS]\n%s" % operations, "[BACKEND LOG] %s" % log_url, ]) html_message = '\n\n'.join([ '

Exit code %s

' % log.exit_code, '

Stderr

' '
%s
' % escape(log.stderr), '

Stdout

' '
%s
' % escape(log.stdout), '

Script

' '
%s
' % escape(log.script), '

Traceback

' '
%s
' % escape(log.traceback), '

Operations

' '
%s
' % escape(operations), '

Backend log %s

' % (log_url, log_url), ]) mail_admins(subject, message, html_message=html_message) def get_backend_url(ids): if len(ids) == 1: return reverse('admin:orchestration_backendlog_change', args=ids) elif len(ids) > 1: url = reverse('admin:orchestration_backendlog_changelist') return url + '?id__in=%s' % ','.join(map(str, ids)) return '' def message_user(request, logs): total, successes, async = 0, 0, 0 ids = [] async_ids = [] for log in logs: total += 1 if log.state != log.EXCEPTION: # EXCEPTION logs are not stored on the database ids.append(log.pk) if log.is_success: successes += 1 elif not log.has_finished: async += 1 async_ids.append(log.id) errors = total-successes-async url = get_backend_url(ids) async_url = get_backend_url(async_ids) async_msg = '' if async: async_msg = ungettext( _('{async} backend is running on the background'), _('{async} backends are running on the background'), async) if errors: msg = ungettext( _('{errors} out of {total} backend has fail to execute'), _('{errors} out of {total} backends have fail to execute'), errors) if async_msg: msg += ', ' + str(async_msg) msg = msg.format(errors=errors, async=async, async_url=async_url, total=total, url=url) messages.error(request, mark_safe(msg + '.')) elif successes: if async_msg: msg = ungettext( _('{successes} out of {total} backend has been executed'), _('{successes} out of {total} backends have been executed'), successes) msg += ', ' + str(async_msg) else: msg = ungettext( _('{total} backend has been executed'), _('{total} backends have been executed'), total) msg = msg.format(total=total, url=url, async_url=async_url, async=async, successes=successes) messages.success(request, mark_safe(msg + '.')) else: msg = async_msg.format(url=url, async_url=async_url, async=async) messages.success(request, mark_safe(msg + '.'))