Mercurial > libervia-backend
comparison sat/tools/common/data_objects.py @ 3310:e4121a1f2399
tools (common/data_objects): removed deprecated code:
`BlogItem`, `BlogItems` and `parsePubSubMetadata` are not needed anymore with the new blog
data serialisation.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 16 Jul 2020 09:07:26 +0200 |
parents | 9f0e28137cd0 |
children | be6d91572633 |
comparison
equal
deleted
inserted
replaced
3309:71761e9fb984 | 3310:e4121a1f2399 |
---|---|
1 #!/usr/bin/env python3 | 1 #!/usr/bin/env python3 |
2 | 2 |
3 | 3 # SàT: an XMPP client |
4 # SAT: a jabber client | |
5 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) | 4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) |
6 | 5 |
7 # This program is free software: you can redistribute it and/or modify | 6 # This program is free software: you can redistribute it and/or modify |
8 # it under the terms of the GNU Affero General Public License as published by | 7 # it under the terms of the GNU Affero General Public License as published by |
9 # the Free Software Foundation, either version 3 of the License, or | 8 # the Free Software Foundation, either version 3 of the License, or |
30 | 29 |
31 from sat.tools.common import uri as xmpp_uri | 30 from sat.tools.common import uri as xmpp_uri |
32 import urllib.request, urllib.parse, urllib.error | 31 import urllib.request, urllib.parse, urllib.error |
33 | 32 |
34 q = lambda value: urllib.parse.quote(value.encode("utf-8"), safe="@") | 33 q = lambda value: urllib.parse.quote(value.encode("utf-8"), safe="@") |
35 | |
36 | |
37 def parsePubSubMetadata(metadata, items): | |
38 """Helper method to have nicer metadata while doing a PubSub request | |
39 | |
40 The "rsm_index" and "rsm_count" keys will be converted to int | |
41 The "mam_stable" and "mam_complete" keys will be converted to boolean | |
42 A "complete" key can have the following values: | |
43 - True: we are on the last page, i.e. last items have been received | |
44 - False: we are not on the last page | |
45 - None: we don't have enough data fo know our position in the pagination | |
46 @param metadata(dict): dict retrieved fro bridge with request metadata | |
47 @param items(list): items retrieved (used to determine "complete" value) | |
48 @return (dict): parsed metadata | |
49 """ | |
50 data = {} | |
51 assert "complete" not in metadata | |
52 | |
53 for key, value in metadata.items(): | |
54 if key in ("rsm_index", "rsm_count"): | |
55 value = int(value) | |
56 elif key == "mam_stable": | |
57 value = C.bool(value) | |
58 elif key == "mam_complete": | |
59 key = "complete" | |
60 value = C.bool(value) | |
61 data[key] = value | |
62 if "complete" not in data: | |
63 index = data.get("rsm_index") | |
64 count = data.get("rsm_count") | |
65 if index is None or count is None: | |
66 # we don't have enough information to know if the data is complete or not | |
67 data["complete"] = None | |
68 else: | |
69 # normally we have a strict equality here but XEP-0059 states | |
70 # that index MAY be approximative, so just in case… | |
71 data["complete"] = index + len(items) >= count | |
72 return data | |
73 | |
74 | |
75 class BlogItem(object): | |
76 def __init__(self, mb_data, parent, deserialise=True): | |
77 """ | |
78 @param deserialise(bool): if True, mb_data is a serialised string which must | |
79 be deserialised | |
80 """ | |
81 # FIXME: deserialise should not be done here, but before BlogItem is called | |
82 if deserialise: | |
83 self.mb_data = data_format.deserialise(mb_data) | |
84 else: | |
85 self.mb_data = mb_data | |
86 self.parent = parent | |
87 self._comments = None | |
88 self._comments_items_list = None | |
89 | |
90 def json(self): | |
91 ret = {} | |
92 for attr in ( | |
93 "id", "atom_id", "uri", "published", "updated", "language", "author", | |
94 "author_jid", "author_jid_verified", "author_email", "tags", "groups", | |
95 "title", "title_xhtml", "content", "content_xhtml", "comments", | |
96 "comments_service", "comments_node", "comments_items_list" | |
97 ): | |
98 value = getattr(self, attr) | |
99 if value is not None: | |
100 ret[attr] = value | |
101 return ret | |
102 | |
103 @property | |
104 def id(self): | |
105 return self.mb_data.get("id") | |
106 | |
107 @property | |
108 def atom_id(self): | |
109 return self.mb_data.get("atom_id") | |
110 | |
111 @property | |
112 def uri(self): | |
113 node = self.parent.node | |
114 service = self.parent.service | |
115 return xmpp_uri.buildXMPPUri( | |
116 "pubsub", subtype="microblog", path=service, node=node, item=self.id | |
117 ) | |
118 | |
119 @property | |
120 def published(self): | |
121 return self.mb_data.get("published") | |
122 | |
123 @property | |
124 def updated(self): | |
125 return self.mb_data.get("updated") | |
126 | |
127 @property | |
128 def language(self): | |
129 return self.mb_data.get("language") | |
130 | |
131 @property | |
132 def author(self): | |
133 return self.mb_data.get("author") | |
134 | |
135 @property | |
136 def author_jid(self): | |
137 return self.mb_data.get("author_jid") | |
138 | |
139 @property | |
140 def author_jid_verified(self): | |
141 return self.mb_data.get("author_jid_verified") | |
142 | |
143 @property | |
144 def author_email(self): | |
145 return self.mb_data.get("author_email") | |
146 | |
147 @property | |
148 def tags(self): | |
149 return self.mb_data.get('tags', []) | |
150 | |
151 @property | |
152 def groups(self): | |
153 return self.mb_data.get('groups', []) | |
154 | |
155 @property | |
156 def title(self): | |
157 return self.mb_data.get("title") | |
158 | |
159 @property | |
160 def title_xhtml(self): | |
161 try: | |
162 return safe(self.mb_data["title_xhtml"]) | |
163 except KeyError: | |
164 return None | |
165 | |
166 @property | |
167 def content(self): | |
168 return self.mb_data.get("content") | |
169 | |
170 @property | |
171 def content_xhtml(self): | |
172 try: | |
173 return safe(self.mb_data["content_xhtml"]) | |
174 except KeyError: | |
175 return None | |
176 | |
177 @property | |
178 def comments(self): | |
179 if self._comments is None: | |
180 self._comments = data_format.dict2iterdict( | |
181 "comments", self.mb_data, ("node", "service") | |
182 ) | |
183 return self._comments | |
184 | |
185 @property | |
186 def comments_service(self): | |
187 return self.mb_data.get("comments_service") | |
188 | |
189 @property | |
190 def comments_node(self): | |
191 return self.mb_data.get("comments_node") | |
192 | |
193 @property | |
194 def comments_items_list(self): | |
195 return [] if self._comments_items_list is None else self._comments_items_list | |
196 | |
197 def appendCommentsItems(self, items): | |
198 """append comments items to self.comments_items""" | |
199 if self._comments_items_list is None: | |
200 self._comments_items_list = [] | |
201 self._comments_items_list.append(items) | |
202 | |
203 | |
204 class BlogItems(object): | |
205 def __init__(self, mb_data, deserialise=True): | |
206 """ | |
207 @param deserialise(bool): if True, mb_data is a serialised string which must | |
208 be deserialised | |
209 """ | |
210 # FIXME: deserialise should not be done here, but before BlogItem is called | |
211 self.items = [BlogItem(i, self, deserialise=deserialise) for i in mb_data[0]] | |
212 self.metadata = parsePubSubMetadata(mb_data[1], self.items) | |
213 | |
214 def json(self): | |
215 ret = { | |
216 "items": [i.json() for i in self.items], | |
217 } | |
218 for attr in ("service", "node", "uri", "with_rsm"): | |
219 ret[attr] = getattr(self, attr) | |
220 if self.with_rsm: | |
221 for attr in ("rsm_first", "rsm_last", "rsm_index", "rsm_count", "complete"): | |
222 ret[attr] = getattr(self, attr) | |
223 | |
224 return ret | |
225 | |
226 @property | |
227 def service(self): | |
228 return self.metadata["service"] | |
229 | |
230 @property | |
231 def node(self): | |
232 return self.metadata["node"] | |
233 | |
234 @property | |
235 def uri(self): | |
236 return self.metadata["uri"] | |
237 | |
238 @property | |
239 def with_rsm(self): | |
240 """Return True if RSM is activated on this request""" | |
241 return "rsm_first" in self.metadata | |
242 | |
243 @property | |
244 def rsm_first(self): | |
245 return self.metadata["rsm_first"] | |
246 | |
247 @property | |
248 def rsm_last(self): | |
249 return self.metadata["rsm_last"] | |
250 | |
251 @property | |
252 def rsm_index(self): | |
253 return self.metadata["rsm_index"] | |
254 | |
255 @property | |
256 def rsm_count(self): | |
257 return self.metadata["rsm_count"] | |
258 | |
259 @property | |
260 def complete(self): | |
261 return self.metadata["complete"] | |
262 | |
263 def __len__(self): | |
264 return self.items.__len__() | |
265 | |
266 def __missing__(self, key): | |
267 return self.items.__missing__(key) | |
268 | |
269 def __getitem__(self, key): | |
270 return self.items.__getitem__(key) | |
271 | |
272 def __iter__(self): | |
273 return self.items.__iter__() | |
274 | |
275 def __reversed__(self): | |
276 return self.items.__reversed__() | |
277 | |
278 def __contains__(self, item): | |
279 return self.items.__contains__(item) | |
280 | 34 |
281 | 35 |
282 class Message(object): | 36 class Message(object): |
283 def __init__(self, msg_data): | 37 def __init__(self, msg_data): |
284 self._uid = msg_data[0] | 38 self._uid = msg_data[0] |