| ... |
... |
@@ -21,8 +21,11 @@ |
|
21
|
21
|
import nbxmpp
|
|
22
|
22
|
from nbxmpp.namespaces import Namespace
|
|
23
|
23
|
from nbxmpp.util import generate_id
|
|
24
|
|
-from nbxmpp.util import is_error_result
|
|
|
24
|
+from nbxmpp.errors import StanzaError
|
|
|
25
|
+from nbxmpp.errors import MalformedStanzaError
|
|
|
26
|
+from nbxmpp.errors import is_error
|
|
25
|
27
|
from nbxmpp.structs import StanzaHandler
|
|
|
28
|
+from nbxmpp.modules.util import raise_if_error
|
|
26
|
29
|
|
|
27
|
30
|
from gajim.common import app
|
|
28
|
31
|
from gajim.common.nec import NetworkEvent
|
| ... |
... |
@@ -34,6 +37,7 @@ |
|
34
|
37
|
from gajim.common.modules.misc import parse_oob
|
|
35
|
38
|
from gajim.common.modules.misc import parse_correction
|
|
36
|
39
|
from gajim.common.modules.util import get_eme_message
|
|
|
40
|
+from gajim.common.modules.util import as_task
|
|
37
|
41
|
from gajim.common.modules.base import BaseModule
|
|
38
|
42
|
|
|
39
|
43
|
|
| ... |
... |
@@ -262,13 +266,8 @@ def _get_query_id(self, jid): |
|
262
|
266
|
self._mam_query_ids[jid] = query_id
|
|
263
|
267
|
return query_id
|
|
264
|
268
|
|
|
265
|
|
- def request_archive_on_signin(self):
|
|
|
269
|
+ def _get_query_params(self):
|
|
266
|
270
|
own_jid = self._con.get_own_jid().bare
|
|
267
|
|
-
|
|
268
|
|
- if own_jid in self._mam_query_ids:
|
|
269
|
|
- self._log.warning('Request already running: %s', own_jid)
|
|
270
|
|
- return
|
|
271
|
|
-
|
|
272
|
271
|
archive = app.storage.archive.get_archive_infos(own_jid)
|
|
273
|
272
|
|
|
274
|
273
|
mam_id = None
|
| ... |
... |
@@ -276,7 +275,6 @@ def request_archive_on_signin(self): |
|
276
|
275
|
mam_id = archive.last_mam_id
|
|
277
|
276
|
|
|
278
|
277
|
start_date = None
|
|
279
|
|
- queryid = self._get_query_id(own_jid)
|
|
280
|
278
|
if mam_id:
|
|
281
|
279
|
self._log.info('Request archive: %s, after mam-id %s',
|
|
282
|
280
|
own_jid, mam_id)
|
| ... |
... |
@@ -286,38 +284,13 @@ def request_archive_on_signin(self): |
|
286
|
284
|
start_date = datetime.utcnow() - timedelta(days=7)
|
|
287
|
285
|
self._log.info('Request archive: %s, after date %s',
|
|
288
|
286
|
own_jid, start_date)
|
|
|
287
|
+ return mam_id, start_date
|
|
289
|
288
|
|
|
290
|
|
- self._nbxmpp('MAM').make_query(own_jid,
|
|
291
|
|
- queryid,
|
|
292
|
|
- after=mam_id,
|
|
293
|
|
- start=start_date,
|
|
294
|
|
- callback=self._result_finished,
|
|
295
|
|
- user_data={'queryid': queryid,
|
|
296
|
|
- 'start': start_date,
|
|
297
|
|
- 'groupchat': False})
|
|
298
|
|
-
|
|
299
|
|
- if own_jid in self._catch_up_finished:
|
|
300
|
|
- self._catch_up_finished.remove(own_jid)
|
|
301
|
|
-
|
|
302
|
|
- def request_archive_on_muc_join(self, jid):
|
|
|
289
|
+ def _get_muc_query_params(self, jid, threshold):
|
|
303
|
290
|
archive = app.storage.archive.get_archive_infos(jid)
|
|
304
|
|
- disco_info = app.storage.cache.get_last_disco_info(jid)
|
|
305
|
|
-
|
|
306
|
|
- context = 'public'
|
|
307
|
|
- if disco_info is not None and disco_info.muc_is_members_only:
|
|
308
|
|
- context = 'private'
|
|
309
|
|
-
|
|
310
|
|
- threshold = app.settings.get_group_chat_setting(self._account,
|
|
311
|
|
- jid,
|
|
312
|
|
- 'sync_threshold',
|
|
313
|
|
- context=context)
|
|
314
|
|
- self._log.info('Threshold for %s: %s', jid, threshold)
|
|
315
|
|
-
|
|
316
|
|
- if threshold == SyncThreshold.NO_SYNC:
|
|
317
|
|
- return
|
|
318
|
|
-
|
|
319
|
291
|
mam_id = None
|
|
320
|
292
|
start_date = None
|
|
|
293
|
+
|
|
321
|
294
|
if archive is None or archive.last_mam_id is None:
|
|
322
|
295
|
# First join
|
|
323
|
296
|
start_date = datetime.utcnow() - timedelta(days=1)
|
| ... |
... |
@@ -353,67 +326,117 @@ def request_archive_on_muc_join(self, jid): |
|
353
|
326
|
self._log.info('Request archive: %s, after mam-id %s:',
|
|
354
|
327
|
jid, archive.last_mam_id)
|
|
355
|
328
|
|
|
|
329
|
+ return mam_id, start_date
|
|
|
330
|
+
|
|
|
331
|
+ @as_task
|
|
|
332
|
+ def request_archive_on_signin(self):
|
|
|
333
|
+ _task = yield
|
|
|
334
|
+
|
|
|
335
|
+ own_jid = self._con.get_own_jid().bare
|
|
|
336
|
+
|
|
|
337
|
+ if own_jid in self._mam_query_ids:
|
|
|
338
|
+ self._log.warning('request already running for %s', own_jid)
|
|
|
339
|
+ return
|
|
|
340
|
+
|
|
|
341
|
+ mam_id, start_date = self._get_query_params()
|
|
|
342
|
+
|
|
|
343
|
+ result = yield self._execute_query(own_jid, mam_id, start_date)
|
|
|
344
|
+ if is_error(result) and result.condition == 'item-not-found':
|
|
|
345
|
+ app.storage.archive.reset_archive_infos(result.jid)
|
|
|
346
|
+ _, start_date = self._get_query_params()
|
|
|
347
|
+ result = yield self._execute_query(result.jid, None, start_date)
|
|
|
348
|
+ raise_if_error(result)
|
|
|
349
|
+
|
|
|
350
|
+ if result.rsm.last is not None:
|
|
|
351
|
+ # <last> is not provided if the requested page was empty
|
|
|
352
|
+ # so this means we did not get anything hence we only need
|
|
|
353
|
+ # to update the archive info if <last> is present
|
|
|
354
|
+ app.storage.archive.set_archive_infos(
|
|
|
355
|
+ result.jid,
|
|
|
356
|
+ last_mam_id=result.rsm.last,
|
|
|
357
|
+ last_muc_timestamp=time.time())
|
|
|
358
|
+
|
|
|
359
|
+ if start_date is not None:
|
|
|
360
|
+ # Record the earliest timestamp we request from
|
|
|
361
|
+ # the account archive. For the account archive we only
|
|
|
362
|
+ # set start_date at the very first request.
|
|
|
363
|
+ app.storage.archive.set_archive_infos(
|
|
|
364
|
+ result.jid,
|
|
|
365
|
+ oldest_mam_timestamp=start_date.timestamp())
|
|
|
366
|
+
|
|
|
367
|
+ @as_task
|
|
|
368
|
+ def request_archive_on_muc_join(self, jid):
|
|
|
369
|
+ _task = yield
|
|
|
370
|
+
|
|
|
371
|
+ disco_info = app.storage.cache.get_last_disco_info(jid)
|
|
|
372
|
+
|
|
|
373
|
+ context = 'public'
|
|
|
374
|
+ if disco_info is not None and disco_info.muc_is_members_only:
|
|
|
375
|
+ context = 'private'
|
|
|
376
|
+
|
|
|
377
|
+ threshold = app.settings.get_group_chat_setting(self._account,
|
|
|
378
|
+ jid,
|
|
|
379
|
+ 'sync_threshold',
|
|
|
380
|
+ context=context)
|
|
|
381
|
+ self._log.info('Threshold for %s: %s', jid, threshold)
|
|
|
382
|
+
|
|
|
383
|
+ if threshold == SyncThreshold.NO_SYNC:
|
|
|
384
|
+ return
|
|
|
385
|
+
|
|
|
386
|
+ mam_id, start_date = self._get_muc_query_params(jid, threshold)
|
|
|
387
|
+
|
|
|
388
|
+ result = yield self._execute_query(jid, mam_id, start_date)
|
|
|
389
|
+ if is_error(result) and result.condition == 'item-not-found':
|
|
|
390
|
+ app.storage.archive.reset_archive_infos(result.jid)
|
|
|
391
|
+ _, start_date = self._get_muc_query_params(jid, threshold)
|
|
|
392
|
+ result = yield self._execute_query(result.jid, None, start_date)
|
|
|
393
|
+ raise_if_error(result)
|
|
|
394
|
+
|
|
|
395
|
+ if result.rsm.last is not None:
|
|
|
396
|
+ # <last> is not provided if the requested page was empty
|
|
|
397
|
+ # so this means we did not get anything hence we only need
|
|
|
398
|
+ # to update the archive info if <last> is present
|
|
|
399
|
+ app.storage.archive.set_archive_infos(
|
|
|
400
|
+ result.jid,
|
|
|
401
|
+ last_mam_id=result.rsm.last,
|
|
|
402
|
+ last_muc_timestamp=time.time())
|
|
|
403
|
+
|
|
|
404
|
+ @as_task
|
|
|
405
|
+ def _execute_query(self, jid, mam_id, start_date):
|
|
|
406
|
+ _task = yield
|
|
|
407
|
+
|
|
356
|
408
|
if jid in self._catch_up_finished:
|
|
357
|
409
|
self._catch_up_finished.remove(jid)
|
|
358
|
410
|
|
|
359
|
411
|
queryid = self._get_query_id(jid)
|
|
360
|
|
- self._nbxmpp('MAM').make_query(jid,
|
|
|
412
|
+
|
|
|
413
|
+ result = yield self.make_query(jid,
|
|
361
|
414
|
queryid,
|
|
362
|
415
|
after=mam_id,
|
|
363
|
|
- start=start_date,
|
|
364
|
|
- callback=self._result_finished,
|
|
365
|
|
- user_data={'queryid': queryid,
|
|
366
|
|
- 'start': start_date,
|
|
367
|
|
- 'groupchat': True})
|
|
368
|
|
-
|
|
369
|
|
- def _result_finished(self, result, user_data):
|
|
370
|
|
- queryid, start_date, groupchat = user_data.values()
|
|
371
|
|
- self._remove_query_id(result.jid)
|
|
|
416
|
+ start=start_date)
|
|
372
|
417
|
|
|
373
|
|
- if is_error_result(result):
|
|
374
|
|
- if result.condition == 'item-not-found':
|
|
375
|
|
- app.storage.archive.reset_archive_infos(result.jid)
|
|
376
|
|
- if groupchat:
|
|
377
|
|
- self.request_archive_on_muc_join(result.jid)
|
|
378
|
|
- else:
|
|
379
|
|
- self.request_archive_on_signin()
|
|
380
|
|
- return
|
|
381
|
|
-
|
|
382
|
|
- if result.complete:
|
|
383
|
|
- self._catch_up_finished.append(result.jid)
|
|
384
|
|
- self._log.info('Request finished: %s, last mam id: %s',
|
|
385
|
|
- result.jid, result.rsm.last)
|
|
|
418
|
+ self._remove_query_id(result.jid)
|
|
386
|
419
|
|
|
387
|
|
- if result.rsm.last is not None:
|
|
388
|
|
- # <last> is not provided if the requested page was empty
|
|
389
|
|
- # so this means we did not get anything hence we only need
|
|
390
|
|
- # to update the archive info if <last> is present
|
|
391
|
|
- app.storage.archive.set_archive_infos(
|
|
392
|
|
- result.jid,
|
|
393
|
|
- last_mam_id=result.rsm.last,
|
|
394
|
|
- last_muc_timestamp=time.time())
|
|
395
|
|
-
|
|
396
|
|
- if start_date is not None and not groupchat:
|
|
397
|
|
- # Record the earliest timestamp we request from
|
|
398
|
|
- # the account archive. For the account archive we only
|
|
399
|
|
- # set start_date at the very first request.
|
|
400
|
|
- app.storage.archive.set_archive_infos(
|
|
401
|
|
- result.jid,
|
|
402
|
|
- oldest_mam_timestamp=start_date.timestamp())
|
|
|
420
|
+ raise_if_error(result)
|
|
403
|
421
|
|
|
404
|
|
- else:
|
|
|
422
|
+ while not result.complete:
|
|
405
|
423
|
app.storage.archive.set_archive_infos(result.jid,
|
|
406
|
424
|
last_mam_id=result.rsm.last)
|
|
407
|
425
|
queryid = self._get_query_id(result.jid)
|
|
408
|
426
|
|
|
409
|
|
- self._nbxmpp('MAM').make_query(result.jid,
|
|
|
427
|
+ result = yield self.make_query(result.jid,
|
|
410
|
428
|
queryid,
|
|
411
|
429
|
after=result.rsm.last,
|
|
412
|
|
- start=start_date,
|
|
413
|
|
- callback=self._result_finished,
|
|
414
|
|
- user_data={'queryid': queryid,
|
|
415
|
|
- 'start': start_date,
|
|
416
|
|
- 'groupchat': groupchat})
|
|
|
430
|
+ start=start_date)
|
|
|
431
|
+
|
|
|
432
|
+ self._remove_query_id(result.jid)
|
|
|
433
|
+
|
|
|
434
|
+ raise_if_error(result)
|
|
|
435
|
+
|
|
|
436
|
+ self._catch_up_finished.append(result.jid)
|
|
|
437
|
+ self._log.info('Request finished: %s, last mam id: %s',
|
|
|
438
|
+ result.jid, result.rsm.last)
|
|
|
439
|
+ yield result
|
|
417
|
440
|
|
|
418
|
441
|
def request_archive_interval(self,
|
|
419
|
442
|
start_date,
|
| ... |
... |
@@ -433,24 +456,26 @@ def request_archive_interval(self, |
|
433
|
456
|
queryid = self._get_query_id(jid)
|
|
434
|
457
|
self._mam_query_ids[jid] = queryid
|
|
435
|
458
|
|
|
436
|
|
- self._nbxmpp('MAM').make_query(jid,
|
|
437
|
|
- queryid,
|
|
438
|
|
- after=after,
|
|
439
|
|
- start=start_date,
|
|
440
|
|
- end=end_date,
|
|
441
|
|
- callback=self._on_interval_result,
|
|
442
|
|
- user_data={'queryid': queryid,
|
|
443
|
|
- 'start_date': start_date,
|
|
444
|
|
- 'end_date': end_date})
|
|
|
459
|
+ self.make_query(jid,
|
|
|
460
|
+ queryid,
|
|
|
461
|
+ after=after,
|
|
|
462
|
+ start=start_date,
|
|
|
463
|
+ end=end_date,
|
|
|
464
|
+ callback=self._on_interval_result,
|
|
|
465
|
+ user_data=(queryid, start_date, end_date))
|
|
445
|
466
|
return queryid
|
|
446
|
467
|
|
|
447
|
|
- def _on_interval_result(self, result, user_data):
|
|
448
|
|
- queryid, start_date, end_date = user_data.values()
|
|
449
|
|
- self._remove_query_id(result.jid)
|
|
|
468
|
+ def _on_interval_result(self, task):
|
|
|
469
|
+ queryid, start_date, end_date = task.get_user_data()
|
|
450
|
470
|
|
|
451
|
|
- if is_error_result(result):
|
|
|
471
|
+ try:
|
|
|
472
|
+ result = task.finish()
|
|
|
473
|
+ except (StanzaError, MalformedStanzaError) as error:
|
|
|
474
|
+ self._remove_query_id(error.jid)
|
|
452
|
475
|
return
|
|
453
|
476
|
|
|
|
477
|
+ self._remove_query_id(result.jid)
|
|
|
478
|
+
|
|
454
|
479
|
if start_date:
|
|
455
|
480
|
timestamp = start_date.timestamp()
|
|
456
|
481
|
else:
|