comparison libervia/pages/lists/view/page_meta.py @ 1387:a84383c659b4

lists: creation, invitation, item deletion: this big patch includes: - reorganisation of pages for consistency, discovery is now the main list page, and list overview is now in `view` while item view is moved to `view_item` - lists from lists of interest are now shown in discovery page - list deletion from discory page - list can now be created, using templates now available from backend - invitation manager can now be used from list overview - list item can now be deleted from `view_item`
author Goffi <goffi@goffi.org>
date Sat, 20 Feb 2021 14:07:22 +0100
parents libervia/pages/lists/page_meta.py@e3e303a30a74
children ac4173fff71d
comparison
equal deleted inserted replaced
1386:83be300d17e3 1387:a84383c659b4
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 2
3
4 from libervia.server.constants import Const as C
5 from sat.core.i18n import _
6 from libervia.server.utils import SubPage
7 from libervia.server import session_iface
8 from twisted.words.protocols.jabber import jid
9 from sat.tools.common import template_xmlui 3 from sat.tools.common import template_xmlui
10 from sat.tools.common import uri 4 from sat.tools.common import data_objects
11 from sat.tools.common import data_format 5 from sat.tools.common import data_format
12 from sat.core.log import getLogger 6 from sat.core.log import getLogger
7 from sat_frontends.bridge.bridge_frontend import BridgeException
8 from libervia.server.constants import Const as C
13 9
14 log = getLogger(__name__) 10 log = getLogger(__name__)
15 11
16 12 name = "lists"
17 name = "list_view"
18 access = C.PAGES_ACCESS_PUBLIC 13 access = C.PAGES_ACCESS_PUBLIC
19 template = "list/item.html" 14 template = "list/overview.html"
20 15
21 16
22 def parse_url(self, request): 17 def parse_url(self, request):
23 try: 18 self.getPathArgs(request, ["service", "node"], service="jid")
24 item_id = self.nextPath(request)
25 except IndexError:
26 log.warning(_("no list item id specified"))
27 self.pageError(request, C.HTTP_BAD_REQUEST)
28
29 data = self.getRData(request) 19 data = self.getRData(request)
30 data["list_item_id"] = item_id 20 service, node = data["service"], data["node"]
21 if node is None:
22 self.HTTPRedirect(request, self.getPageByName("lists_disco").url)
23 if node == "@":
24 node = data["node"] = ""
25 template_data = request.template_data
26 template_data["url_list_items"] = self.getURL(service.full(), node or "@")
27 template_data["url_list_new"] = self.getPageByName("list_new").getURL(
28 service.full(), node or "@")
31 29
32 30
33 async def prepare_render(self, request): 31 async def prepare_render(self, request):
34 data = self.getRData(request) 32 data = self.getRData(request)
35 template_data = request.template_data 33 template_data = request.template_data
36 session = self.host.getSessionData(request, session_iface.ISATSession) 34 service, node = data["service"], data["node"]
37 service, node, list_item_id = ( 35 profile = self.getProfile(request) or C.SERVICE_PROFILE
38 data.get("service", ""),
39 data.get("node", ""),
40 data["list_item_id"],
41 )
42 profile = self.getProfile(request)
43 36
44 if profile is None: 37 self.checkCache(request, C.CACHE_PUBSUB, service=service, node=node, short="tickets")
45 profile = C.SERVICE_PROFILE 38
39 extra = self.getPubsubExtra(request)
40 extra["labels_as_list"] = C.BOOL_TRUE
41 self.handleSearch(request, extra)
46 42
47 list_raw = await self.host.bridgeCall( 43 list_raw = await self.host.bridgeCall(
48 "listGet", 44 "listGet",
49 service.full() if service else "", 45 service.full() if service else "",
50 node, 46 node,
51 C.NO_LIMIT, 47 C.NO_LIMIT,
52 [list_item_id], 48 [],
53 "", 49 "",
54 {"labels_as_list": C.BOOL_TRUE}, 50 extra,
55 profile, 51 profile,
56 ) 52 )
53 if profile != C.SERVICE_PROFILE:
54 try:
55 affiliations = await self.host.bridgeCall(
56 "psNodeAffiliationsGet",
57 service.full() if service else "",
58 node,
59 profile
60 )
61 except BridgeException as e:
62 log.warning(f"Can't get affiliations for node {node!r} at {service}: {e}")
63 template_data["owner"] = False
64 else:
65 is_owner = affiliations.get(self.getJid(request).userhost()) == 'owner'
66 template_data["owner"] = is_owner
67 if is_owner:
68 self.exposeToScripts(
69 request,
70 affiliations={str(e): str(a) for e, a in affiliations.items()}
71 )
72 else:
73 template_data["owner"] = False
74
57 list_items, metadata = data_format.deserialise(list_raw, type_check=list) 75 list_items, metadata = data_format.deserialise(list_raw, type_check=list)
58 list_item = [template_xmlui.create(self.host, x) for x in list_items][0] 76 template_data["list_items"] = [
59 template_data["item"] = list_item 77 template_xmlui.create(self.host, x) for x in list_items
60 comments_uri = list_item.widgets["comments_uri"].value 78 ]
61 if comments_uri: 79 view_url = self.getPageByName('list_view').getURL(service.full(), node or '@')
62 uri_data = uri.parseXMPPUri(comments_uri) 80 template_data["on_list_item_click"] = data_objects.OnClick(
63 template_data["comments_node"] = comments_node = uri_data["node"] 81 url=f"{view_url}/{{item.id}}"
64 template_data["comments_service"] = comments_service = uri_data["path"] 82 )
65 comments = data_format.deserialise(await self.host.bridgeCall( 83 self.setPagination(request, metadata)
66 "mbGet", comments_service, comments_node, C.NO_LIMIT, [], {}, profile 84 self.exposeToScripts(
67 )) 85 request,
68 86 lists_ns=self.host.ns_map["tickets"],
69 template_data["comments"] = comments 87 pubsub_service=service.full(),
70 template_data["login_url"] = self.getPageRedirectURL(request) 88 pubsub_node=node,
71 89 )
72 if session.connected:
73 # we set edition URL only if user is the publisher or the node owner
74 publisher = jid.JID(list_item.widgets["publisher"].value)
75 is_publisher = publisher.userhostJID() == session.jid.userhostJID()
76 affiliation = None
77 if not is_publisher:
78 node = node or self.host.ns_map["tickets"]
79 affiliation = await self.host.getAffiliation(request, service, node)
80 if is_publisher or affiliation == "owner":
81 template_data["url_list_item_edit"] = self.getURLByPath(
82 SubPage("lists"),
83 service.full(),
84 node or "@",
85 SubPage("list_edit"),
86 list_item_id,
87 )
88
89 # we add xmpp: URI
90 uri_args = {'path': service.full()}
91 uri_args['node'] = node or self.host.ns_map["tickets"]
92 if list_item_id:
93 uri_args['item'] = list_item_id
94 template_data['xmpp_uri'] = uri.buildXMPPUri('pubsub', **uri_args)
95
96
97 async def on_data_post(self, request):
98 type_ = self.getPostedData(request, "type")
99 if type_ == "comment":
100 blog_page = self.getPageByName("blog_view")
101 await blog_page.on_data_post(self, request)
102 else:
103 log.warning(_("Unhandled data type: {}").format(type_))