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-play picto-blue"),
"ABORTING": ("Job aborting", "fas fa-play 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)