# HG changeset patch # User Goffi # Date 1611856304 -3600 # Node ID e3e303a30a74f0b032fb92175fb5ab5eca003759 # Parent 46ce79eac75490cae101afa61d43b9ecb4740b14 pages (tickets): renamed "tickets" to "lists": "lists" is more generic, and tickets is actually a specific kind of list. /!\ "tickets_trackers_json" option has been renamed to "lists_directory_json". diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/_browser/invitation.py --- a/libervia/pages/_browser/invitation.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/_browser/invitation.py Thu Jan 28 18:51:44 2021 +0100 @@ -3,7 +3,7 @@ from template import Template from dialog import notification from cache import cache -# we use JS RegExp because Python're is really long to import in Brython +# we use JS RegExp because Python's re is really long to import in Brython from javascript import RegExp bridge = Bridge() diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/events/page_meta.py --- a/libervia/pages/events/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/events/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -7,7 +7,7 @@ from sat.core.log import getLogger log = getLogger(__name__) -"""ticket handling pages""" + name = "events" access = C.PAGES_ACCESS_PUBLIC diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/lists/create/page_meta.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/lists/create/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + + +from libervia.server.constants import Const as C +from sat.tools.common import template_xmlui +from sat.tools.common import data_objects +from sat.tools.common import data_format +from sat.core.log import getLogger + +log = getLogger(__name__) + +name = "list_create" +access = C.PAGES_ACCESS_PUBLIC +template = "list/overview.html" + + +def parse_url(self, request): + self.getPathArgs(request, ["service", "node"], service="jid") + data = self.getRData(request) + service, node = data["service"], data["node"] + if node is None: + self.pageRedirect("lists_disco", request) + if node == "@": + node = data["node"] = "" + template_data = request.template_data + template_data["url_list_items"] = self.getURL(service.full(), node or "@") + template_data["url_list_new"] = self.getSubPageURL(request, "list_new") + + +async def prepare_render(self, request): + data = self.getRData(request) + template_data = request.template_data + service, node = data["service"], data["node"] + profile = self.getProfile(request) or C.SERVICE_PROFILE + + self.checkCache(request, C.CACHE_PUBSUB, service=service, node=node, short="tickets") + + extra = self.getPubsubExtra(request) + extra["labels_as_list"] = C.BOOL_TRUE + self.handleSearch(request, extra) + + list_data_raw = await self.host.bridgeCall( + "listGet", + service.full() if service else "", + node, + C.NO_LIMIT, + [], + "", + extra, + profile, + ) + list_items, metadata = data_format.deserialise(list_data_raw, type_check=list) + template_data["list_items"] = [template_xmlui.create(self.host, x) for x in + list_items] + template_data["on_list_item_click"] = data_objects.OnClick( + url=self.getSubPageURL(request, "list_view") + "/{item.id}" + ) + self.setPagination(request, metadata) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/lists/disco/page_meta.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/lists/disco/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + + +from libervia.server.constants import Const as C +from twisted.words.protocols.jabber import jid +from sat.core.log import getLogger + +log = getLogger(__name__) + +name = "lists_disco" +access = C.PAGES_ACCESS_PUBLIC +template = "list/discover.html" + + +def prepare_render(self, request): + lists_directory_config = self.host.options["lists_directory_json"] + if lists_directory_config: + trackers = request.template_data["lists_directory"] = [] + try: + for tracker_data in lists_directory_config: + service = tracker_data["service"] + node = tracker_data["node"] + name = tracker_data["name"] + url = self.getPageByName("lists").getURL(service, node) + trackers.append({"name": name, "url": url}) + except KeyError as e: + log.warning("Missing field in lists_directory_json: {msg}".format(msg=e)) + except Exception as e: + log.warning("Can't decode lists directory: {msg}".format(msg=e)) + + +def on_data_post(self, request): + jid_str = self.getPostedData(request, "jid") + try: + jid_ = jid.JID(jid_str) + except RuntimeError: + self.pageError(request, C.HTTP_BAD_REQUEST) + # for now we just use default node + url = self.getPageByName("lists").getURL(jid_.full(), "@") + self.HTTPRedirect(request, url) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/lists/edit/page_meta.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/lists/edit/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 + + +from libervia.server.constants import Const as C +from sat.core.i18n import _ +from twisted.internet import defer +from sat.tools.common import template_xmlui +from sat.tools.common import data_format +from sat.core.log import getLogger + +log = getLogger(__name__) + +name = "list_edit" +access = C.PAGES_ACCESS_PROFILE +template = "list/edit.html" + + +def parse_url(self, request): + try: + item_id = self.nextPath(request) + except IndexError: + log.warning(_("no list item id specified")) + self.pageError(request, C.HTTP_BAD_REQUEST) + + data = self.getRData(request) + data["list_item_id"] = item_id + + +@defer.inlineCallbacks +def prepare_render(self, request): + data = self.getRData(request) + template_data = request.template_data + service, node, list_item_id = ( + data.get("service", ""), + data.get("node", ""), + data["list_item_id"], + ) + profile = self.getProfile(request) + + # we don't ignore "author" below to keep it when a list item is edited + # by node owner/admin and "consistent publisher" is activated + ignore = ( + "publisher", + "author", + "author_jid", + "author_email", + "created", + "updated", + "comments_uri", + ) + list_raw = yield self.host.bridgeCall( + "listGet", + service.full() if service else "", + node, + C.NO_LIMIT, + [list_item_id], + "", + {}, + profile, + ) + list_items, metadata = data_format.deserialise(list_raw, type_check=list) + list_item = [template_xmlui.create(self.host, x, ignore=ignore) for x in list_items][0] + + try: + # small trick to get a one line text input instead of the big textarea + list_item.widgets["labels"].type = "string" + list_item.widgets["labels"].value = list_item.widgets["labels"].value.replace( + "\n", ", " + ) + except KeyError: + pass + + # for now we don't have XHTML editor, so we'll go with a TextBox and a convertion + # to a text friendly syntax using markdown + wid = list_item.widgets['body'] + if wid.type == "xhtmlbox": + wid.type = "textbox" + wid.value = yield self.host.bridgeCall( + "syntaxConvert", wid.value, C.SYNTAX_XHTML, "markdown", + False, profile) + + template_data["new_list_item_xmlui"] = list_item + + +@defer.inlineCallbacks +def on_data_post(self, request): + data = self.getRData(request) + service = data["service"] + node = data["node"] + list_item_id = data["list_item_id"] + posted_data = self.getAllPostedData(request) + if not posted_data["title"] or not posted_data["body"]: + self.pageError(request, C.HTTP_BAD_REQUEST) + try: + posted_data["labels"] = [l.strip() for l in posted_data["labels"][0].split(",")] + except (KeyError, IndexError): + pass + profile = self.getProfile(request) + + # we convert back body to XHTML + body = yield self.host.bridgeCall( + "syntaxConvert", posted_data['body'][0], "markdown", C.SYNTAX_XHTML, + False, profile) + posted_data['body'] = ['
{body}
'.format(ns=C.NS_XHTML, + body=body)] + + extra = {'update': True} + yield self.host.bridgeCall( + "listSet", service.full(), node, posted_data, "", list_item_id, + data_format.serialise(extra), profile + ) + # we don't want to redirect to edit page on success, but to list overview + data["post_redirect_page"] = ( + self.getPageByName("lists"), + service.full(), + node or "@", + ) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/lists/new/page_meta.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/lists/new/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +from libervia.server.constants import Const as C +from sat.tools.common import template_xmlui +from sat.core.log import getLogger + +log = getLogger(__name__) + + +name = "list_new" +access = C.PAGES_ACCESS_PROFILE +template = "list/create_item.html" + + +async def prepare_render(self, request): + data = self.getRData(request) + template_data = request.template_data + service, node = data.get("service", ""), data.get("node", "") + profile = self.getProfile(request) + schema = await self.host.bridgeCall("listSchemaGet", service.full(), node, profile) + data["schema"] = schema + # following fields are handled in backend + ignore = ( + "author", + "author_jid", + "author_email", + "created", + "updated", + "comments_uri", + "status", + "milestone", + "priority", + ) + xmlui_obj = template_xmlui.create(self.host, schema, ignore=ignore) + try: + # small trick to get a one line text input instead of the big textarea + xmlui_obj.widgets["labels"].type = "string" + except KeyError: + pass + + # same as for list_edit, we have to convert for now + wid = xmlui_obj.widgets['body'] + if wid.type == "xhtmlbox": + wid.type = "textbox" + wid.value = await self.host.bridgeCall( + "syntaxConvert", wid.value, C.SYNTAX_XHTML, "markdown", + False, profile) + template_data["new_list_item_xmlui"] = xmlui_obj + + +async def on_data_post(self, request): + data = self.getRData(request) + service = data["service"] + node = data["node"] + posted_data = self.getAllPostedData(request) + if not posted_data["title"] or not posted_data["body"]: + self.pageError(request, C.HTTP_BAD_REQUEST) + try: + posted_data["labels"] = [l.strip() for l in posted_data["labels"][0].split(",")] + except (KeyError, IndexError): + pass + profile = self.getProfile(request) + + # we convert back body to XHTML + body = await self.host.bridgeCall( + "syntaxConvert", posted_data['body'][0], "markdown", C.SYNTAX_XHTML, + False, profile) + posted_data['body'] = ['
{body}
'.format(ns=C.NS_XHTML, + body=body)] + + + await self.host.bridgeCall( + "listSet", service.full(), node, posted_data, "", "", "", profile + ) + # we don't want to redirect to creation page on success, but to list overview + data["post_redirect_page"] = ( + self.getPageByName("lists"), + service.full(), + node or "@", + ) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/lists/page_meta.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/lists/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +from libervia.server.constants import Const as C +from sat.tools.common import template_xmlui +from sat.tools.common import data_objects +from sat.tools.common import data_format +from sat.core.log import getLogger + +log = getLogger(__name__) + +name = "lists" +access = C.PAGES_ACCESS_PUBLIC +template = "list/overview.html" + + +def parse_url(self, request): + self.getPathArgs(request, ["service", "node"], service="jid") + data = self.getRData(request) + service, node = data["service"], data["node"] + if node is None: + self.pageRedirect("lists_disco", request) + if node == "@": + node = data["node"] = "" + template_data = request.template_data + template_data["url_list_items"] = self.getURL(service.full(), node or "@") + template_data["url_list_new"] = self.getSubPageURL(request, "list_new") + + +async def prepare_render(self, request): + data = self.getRData(request) + template_data = request.template_data + service, node = data["service"], data["node"] + profile = self.getProfile(request) or C.SERVICE_PROFILE + + self.checkCache(request, C.CACHE_PUBSUB, service=service, node=node, short="tickets") + + extra = self.getPubsubExtra(request) + extra["labels_as_list"] = C.BOOL_TRUE + self.handleSearch(request, extra) + + list_raw = await self.host.bridgeCall( + "listGet", + service.full() if service else "", + node, + C.NO_LIMIT, + [], + "", + extra, + profile, + ) + list_items, metadata = data_format.deserialise(list_raw, type_check=list) + template_data["list_items"] = [ + template_xmlui.create(self.host, x) for x in list_items + ] + template_data["on_list_item_click"] = data_objects.OnClick( + url=self.getSubPageURL(request, "list_view") + "/{item.id}" + ) + self.setPagination(request, metadata) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/lists/view/page_meta.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/lists/view/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + + +from libervia.server.constants import Const as C +from sat.core.i18n import _ +from libervia.server.utils import SubPage +from libervia.server import session_iface +from twisted.words.protocols.jabber import jid +from sat.tools.common import template_xmlui +from sat.tools.common import uri +from sat.tools.common import data_format +from sat.core.log import getLogger + +log = getLogger(__name__) + + +name = "list_view" +access = C.PAGES_ACCESS_PUBLIC +template = "list/item.html" + + +def parse_url(self, request): + try: + item_id = self.nextPath(request) + except IndexError: + log.warning(_("no list item id specified")) + self.pageError(request, C.HTTP_BAD_REQUEST) + + data = self.getRData(request) + data["list_item_id"] = item_id + + +async def prepare_render(self, request): + data = self.getRData(request) + template_data = request.template_data + session = self.host.getSessionData(request, session_iface.ISATSession) + service, node, list_item_id = ( + data.get("service", ""), + data.get("node", ""), + data["list_item_id"], + ) + profile = self.getProfile(request) + + if profile is None: + profile = C.SERVICE_PROFILE + + list_raw = await self.host.bridgeCall( + "listGet", + service.full() if service else "", + node, + C.NO_LIMIT, + [list_item_id], + "", + {"labels_as_list": C.BOOL_TRUE}, + profile, + ) + list_items, metadata = data_format.deserialise(list_raw, type_check=list) + list_item = [template_xmlui.create(self.host, x) for x in list_items][0] + template_data["item"] = list_item + comments_uri = list_item.widgets["comments_uri"].value + if comments_uri: + uri_data = uri.parseXMPPUri(comments_uri) + template_data["comments_node"] = comments_node = uri_data["node"] + template_data["comments_service"] = comments_service = uri_data["path"] + comments = data_format.deserialise(await self.host.bridgeCall( + "mbGet", comments_service, comments_node, C.NO_LIMIT, [], {}, profile + )) + + template_data["comments"] = comments + template_data["login_url"] = self.getPageRedirectURL(request) + + if session.connected: + # we set edition URL only if user is the publisher or the node owner + publisher = jid.JID(list_item.widgets["publisher"].value) + is_publisher = publisher.userhostJID() == session.jid.userhostJID() + affiliation = None + if not is_publisher: + node = node or self.host.ns_map["tickets"] + affiliation = await self.host.getAffiliation(request, service, node) + if is_publisher or affiliation == "owner": + template_data["url_list_item_edit"] = self.getURLByPath( + SubPage("lists"), + service.full(), + node or "@", + SubPage("list_edit"), + list_item_id, + ) + + # we add xmpp: URI + uri_args = {'path': service.full()} + uri_args['node'] = node or self.host.ns_map["tickets"] + if list_item_id: + uri_args['item'] = list_item_id + template_data['xmpp_uri'] = uri.buildXMPPUri('pubsub', **uri_args) + + +async def on_data_post(self, request): + type_ = self.getPostedData(request, "type") + if type_ == "comment": + blog_page = self.getPageByName("blog_view") + await blog_page.on_data_post(self, request) + else: + log.warning(_("Unhandled data type: {}").format(type_)) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/merge-requests/disco/page_meta.py --- a/libervia/pages/merge-requests/disco/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/merge-requests/disco/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -6,7 +6,7 @@ from sat.core.log import getLogger log = getLogger(__name__) -"""ticket handling pages""" + name = "merge-requests_disco" access = C.PAGES_ACCESS_PUBLIC diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/merge-requests/edit/page_meta.py --- a/libervia/pages/merge-requests/edit/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/merge-requests/edit/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -3,7 +3,6 @@ from libervia.server.constants import Const as C from sat.core.i18n import _ -from twisted.internet import defer from sat.tools.common import template_xmlui from sat.tools.common import data_format from sat.core.log import getLogger @@ -20,20 +19,20 @@ try: item_id = self.nextPath(request) except IndexError: - log.warning(_("no ticket id specified")) + log.warning(_("no list item id specified")) self.pageError(request, C.HTTP_BAD_REQUEST) data = self.getRData(request) - data["ticket_id"] = item_id + data["list_item_id"] = item_id async def prepare_render(self, request): data = self.getRData(request) template_data = request.template_data - service, node, ticket_id = ( + service, node, list_item_id = ( data.get("service", ""), data.get("node", ""), - data["ticket_id"], + data["list_item_id"], ) profile = self.getProfile(request) @@ -54,39 +53,41 @@ service.full() if service else "", node, C.NO_LIMIT, - [ticket_id], + [list_item_id], "", {}, profile, ) ) - ticket = template_xmlui.create(self.host, merge_requests['items'][0], ignore=ignore) + list_item = template_xmlui.create( + self.host, merge_requests['items'][0], ignore=ignore + ) try: # small trick to get a one line text input instead of the big textarea - ticket.widgets["labels"].type = "string" - ticket.widgets["labels"].value = ticket.widgets["labels"].value.replace( + list_item.widgets["labels"].type = "string" + list_item.widgets["labels"].value = list_item.widgets["labels"].value.replace( "\n", ", " ) except KeyError: pass - # same as tickets_edit - wid = ticket.widgets['body'] + # same as list_edit + wid = list_item.widgets['body'] if wid.type == "xhtmlbox": wid.type = "textbox" wid.value = await self.host.bridgeCall( "syntaxConvert", wid.value, C.SYNTAX_XHTML, "markdown", False, profile) - template_data["new_ticket_xmlui"] = ticket + template_data["new_list_item_xmlui"] = list_item async def on_data_post(self, request): data = self.getRData(request) service = data["service"] node = data["node"] - ticket_id = data["ticket_id"] + list_item_id = data["list_item_id"] posted_data = self.getAllPostedData(request) if not posted_data["title"] or not posted_data["body"]: self.pageError(request, C.HTTP_BAD_REQUEST) @@ -112,11 +113,11 @@ "auto", posted_data, "", - ticket_id, + list_item_id, data_format.serialise(extra), profile, ) - # we don't want to redirect to edit page on success, but to tickets list + # we don't want to redirect to edit page on success, but to list overview data["post_redirect_page"] = ( self.getPageByName("merge-requests"), service.full(), diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/merge-requests/new/page_meta.py --- a/libervia/pages/merge-requests/new/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/merge-requests/new/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -5,7 +5,7 @@ from sat.core.log import getLogger log = getLogger(__name__) -"""ticket handling pages""" + name = "merge-requests_new" access = C.PAGES_ACCESS_PUBLIC diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/merge-requests/page_meta.py --- a/libervia/pages/merge-requests/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/merge-requests/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -2,18 +2,17 @@ from libervia.server.constants import Const as C -from twisted.internet import defer from sat.tools.common import template_xmlui from sat.tools.common import data_format from sat.tools.common import data_objects from sat.core.log import getLogger log = getLogger(__name__) -"""ticket handling pages""" + name = "merge-requests" access = C.PAGES_ACCESS_PUBLIC -template = "ticket/overview.html" +template = "list/overview.html" def parse_url(self, request): @@ -28,10 +27,10 @@ request, C.CACHE_PUBSUB, service=service, node=node, short="merge-requests" ) template_data = request.template_data - template_data["url_tickets_list"] = self.getPageByName("merge-requests").getURL( + template_data["url_list_items"] = self.getPageByName("merge-requests").getURL( service.full(), node ) - template_data["url_tickets_new"] = self.getSubPageURL(request, "merge-requests_new") + template_data["url_list_new"] = self.getSubPageURL(request, "merge-requests_new") async def prepare_render(self, request): @@ -53,9 +52,9 @@ ) ) - template_data["tickets"] = [ + template_data["list_items"] = [ template_xmlui.create(self.host, x) for x in merge_requests['items'] ] - template_data["on_ticket_click"] = data_objects.OnClick( + template_data["on_list_item_click"] = data_objects.OnClick( url=self.getSubPageURL(request, "merge-requests_view") + "/{item.id}" ) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/merge-requests/view/page_meta.py --- a/libervia/pages/merge-requests/view/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/pages/merge-requests/view/page_meta.py Thu Jan 28 18:51:44 2021 +0100 @@ -5,7 +5,6 @@ from sat.core.i18n import _ from libervia.server.utils import SubPage from libervia.server import session_iface -from twisted.internet import defer from twisted.words.protocols.jabber import jid from sat.tools.common import template_xmlui from sat.tools.common import uri @@ -22,21 +21,21 @@ try: item_id = self.nextPath(request) except IndexError: - log.warning(_("no ticket id specified")) + log.warning(_("no list item id specified")) self.pageError(request, C.HTTP_BAD_REQUEST) data = self.getRData(request) - data["ticket_id"] = item_id + data["list_item_id"] = item_id async def prepare_render(self, request): data = self.getRData(request) template_data = request.template_data session = self.host.getSessionData(request, session_iface.ISATSession) - service, node, ticket_id = ( + service, node, list_item_id = ( data.get("service", ""), data.get("node", ""), - data["ticket_id"], + data["list_item_id"], ) profile = self.getProfile(request) @@ -49,18 +48,18 @@ service.full() if service else "", node, C.NO_LIMIT, - [ticket_id], + [list_item_id], "", {"parse": C.BOOL_TRUE, "labels_as_list": C.BOOL_TRUE}, profile, ) ) - ticket = template_xmlui.create( + list_item = template_xmlui.create( self.host, merge_requests['items'][0], ignore=["request_data", "type"] ) - template_data["item"] = ticket + template_data["item"] = list_item template_data["patches"] = merge_requests['items_patches'][0] - comments_uri = ticket.widgets["comments_uri"].value + comments_uri = list_item.widgets["comments_uri"].value if comments_uri: uri_data = uri.parseXMPPUri(comments_uri) template_data["comments_node"] = comments_node = uri_data["node"] @@ -73,19 +72,19 @@ if session.connected: # we set edition URL only if user is the publisher or the node owner - publisher = jid.JID(ticket.widgets["publisher"].value) + publisher = jid.JID(list_item.widgets["publisher"].value) is_publisher = publisher.userhostJID() == session.jid.userhostJID() affiliation = None if not is_publisher: node = node or self.host.ns_map["merge_requests"] affiliation = await self.host.getAffiliation(request, service, node) if is_publisher or affiliation == "owner": - template_data["url_ticket_edit"] = self.getURLByPath( + template_data["url_list_item_edit"] = self.getURLByPath( SubPage("merge-requests"), service.full(), node or "@", SubPage("merge-requests_edit"), - ticket_id, + list_item_id, ) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/tickets/disco/page_meta.py --- a/libervia/pages/tickets/disco/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - - -from libervia.server.constants import Const as C -from twisted.words.protocols.jabber import jid -from sat.core.log import getLogger - -log = getLogger(__name__) -"""ticket handling pages""" - -name = "tickets_disco" -access = C.PAGES_ACCESS_PUBLIC -template = "ticket/discover.html" - - -def prepare_render(self, request): - tickets_trackers_config = self.host.options["tickets_trackers_json"] - if tickets_trackers_config: - trackers = request.template_data["tickets_trackers"] = [] - try: - for tracker_data in tickets_trackers_config: - service = tracker_data["service"] - node = tracker_data["node"] - name = tracker_data["name"] - url = self.getPageByName("tickets").getURL(service, node) - trackers.append({"name": name, "url": url}) - except KeyError as e: - log.warning("Missing field in tickets_trackers_json: {msg}".format(msg=e)) - except Exception as e: - log.warning("Can't decode tickets trackers: {msg}".format(msg=e)) - - -def on_data_post(self, request): - jid_str = self.getPostedData(request, "jid") - try: - jid_ = jid.JID(jid_str) - except RuntimeError: - self.pageError(request, C.HTTP_BAD_REQUEST) - # for now we just use default node - url = self.getPageByName("tickets").getURL(jid_.full(), "@") - self.HTTPRedirect(request, url) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/tickets/edit/page_meta.py --- a/libervia/pages/tickets/edit/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -#!/usr/bin/env python3 - - -from libervia.server.constants import Const as C -from sat.core.i18n import _ -from twisted.internet import defer -from sat.tools.common import template_xmlui -from sat.tools.common import data_format -from sat.core.log import getLogger - -log = getLogger(__name__) -"""ticket handling pages""" - -name = "tickets_edit" -access = C.PAGES_ACCESS_PROFILE -template = "ticket/edit.html" - - -def parse_url(self, request): - try: - item_id = self.nextPath(request) - except IndexError: - log.warning(_("no ticket id specified")) - self.pageError(request, C.HTTP_BAD_REQUEST) - - data = self.getRData(request) - data["ticket_id"] = item_id - - -@defer.inlineCallbacks -def prepare_render(self, request): - data = self.getRData(request) - template_data = request.template_data - service, node, ticket_id = ( - data.get("service", ""), - data.get("node", ""), - data["ticket_id"], - ) - profile = self.getProfile(request) - - # we don't ignore "author" below to keep it when a ticket is edited - # by node owner/admin and "consistent publisher" is activated - ignore = ( - "publisher", - "author", - "author_jid", - "author_email", - "created", - "updated", - "comments_uri", - ) - tickets_raw = yield self.host.bridgeCall( - "ticketsGet", - service.full() if service else "", - node, - C.NO_LIMIT, - [ticket_id], - "", - {}, - profile, - ) - tickets, metadata = data_format.deserialise(tickets_raw, type_check=list) - ticket = [template_xmlui.create(self.host, x, ignore=ignore) for x in tickets][0] - - try: - # small trick to get a one line text input instead of the big textarea - ticket.widgets["labels"].type = "string" - ticket.widgets["labels"].value = ticket.widgets["labels"].value.replace( - "\n", ", " - ) - except KeyError: - pass - - # for now we don't have XHTML editor, so we'll go with a TextBox and a convertion - # to a text friendly syntax using markdown - wid = ticket.widgets['body'] - if wid.type == "xhtmlbox": - wid.type = "textbox" - wid.value = yield self.host.bridgeCall( - "syntaxConvert", wid.value, C.SYNTAX_XHTML, "markdown", - False, profile) - - template_data["new_ticket_xmlui"] = ticket - - -@defer.inlineCallbacks -def on_data_post(self, request): - data = self.getRData(request) - service = data["service"] - node = data["node"] - ticket_id = data["ticket_id"] - posted_data = self.getAllPostedData(request) - if not posted_data["title"] or not posted_data["body"]: - self.pageError(request, C.HTTP_BAD_REQUEST) - try: - posted_data["labels"] = [l.strip() for l in posted_data["labels"][0].split(",")] - except (KeyError, IndexError): - pass - profile = self.getProfile(request) - - # we convert back body to XHTML - body = yield self.host.bridgeCall( - "syntaxConvert", posted_data['body'][0], "markdown", C.SYNTAX_XHTML, - False, profile) - posted_data['body'] = ['
{body}
'.format(ns=C.NS_XHTML, - body=body)] - - extra = {'update': True} - yield self.host.bridgeCall( - "ticketSet", service.full(), node, posted_data, "", ticket_id, - data_format.serialise(extra), profile - ) - # we don't want to redirect to edit page on success, but to tickets list - data["post_redirect_page"] = ( - self.getPageByName("tickets"), - service.full(), - node or "@", - ) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/tickets/new/page_meta.py --- a/libervia/pages/tickets/new/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 - -from libervia.server.constants import Const as C -from twisted.internet import defer -from sat.tools.common import template_xmlui -from sat.core.log import getLogger - -log = getLogger(__name__) -"""ticket handling pages""" - -name = "tickets_new" -access = C.PAGES_ACCESS_PROFILE -template = "ticket/create.html" - - -async def prepare_render(self, request): - data = self.getRData(request) - template_data = request.template_data - service, node = data.get("service", ""), data.get("node", "") - profile = self.getProfile(request) - schema = await self.host.bridgeCall("ticketsSchemaGet", service.full(), node, profile) - data["schema"] = schema - # following fields are handled in backend - ignore = ( - "author", - "author_jid", - "author_email", - "created", - "updated", - "comments_uri", - "status", - "milestone", - "priority", - ) - xmlui_obj = template_xmlui.create(self.host, schema, ignore=ignore) - try: - # small trick to get a one line text input instead of the big textarea - xmlui_obj.widgets["labels"].type = "string" - except KeyError: - pass - - # same as for tickets_edit, we have to convert for now - wid = xmlui_obj.widgets['body'] - if wid.type == "xhtmlbox": - wid.type = "textbox" - wid.value = await self.host.bridgeCall( - "syntaxConvert", wid.value, C.SYNTAX_XHTML, "markdown", - False, profile) - template_data["new_ticket_xmlui"] = xmlui_obj - - -async def on_data_post(self, request): - data = self.getRData(request) - service = data["service"] - node = data["node"] - posted_data = self.getAllPostedData(request) - if not posted_data["title"] or not posted_data["body"]: - self.pageError(request, C.HTTP_BAD_REQUEST) - try: - posted_data["labels"] = [l.strip() for l in posted_data["labels"][0].split(",")] - except (KeyError, IndexError): - pass - profile = self.getProfile(request) - - # we convert back body to XHTML - body = await self.host.bridgeCall( - "syntaxConvert", posted_data['body'][0], "markdown", C.SYNTAX_XHTML, - False, profile) - posted_data['body'] = ['
{body}
'.format(ns=C.NS_XHTML, - body=body)] - - - await self.host.bridgeCall( - "ticketSet", service.full(), node, posted_data, "", "", "", profile - ) - # we don't want to redirect to creation page on success, but to tickets list - data["post_redirect_page"] = ( - self.getPageByName("tickets"), - service.full(), - node or "@", - ) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/tickets/page_meta.py --- a/libervia/pages/tickets/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 - - -from libervia.server.constants import Const as C -from sat.tools.common import template_xmlui -from sat.tools.common import data_objects -from sat.tools.common import data_format -from sat.core.log import getLogger - -log = getLogger(__name__) -"""ticket handling pages""" - -name = "tickets" -access = C.PAGES_ACCESS_PUBLIC -template = "ticket/overview.html" - - -def parse_url(self, request): - self.getPathArgs(request, ["service", "node"], service="jid") - data = self.getRData(request) - service, node = data["service"], data["node"] - if node is None: - self.pageRedirect("tickets_disco", request) - if node == "@": - node = data["node"] = "" - template_data = request.template_data - template_data["url_tickets_list"] = self.getURL(service.full(), node or "@") - template_data["url_tickets_new"] = self.getSubPageURL(request, "tickets_new") - - -async def prepare_render(self, request): - data = self.getRData(request) - template_data = request.template_data - service, node = data["service"], data["node"] - profile = self.getProfile(request) or C.SERVICE_PROFILE - - self.checkCache(request, C.CACHE_PUBSUB, service=service, node=node, short="tickets") - - extra = self.getPubsubExtra(request) - extra["labels_as_list"] = C.BOOL_TRUE - self.handleSearch(request, extra) - - tickets_data_raw = await self.host.bridgeCall( - "ticketsGet", - service.full() if service else "", - node, - C.NO_LIMIT, - [], - "", - extra, - profile, - ) - tickets, metadata = data_format.deserialise(tickets_data_raw, type_check=list) - template_data["tickets"] = [template_xmlui.create(self.host, x) for x in tickets] - template_data["on_ticket_click"] = data_objects.OnClick( - url=self.getSubPageURL(request, "tickets_view") + "/{item.id}" - ) - self.setPagination(request, metadata) diff -r 46ce79eac754 -r e3e303a30a74 libervia/pages/tickets/view/page_meta.py --- a/libervia/pages/tickets/view/page_meta.py Fri Dec 11 17:35:06 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 - - -from libervia.server.constants import Const as C -from sat.core.i18n import _ -from libervia.server.utils import SubPage -from libervia.server import session_iface -from twisted.internet import defer -from twisted.words.protocols.jabber import jid -from sat.tools.common import template_xmlui -from sat.tools.common import uri -from sat.tools.common import data_format -from sat.core.log import getLogger - -log = getLogger(__name__) -"""ticket handling pages""" - -name = "tickets_view" -access = C.PAGES_ACCESS_PUBLIC -template = "ticket/item.html" - - -def parse_url(self, request): - try: - item_id = self.nextPath(request) - except IndexError: - log.warning(_("no ticket id specified")) - self.pageError(request, C.HTTP_BAD_REQUEST) - - data = self.getRData(request) - data["ticket_id"] = item_id - - -async def prepare_render(self, request): - data = self.getRData(request) - template_data = request.template_data - session = self.host.getSessionData(request, session_iface.ISATSession) - service, node, ticket_id = ( - data.get("service", ""), - data.get("node", ""), - data["ticket_id"], - ) - profile = self.getProfile(request) - - if profile is None: - profile = C.SERVICE_PROFILE - - tickets_raw = await self.host.bridgeCall( - "ticketsGet", - service.full() if service else "", - node, - C.NO_LIMIT, - [ticket_id], - "", - {"labels_as_list": C.BOOL_TRUE}, - profile, - ) - tickets, metadata = data_format.deserialise(tickets_raw, type_check=list) - ticket = [template_xmlui.create(self.host, x) for x in tickets][0] - template_data["item"] = ticket - comments_uri = ticket.widgets["comments_uri"].value - if comments_uri: - uri_data = uri.parseXMPPUri(comments_uri) - template_data["comments_node"] = comments_node = uri_data["node"] - template_data["comments_service"] = comments_service = uri_data["path"] - comments = data_format.deserialise(await self.host.bridgeCall( - "mbGet", comments_service, comments_node, C.NO_LIMIT, [], {}, profile - )) - - template_data["comments"] = comments - template_data["login_url"] = self.getPageRedirectURL(request) - - if session.connected: - # we set edition URL only if user is the publisher or the node owner - publisher = jid.JID(ticket.widgets["publisher"].value) - is_publisher = publisher.userhostJID() == session.jid.userhostJID() - affiliation = None - if not is_publisher: - node = node or self.host.ns_map["tickets"] - affiliation = await self.host.getAffiliation(request, service, node) - if is_publisher or affiliation == "owner": - template_data["url_ticket_edit"] = self.getURLByPath( - SubPage("tickets"), - service.full(), - node or "@", - SubPage("tickets_edit"), - ticket_id, - ) - - -@defer.inlineCallbacks -def on_data_post(self, request): - type_ = self.getPostedData(request, "type") - if type_ == "comment": - blog_page = self.getPageByName("blog_view") - yield blog_page.on_data_post(self, request) - else: - log.warning(_("Unhandled data type: {}").format(type_)) diff -r 46ce79eac754 -r e3e303a30a74 libervia/server/constants.py --- a/libervia/server/constants.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/server/constants.py Thu Jan 28 18:51:44 2021 +0100 @@ -89,7 +89,7 @@ "photos", "files", "events", - "tickets", + "lists", "merge-requests", # XXX: app is not available anymore since removal of pyjamas code with Python 3 # port. It should come back at a later point with an alternative (Brython diff -r 46ce79eac754 -r e3e303a30a74 libervia/server/pages.py --- a/libervia/server/pages.py Fri Dec 11 17:35:06 2020 +0100 +++ b/libervia/server/pages.py Thu Jan 28 18:51:44 2021 +0100 @@ -726,7 +726,9 @@ continue if child_name == subpage_name: return path.decode('utf-8'), child - raise exceptions.NotFound(_("requested sub page has not been found")) + raise exceptions.NotFound( + _("requested sub page has not been found ({subpage_name})").format( + subpage_name=subpage_name)) def getSubPageURL(self, request, page_name, *args): """retrieve a page in direct children and build its URL according to request @@ -1786,7 +1788,11 @@ log.debug(f"using URI cache for {self}") cache_url.use(request) else: - await asDeferred(self.parse_url, self, request) + try: + await asDeferred(self.parse_url, self, request) + except Exception as e: + __import__('pudb').set_trace() + print(e) self._subpagesHandler(request) diff -r 46ce79eac754 -r e3e303a30a74 twisted/plugins/libervia_server.py --- a/twisted/plugins/libervia_server.py Fri Dec 11 17:35:06 2020 +0100 +++ b/twisted/plugins/libervia_server.py Thu Jan 28 18:51:44 2021 +0100 @@ -142,7 +142,7 @@ ["url_redirections_dict", None, {}, None], ["menu_json", None, {'': C.DEFAULT_MENU}, None], ["menu_extra_json", None, {}, None], - ["tickets_trackers_json", None, None, None], + ["lists_directory_json", None, None, None], ["mr_handlers_json", None, None, None], ]