Mercurial > libervia-backend
comparison libervia/backend/tools/common/data_objects.py @ 4071:4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Jun 2023 11:49:51 +0200 |
parents | sat/tools/common/data_objects.py@524856bd7b19 |
children | f8284f994948 |
comparison
equal
deleted
inserted
replaced
4070:d10748475025 | 4071:4b842c1fb686 |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 # Libervia: an XMPP client | |
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) | |
5 | |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 """Objects handling bridge data, with jinja2 safe markup handling""" | |
20 | |
21 from libervia.backend.core.constants import Const as C | |
22 from libervia.backend.tools.common import data_format | |
23 from os.path import basename | |
24 | |
25 try: | |
26 from jinja2 import Markup as safe | |
27 except ImportError: | |
28 safe = str | |
29 | |
30 from libervia.backend.tools.common import uri as xmpp_uri | |
31 import urllib.request, urllib.parse, urllib.error | |
32 | |
33 q = lambda value: urllib.parse.quote(value.encode("utf-8"), safe="@") | |
34 | |
35 | |
36 class Message(object): | |
37 def __init__(self, msg_data): | |
38 self._uid = msg_data[0] | |
39 self._timestamp = msg_data[1] | |
40 self._from_jid = msg_data[2] | |
41 self._to_jid = msg_data[3] | |
42 self._message_data = msg_data[4] | |
43 self._subject_data = msg_data[5] | |
44 self._type = msg_data[6] | |
45 self._extra = data_format.deserialise(msg_data[7]) | |
46 self._html = dict(data_format.get_sub_dict("xhtml", self._extra)) | |
47 | |
48 @property | |
49 def id(self): | |
50 return self._uid | |
51 | |
52 @property | |
53 def timestamp(self): | |
54 return self._timestamp | |
55 | |
56 @property | |
57 def from_(self): | |
58 return self._from_jid | |
59 | |
60 @property | |
61 def text(self): | |
62 try: | |
63 return self._message_data[""] | |
64 except KeyError: | |
65 return next(iter(self._message_data.values())) | |
66 | |
67 @property | |
68 def subject(self): | |
69 try: | |
70 return self._subject_data[""] | |
71 except KeyError: | |
72 return next(iter(self._subject_data.values())) | |
73 | |
74 @property | |
75 def type(self): | |
76 return self._type | |
77 | |
78 @property | |
79 def thread(self): | |
80 return self._extra.get("thread") | |
81 | |
82 @property | |
83 def thread_parent(self): | |
84 return self._extra.get("thread_parent") | |
85 | |
86 @property | |
87 def received(self): | |
88 return self._extra.get("received_timestamp", self._timestamp) | |
89 | |
90 @property | |
91 def delay_sender(self): | |
92 return self._extra.get("delay_sender") | |
93 | |
94 @property | |
95 def info_type(self): | |
96 return self._extra.get("info_type") | |
97 | |
98 @property | |
99 def html(self): | |
100 if not self._html: | |
101 return None | |
102 try: | |
103 return safe(self._html[""]) | |
104 except KeyError: | |
105 return safe(next(iter(self._html.values()))) | |
106 | |
107 | |
108 class Messages(object): | |
109 def __init__(self, msgs_data): | |
110 self.messages = [Message(m) for m in msgs_data] | |
111 | |
112 def __len__(self): | |
113 return self.messages.__len__() | |
114 | |
115 def __missing__(self, key): | |
116 return self.messages.__missing__(key) | |
117 | |
118 def __getitem__(self, key): | |
119 return self.messages.__getitem__(key) | |
120 | |
121 def __iter__(self): | |
122 return self.messages.__iter__() | |
123 | |
124 def __reversed__(self): | |
125 return self.messages.__reversed__() | |
126 | |
127 def __contains__(self, item): | |
128 return self.messages.__contains__(item) | |
129 | |
130 | |
131 class Room(object): | |
132 def __init__(self, jid, name=None, url=None): | |
133 self.jid = jid | |
134 self.name = name or jid | |
135 if url is not None: | |
136 self.url = url | |
137 | |
138 | |
139 class Identity(object): | |
140 def __init__(self, jid_str, data=None): | |
141 self.jid_str = jid_str | |
142 self.data = data if data is not None else {} | |
143 | |
144 @property | |
145 def avatar_basename(self): | |
146 try: | |
147 return basename(self.data['avatar']['path']) | |
148 except (TypeError, KeyError): | |
149 return None | |
150 | |
151 def __getitem__(self, key): | |
152 return self.data[key] | |
153 | |
154 def __getattr__(self, key): | |
155 try: | |
156 return self.data[key] | |
157 except KeyError: | |
158 raise AttributeError(key) | |
159 | |
160 | |
161 class Identities: | |
162 def __init__(self): | |
163 self.identities = {} | |
164 | |
165 def __iter__(self): | |
166 return iter(self.identities) | |
167 | |
168 def __getitem__(self, jid_str): | |
169 try: | |
170 return self.identities[jid_str] | |
171 except KeyError: | |
172 return None | |
173 | |
174 def __setitem__(self, jid_str, data): | |
175 self.identities[jid_str] = Identity(jid_str, data) | |
176 | |
177 def __contains__(self, jid_str): | |
178 return jid_str in self.identities | |
179 | |
180 | |
181 class ObjectQuoter(object): | |
182 """object wrapper which quote attribues (to be used in templates)""" | |
183 | |
184 def __init__(self, obj): | |
185 self.obj = obj | |
186 | |
187 def __unicode__(self): | |
188 return q(self.obj.__unicode__()) | |
189 | |
190 def __str__(self): | |
191 return self.__unicode__() | |
192 | |
193 def __getattr__(self, name): | |
194 return q(self.obj.__getattr__(name)) | |
195 | |
196 def __getitem__(self, key): | |
197 return q(self.obj.__getitem__(key)) | |
198 | |
199 | |
200 class OnClick(object): | |
201 """Class to handle clickable elements targets""" | |
202 | |
203 def __init__(self, url=None): | |
204 self.url = url | |
205 | |
206 def format_url(self, *args, **kwargs): | |
207 """format URL using Python formatting | |
208 | |
209 values will be quoted before being used | |
210 """ | |
211 return self.url.format( | |
212 *[q(a) for a in args], **{k: ObjectQuoter(v) for k, v in kwargs.items()} | |
213 ) |