Line data Source code
1 : /*
2 : * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifdef HAVE_CONFIG_H
19 : #include "config.h"
20 : #endif
21 :
22 : #include "conversation_interface.h"
23 :
24 : #include <cerrno>
25 : #include <sstream>
26 : #include <cstring>
27 :
28 : #include "logger.h"
29 : #include "manager.h"
30 : #include "jamidht/jamiaccount.h"
31 : #include "jamidht/conversation_module.h"
32 :
33 : namespace libjami {
34 :
35 : std::string
36 81 : startConversation(const std::string& accountId)
37 : {
38 81 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
39 81 : if (auto convModule = acc->convModule(true))
40 81 : return convModule->startConversation();
41 0 : return {};
42 : }
43 :
44 : void
45 108 : acceptConversationRequest(const std::string& accountId, const std::string& conversationId)
46 : {
47 108 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
48 108 : if (auto convModule = acc->convModule(true))
49 108 : convModule->acceptConversationRequest(conversationId);
50 108 : }
51 :
52 : void
53 3 : declineConversationRequest(const std::string& accountId, const std::string& conversationId)
54 : {
55 3 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
56 3 : acc->declineConversationRequest(conversationId);
57 3 : }
58 :
59 : bool
60 6 : removeConversation(const std::string& accountId, const std::string& conversationId)
61 : {
62 6 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
63 6 : if (auto convModule = acc->convModule(true))
64 6 : return convModule->removeConversation(conversationId);
65 0 : return false;
66 : }
67 :
68 : std::vector<std::string>
69 7 : getConversations(const std::string& accountId)
70 : {
71 7 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
72 7 : if (auto convModule = acc->convModule(true))
73 7 : return convModule->getConversations();
74 0 : return {};
75 : }
76 :
77 : std::vector<std::map<std::string, std::string>>
78 16 : getActiveCalls(const std::string& accountId, const std::string& conversationId)
79 : {
80 16 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
81 16 : if (auto convModule = acc->convModule(true))
82 16 : return convModule->getActiveCalls(conversationId);
83 0 : return {};
84 : }
85 :
86 : std::vector<std::map<std::string, std::string>>
87 11 : getConversationRequests(const std::string& accountId)
88 : {
89 11 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
90 11 : if (auto convModule = acc->convModule(true))
91 11 : return convModule->getConversationRequests();
92 0 : return {};
93 : }
94 :
95 : void
96 3 : updateConversationInfos(const std::string& accountId,
97 : const std::string& conversationId,
98 : const std::map<std::string, std::string>& infos)
99 : {
100 3 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
101 3 : if (auto convModule = acc->convModule(true))
102 3 : convModule->updateConversationInfos(conversationId, infos);
103 3 : }
104 :
105 : std::map<std::string, std::string>
106 1 : conversationInfos(const std::string& accountId, const std::string& conversationId)
107 : {
108 1 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
109 1 : if (auto convModule = acc->convModule(true))
110 1 : return convModule->conversationInfos(conversationId);
111 0 : return {};
112 : }
113 :
114 : void
115 1 : setConversationPreferences(const std::string& accountId,
116 : const std::string& conversationId,
117 : const std::map<std::string, std::string>& prefs)
118 : {
119 1 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
120 1 : if (auto convModule = acc->convModule(true))
121 1 : convModule->setConversationPreferences(conversationId, prefs);
122 1 : }
123 :
124 : std::map<std::string, std::string>
125 0 : getConversationPreferences(const std::string& accountId, const std::string& conversationId)
126 : {
127 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
128 0 : if (auto convModule = acc->convModule(true))
129 0 : return convModule->getConversationPreferences(conversationId);
130 0 : return {};
131 : }
132 :
133 : // Member management
134 : void
135 107 : addConversationMember(const std::string& accountId,
136 : const std::string& conversationId,
137 : const std::string& contactUri)
138 : {
139 107 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
140 107 : if (auto convModule = acc->convModule(true)) {
141 107 : dht::InfoHash h(contactUri);
142 107 : if (not h) {
143 0 : JAMI_ERROR("addConversationMember: invalid contact URI `{}`", contactUri);
144 0 : return;
145 : }
146 107 : convModule->addConversationMember(conversationId, h);
147 107 : }
148 : }
149 :
150 : void
151 13 : removeConversationMember(const std::string& accountId,
152 : const std::string& conversationId,
153 : const std::string& contactUri)
154 : {
155 13 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
156 13 : if (auto convModule = acc->convModule(true)) {
157 13 : dht::InfoHash h(contactUri);
158 13 : if (not h) {
159 0 : JAMI_ERROR("removeConversationMember: invalid contact URI `{}`", contactUri);
160 0 : return;
161 : }
162 13 : convModule->removeConversationMember(conversationId, h);
163 13 : }
164 : }
165 :
166 : std::vector<std::map<std::string, std::string>>
167 21 : getConversationMembers(const std::string& accountId, const std::string& conversationId)
168 : {
169 21 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
170 21 : if (auto convModule = acc->convModule(true))
171 21 : return convModule->getConversationMembers(conversationId, true);
172 0 : return {};
173 : }
174 :
175 : // Message send/load
176 : void
177 57 : sendMessage(const std::string& accountId,
178 : const std::string& conversationId,
179 : const std::string& message,
180 : const std::string& commitId,
181 : const int32_t& flag)
182 : {
183 57 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
184 57 : if (auto convModule = acc->convModule(true)) {
185 57 : if (flag == 0 /* Reply or simple commit */) {
186 56 : convModule->sendMessage(conversationId, message, commitId);
187 1 : } else if (flag == 1 /* message edition */) {
188 1 : convModule->editMessage(conversationId, message, commitId);
189 0 : } else if (flag == 2 /* reaction */) {
190 0 : convModule->reactToMessage(conversationId, message, commitId);
191 : }
192 57 : }
193 57 : }
194 :
195 : uint32_t
196 0 : loadConversationMessages(const std::string& accountId,
197 : const std::string& conversationId,
198 : const std::string& fromMessage,
199 : size_t n)
200 : {
201 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
202 0 : if (auto convModule = acc->convModule(true))
203 0 : return convModule->loadConversationMessages(conversationId, fromMessage, n);
204 0 : return 0;
205 : }
206 :
207 : uint32_t
208 2 : loadConversation(const std::string& accountId,
209 : const std::string& conversationId,
210 : const std::string& fromMessage,
211 : size_t n)
212 : {
213 2 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
214 2 : if (auto convModule = acc->convModule(true))
215 2 : return convModule->loadConversation(conversationId, fromMessage, n);
216 0 : return 0;
217 : }
218 :
219 : uint32_t
220 0 : loadConversationUntil(const std::string& accountId,
221 : const std::string& conversationId,
222 : const std::string& fromMessage,
223 : const std::string& toMessage)
224 : {
225 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
226 0 : if (auto convModule = acc->convModule(true))
227 0 : return convModule->loadConversationUntil(conversationId, fromMessage, toMessage);
228 0 : return 0;
229 : }
230 :
231 : uint32_t
232 0 : loadSwarmUntil(const std::string& accountId,
233 : const std::string& conversationId,
234 : const std::string& fromMessage,
235 : const std::string& toMessage)
236 : {
237 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
238 0 : if (auto convModule = acc->convModule(true))
239 0 : return convModule->loadSwarmUntil(conversationId, fromMessage, toMessage);
240 0 : return 0;
241 : }
242 :
243 : uint32_t
244 0 : countInteractions(const std::string& accountId,
245 : const std::string& conversationId,
246 : const std::string& toId,
247 : const std::string& fromId,
248 : const std::string& authorUri)
249 : {
250 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
251 0 : if (auto convModule = acc->convModule(true))
252 0 : return convModule->countInteractions(conversationId, toId, fromId, authorUri);
253 0 : return 0;
254 : }
255 :
256 : void
257 0 : clearCache(const std::string& accountId, const std::string& conversationId)
258 : {
259 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
260 0 : if (auto convModule = acc->convModule(true))
261 0 : convModule->clearCache(conversationId);
262 0 : }
263 :
264 : uint32_t
265 0 : searchConversation(const std::string& accountId,
266 : const std::string& conversationId,
267 : const std::string& author,
268 : const std::string& lastId,
269 : const std::string& regexSearch,
270 : const std::string& type,
271 : const int64_t& after,
272 : const int64_t& before,
273 : const uint32_t& maxResult,
274 : const int32_t& flag)
275 : {
276 0 : uint32_t res = 0;
277 0 : jami::Filter filter {author, lastId, regexSearch, type, after, before, maxResult, flag != 0};
278 0 : for (const auto& accId : jami::Manager::instance().getAccountList()) {
279 0 : if (!accountId.empty() && accId != accountId)
280 0 : continue;
281 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accId)) {
282 0 : res = std::uniform_int_distribution<uint32_t>()(acc->rand);
283 0 : if (auto convModule = acc->convModule(true)) {
284 0 : convModule->search(res, conversationId, filter);
285 : }
286 0 : }
287 0 : }
288 0 : return res;
289 0 : }
290 :
291 : void
292 0 : reloadConversationsAndRequests(const std::string& accountId)
293 : {
294 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
295 0 : acc->reloadContacts();
296 0 : if (auto convModule = acc->convModule(true)) {
297 0 : convModule->reloadRequests();
298 0 : convModule->loadConversations();
299 : }
300 0 : }
301 0 : }
302 :
303 : } // namespace libjami
|