Skip to content

Commit

Permalink
Merge pull request #270 from nofusscomputing/feat-2024-09-11
Browse files Browse the repository at this point in the history
  • Loading branch information
jon-nfc authored Sep 12, 2024
2 parents ea5888f + 9942348 commit 9d8c894
Show file tree
Hide file tree
Showing 40 changed files with 947 additions and 217 deletions.
4 changes: 4 additions & 0 deletions app/api/serializers/core/ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,8 @@ def is_valid(self, *, raise_exception=True) -> bool:

self.validated_data['ticket_type'] = int(self._context['view']._ticket_type_value)

if self.instance is None:

self.validated_data['subscribed_users'] = self.validated_data['subscribed_users'] + [ self.validated_data['opened_by'] ]

return is_valid
5 changes: 5 additions & 0 deletions app/core/forms/ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ def __init__(self, request, *args, **kwargs):

self.fields['status'].choices = self.Meta.model.TicketStatus.ProjectTask

self._project: int = kwargs['initial']['project']

self.fields['project'].initial = self._project
self.fields['project'].widget = self.fields['project'].hidden_widget()

self.fields['ticket_type'].initial = self.Meta.model.TicketType.PROJECT_TASK.value

# self.fields['status'].widget = self.fields['status'].hidden_widget()
Expand Down
12 changes: 7 additions & 5 deletions app/core/forms/validate_ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,11 @@ def validate_request_ticket(self):

def validate_project_task_ticket(self):

# check status

# check type
if hasattr(self,'_project'):
self.cleaned_data.update({
'project': self._project
})

if self.cleaned_data['project'] is None:

# raise ValidationError('Test to see what it looks like')
pass
raise ValidationError('A project task requires a project')
113 changes: 113 additions & 0 deletions app/core/lib/markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import re

from markdown_it import MarkdownIt

from mdit_py_plugins import admon, anchors, footnote, tasklists

from pygments import highlight
from pygments.formatters.html import HtmlFormatter
from pygments.lexers import get_lexer_by_name

from django.template.loader import render_to_string

from .markdown_plugins import ticket_number



class Markdown:
"""Ticket and Comment markdown functions
Intended to be used for all areas of a tickets, projects and comments.
"""


def highlight_func(self, code: str, lang: str, _) -> str | None:
"""Use pygments for code high lighting"""

if not lang:

return None

lexer = get_lexer_by_name(lang)

formatter = HtmlFormatter(style='vs', cssclass='codehilite')

return highlight(code, lexer, formatter)


def render_markdown(self, markdown_text):
"""Render Markdown
implemented using https://markdown-it-py.readthedocs.io/en/latest/index.html
Args:
markdown_text (str): Markdown text
Returns:
str: HTML text
"""

md = (
MarkdownIt(
config = "commonmark",
options_update={
'linkify': True,
'highlight': self.highlight_func,
}
)

.enable([
'linkify',
'strikethrough',
'table',
])

.use(admon.admon_plugin)
.use(anchors.anchors_plugin, permalink=True)
.use(footnote.footnote_plugin)
.use(tasklists.tasklists_plugin)
.use(ticket_number.plugin, enabled=True)
)

return md.render(markdown_text)


def build_ticket_html(self, match):

ticket_id = match.group(1)

try:
if hasattr(self, 'ticket'):

ticket = self.ticket.__class__.objects.get(pk=ticket_id)

else:

ticket = self.__class__.objects.get(pk=ticket_id)

project_id = str('0')

if ticket.project:

project_id = str(ticket.project.id).lower()

context: dict = {
'id': ticket.id,
'name': ticket,
'ticket_type': str(ticket.get_ticket_type_display()).lower(),
'ticket_status': str(ticket.get_status_display()).lower(),
'project_id': project_id,
}

html_link = render_to_string('core/ticket/renderers/ticket_link.html.j2', context)

return str(html_link)
except:

return str('#' + ticket_id)



def ticket_reference(self, text):

return re.sub('#(\d+)', self.build_ticket_html, text)
103 changes: 103 additions & 0 deletions app/core/lib/markdown_plugins/ticket_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@

import re

from django.template.loader import render_to_string

from markdown_it import MarkdownIt
from markdown_it.rules_core import StateCore
from markdown_it.token import Token

# Regex string to match a whitespace character, as specified in
# https://github.github.com/gfm/#whitespace-character
# (spec version 0.29-gfm (2019-04-06))
_GFM_WHITESPACE_RE = r"[ \t\n\v\f\r]"


def plugin(
md: MarkdownIt,
enabled: bool = False,
) -> None:
"""markdown_it plugin to render ticket numbers
Placing `#<number>` within markdown will be rendered as a pretty link to the ticket.
Args:
md (MarkdownIt): markdown object
enabled (bool, optional): Enable the parsing of ticket references. Defaults to False.
Returns:
None: nada
"""

def main(state: StateCore) -> None:

tokens = state.tokens
for i in range(0, len(tokens) - 1):
if is_tag_item(tokens, i):
tag_render(tokens[i])


def is_inline(token: Token) -> bool:
return token.type == "inline"


def is_tag_item(tokens: list[Token], index: int) -> bool:

return (
is_inline(tokens[index])
and contains_tag_item(tokens[index])
)


def tag_html(match):

ticket_id = match.group(1)

try:
from core.models.ticket.ticket import Ticket

ticket = Ticket.objects.get(pk=ticket_id)

project_id = str('0')

if ticket.project:

project_id = str(ticket.project.id).lower()

context: dict = {
'id': ticket.id,
'name': ticket,
'ticket_type': str(ticket.get_ticket_type_display()).lower(),
'ticket_status': str(ticket.get_status_display()).lower(),
'project_id': project_id,
}

html_link = render_to_string('core/ticket/renderers/ticket_link.html.j2', context)

return html_link
except:

return str('#' + ticket_id)


def tag_render(token: Token) -> None:
assert token.children is not None

checkbox = Token("html_inline", "", 0)

checkbox.content = tag_replace(token.content)

token.children[0] = checkbox


def tag_replace(text):

return re.sub('#(\d+)', tag_html, text)

def contains_tag_item(token: Token) -> bool:

return re.match(rf"(.+)?#(\d+){_GFM_WHITESPACE_RE}?(.+)?", token.content) is not None

if enabled:

md.core.ruler.after("inline", "links", fn=main)
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Generated by Django 5.0.8 on 2024-09-10 07:30
# Generated by Django 5.0.8 on 2024-09-12 06:18

import access.fields
import access.models
import core.models.ticket.markdown
import core.models.ticket.ticket
import core.models.ticket.ticket_comment
import django.db.models.deletion
Expand Down Expand Up @@ -57,7 +56,6 @@ class Migration(migrations.Migration):
'permissions': [('add_ticket_request', 'Can add a request ticket'), ('change_ticket_request', 'Can change any request ticket'), ('delete_ticket_request', 'Can delete a request ticket'), ('import_ticket_request', 'Can import a request ticket'), ('purge_ticket_request', 'Can purge a request ticket'), ('triage_ticket_request', 'Can triage all request ticket'), ('view_ticket_request', 'Can view all request ticket'), ('add_ticket_incident', 'Can add a incident ticket'), ('change_ticket_incident', 'Can change any incident ticket'), ('delete_ticket_incident', 'Can delete a incident ticket'), ('import_ticket_incident', 'Can import a incident ticket'), ('purge_ticket_incident', 'Can purge a incident ticket'), ('triage_ticket_incident', 'Can triage all incident ticket'), ('view_ticket_incident', 'Can view all incident ticket'), ('add_ticket_problem', 'Can add a problem ticket'), ('change_ticket_problem', 'Can change any problem ticket'), ('delete_ticket_problem', 'Can delete a problem ticket'), ('import_ticket_problem', 'Can import a problem ticket'), ('purge_ticket_problem', 'Can purge a problem ticket'), ('triage_ticket_problem', 'Can triage all problem ticket'), ('view_ticket_problem', 'Can view all problem ticket'), ('add_ticket_change', 'Can add a change ticket'), ('change_ticket_change', 'Can change any change ticket'), ('delete_ticket_change', 'Can delete a change ticket'), ('import_ticket_change', 'Can import a change ticket'), ('purge_ticket_change', 'Can purge a change ticket'), ('triage_ticket_change', 'Can triage all change ticket'), ('view_ticket_change', 'Can view all change ticket'), ('add_ticket_project_task', 'Can add a project task'), ('change_ticket_project_task', 'Can change any project task'), ('delete_ticket_project_task', 'Can delete a project task'), ('import_ticket_project_task', 'Can import a project task'), ('purge_ticket_project_task', 'Can purge a project task'), ('triage_ticket_project_task', 'Can triage all project task'), ('view_ticket_project_task', 'Can view all project task')],
'unique_together': {('external_system', 'external_ref')},
},
bases=(models.Model, core.models.ticket.markdown.TicketMarkdown),
),
migrations.CreateModel(
name='RelatedTickets',
Expand Down Expand Up @@ -106,6 +104,5 @@ class Migration(migrations.Migration):
'ordering': ['ticket', 'parent_id'],
'unique_together': {('external_system', 'external_ref')},
},
bases=(models.Model, core.models.ticket.markdown.TicketMarkdown),
),
]
54 changes: 0 additions & 54 deletions app/core/models/ticket/markdown.py

This file was deleted.

Loading

0 comments on commit 9d8c894

Please sign in to comment.