from datetime import datetime import json import shlex from django import template from django.utils.safestring import mark_safe from django.utils.timesince import timesince from misaka import Markdown, HtmlRenderer, EXT_SUPERSCRIPT, EXT_FENCED_CODE, EXT_AUTOLINK from main.models import Job register = template.Library() @register.filter(name='markdown') def markdown_filter(value): """ Convert markdown content into HTML. """ renderer = HtmlRenderer() markdown = Markdown( renderer, extensions=EXT_SUPERSCRIPT | EXT_FENCED_CODE ) return markdown.render(value) @register.filter(name='email2name') def email2name(email): """ Convert INRIA/IRISA emails into firstname name pattern """ value = email.split('@') if '.' in value[0]: data = value[0].split('.') contact = data[0] + ' ' + data[1] return email2name(contact.title()) else: return value[0].capitalize() @register.filter(name='fancy_webapp_name') def fancy_name(webapp_name): """ Replace underscores by spaces """ return webapp_name.replace('_', ' ') @register.filter(name='fancy_job_queue') def fancy_job_queue(queue): """Display the queue name with its timeout (if any)""" if queue.timeout is None: return queue.name if queue.timeout < 60: return "%s (<%d seconds)" % (queue.name, queue.timeout) else: return "%s (<%s)" % (queue.name, timesince( datetime.fromtimestamp(0), datetime.fromtimestamp(queue.timeout))) _JOB_STATUS_RENDER_VALUES = { "NEW": ("New job", "fas fa-plus picto-green"), "WAITING": ("Waiting job", "fas fa-clock picto-yellow"), "RUNNING": ("Job running", "fas fa-spinner fa-pulse picto-blue"), "ABORTING": ("Job aborting", "fas fa-spinner fa-pulse picto-yellow"), "SUCCESS": ("Job success", "fas fa-check picto-green"), "ERROR": ("Job error", "fas fa-times picto-red"), "ABORTED": ("Job aborted", "fas fa-hand-paper picto-orange"), "TIMEOUT": ("Job timeout", "fas fa-stopwatch picto-orange"), } @register.filter(name='status_icon') def status_icon(obj): """ Renders a status icon for a model """ def render_job_status(status): txt, cls = _JOB_STATUS_RENDER_VALUES.get(status, ("Unknown status", "fas fa-question")) return ('{txt}' .format(txt=txt, cls=cls)) if isinstance(obj, Job): return mark_safe(render_job_status(obj.status)) elif obj == "job-status-dict": return json.dumps({status: render_job_status(status) for status in _JOB_STATUS_RENDER_VALUES}) raise TypeError(type(obj)) @register.filter(name='command_multiline') def command_multiline(cmd): """Format a shell command over multiple lines (for display) `cmd` is the command to be formatted, provided as a list of strings (the actual arguments) or the `None` value (for inserting a newline). """ lst = [] sep = "" for arg in cmd: if arg is None: sep = "\n " else: lst.append(sep) lst.append(shlex.quote(arg)) sep = " " return "".join(lst) @register.filter(name='command_oneline') def command_oneline(cmd): """Format a shell command as a single line (for the clipboard) `cmd` is the command to be formatted, provided as a list of strings (the actual arguments) or the `None` value (for inserting a newline). This converter ignores the `None` elements, thus the command is formatted as a single line. """ return " ".join(shlex.quote(arg) for arg in cmd if arg is not None)