summaryrefslogtreecommitdiff
path: root/slixmpp/xmlstream/handler/collector.py
blob: d9e20279cd356def79e1dd48b964fbcbd974e2fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding: utf-8 -*-
"""
    slixmpp.xmlstream.handler.collector
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Part of Slixmpp: The Slick XMPP Library

    :copyright: (c) 2012 Nathanael C. Fritz, Lance J.T. Stout
    :license: MIT, see LICENSE for more details
"""

import logging
from queue import Queue, Empty

from slixmpp.xmlstream.handler.base import BaseHandler


log = logging.getLogger(__name__)


class Collector(BaseHandler):

    """
    The Collector handler allows for collecting a set of stanzas
    that match a given pattern. Unlike the Waiter handler, a
    Collector does not block execution, and will continue to
    accumulate matching stanzas until told to stop.

    :param string name: The name of the handler.
    :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
                    derived object for matching stanza objects.
    :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
                   instance this handler should monitor.
    """

    def __init__(self, name, matcher, stream=None):
        BaseHandler.__init__(self, name, matcher, stream=stream)
        self._payload = Queue()

    def prerun(self, payload):
        """Store the matched stanza when received during processing.

        :param payload: The matched
            :class:`~slixmpp.xmlstream.stanzabase.ElementBase` object.
        """
        self._payload.put(payload)

    def run(self, payload):
        """Do not process this handler during the main event loop."""
        pass

    def stop(self):
        """
        Stop collection of matching stanzas, and return the ones that
        have been stored so far.
        """
        self._destroy = True
        results = []
        try:
            while True:
                results.append(self._payload.get(False))
        except Empty:
            pass

        self.stream().remove_handler(self.name)
        return results