comparison libervia/pages/blog/view/page_meta.py @ 1493:1702b8c821c4

pages (blog/view): avoid infinite recursion when comment nodes are making a loop
author Goffi <goffi@goffi.org>
date Tue, 22 Mar 2022 16:56:45 +0100
parents 3002ea1d6ae9
children 106bae41f5c8
comparison
equal deleted inserted replaced
1492:3a34d78f2717 1493:1702b8c821c4
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 2
3 import html 3 import html
4 from typing import Dict, Any 4 from typing import Any, Dict, Optional
5 from libervia.server.constants import Const as C 5
6 from twisted.words.protocols.jabber import jid 6 from sat.core.i18n import D_, _
7 from twisted.web import server 7 from sat.core.log import getLogger
8 from sat.core.i18n import _, D_
9 from sat.tools.common.template import safe
10 from sat.tools.common import uri 8 from sat.tools.common import uri
11 from sat.tools.common import data_format 9 from sat.tools.common import data_format
12 from sat.tools.common import regex 10 from sat.tools.common import regex
13 from sat.core.log import getLogger 11 from sat.tools.common.template import safe
12 from twisted.web import server
13 from twisted.words.protocols.jabber import jid
14
14 from libervia.server import utils 15 from libervia.server import utils
16 from libervia.server.constants import Const as C
15 from libervia.server.utils import SubPage 17 from libervia.server.utils import SubPage
16 18
17 log = getLogger(__name__) 19 log = getLogger(__name__)
18 20
19 """generic blog (with service/node provided)""" 21 """generic blog (with service/node provided)"""
114 breadcrumbs.append({ 116 breadcrumbs.append({
115 "label": D_("Post"), 117 "label": D_("Post"),
116 }) 118 })
117 119
118 120
119 async def appendComments(self, request, blog_items, profile): 121 async def appendComments(
122 self,
123 request: server.Request,
124 blog_items: dict,
125 profile: str,
126 _seen: Optional[set] = None
127 ) -> None:
128 """Recursively download and append comments of items
129
130 @param blog_items: items data
131 @param profile: Libervia profile
132 @param _seen: used to avoid infinite recursion. For internal use only
133 """
134 if _seen is None:
135 _seen = set()
120 await self.fillMissingIdentities( 136 await self.fillMissingIdentities(
121 request, [i['author_jid'] for i in blog_items['items']]) 137 request, [i['author_jid'] for i in blog_items['items']])
122 extra: Dict[str, Any] = {C.KEY_ORDER_BY: C.ORDER_BY_CREATION} 138 extra: Dict[str, Any] = {C.KEY_ORDER_BY: C.ORDER_BY_CREATION}
123 if not self.useCache(request): 139 if not self.useCache(request):
124 extra[C.KEY_USE_CACHE] = False 140 extra[C.KEY_USE_CACHE] = False
125 for blog_item in blog_items['items']: 141 for blog_item in blog_items['items']:
126 for comment_data in blog_item['comments']: 142 for comment_data in blog_item['comments']:
127 service = comment_data['service'] 143 service = comment_data['service']
128 node = comment_data['node'] 144 node = comment_data['node']
145 service_node = (service, node)
146 if service_node in _seen:
147 log.warning(
148 f"Items from {node!r} at {service} have already been retrieved, "
149 "there is a recursion at this service"
150 )
151 comment_data["items"] = []
152 continue
153 else:
154 _seen.add(service_node)
129 try: 155 try:
130 comments_data = await self.host.bridgeCall('mbGet', 156 comments_data = await self.host.bridgeCall('mbGet',
131 service, 157 service,
132 node, 158 node,
133 C.NO_LIMIT, 159 C.NO_LIMIT,
144 msg=e)) 170 msg=e))
145 comment_data['items'] = [] 171 comment_data['items'] = []
146 continue 172 continue
147 173
148 comments = data_format.deserialise(comments_data) 174 comments = data_format.deserialise(comments_data)
175 if comments is None:
176 log.error(f"Comments should not be None: {comment_data}")
177 comment_data["items"] = []
178 continue
149 comment_data['items'] = comments['items'] 179 comment_data['items'] = comments['items']
150 await appendComments(self, request, comments, profile) 180 await appendComments(self, request, comments, profile, _seen=_seen)
151 181
152 async def getBlogItems( 182 async def getBlogItems(
153 self, 183 self,
154 request: server.Request, 184 request: server.Request,
155 service: jid.JID, 185 service: jid.JID,