diff --git a/doc/quick_start.rst b/doc/quick_start.rst index a7b7b6b..aef0e3f 100644 --- a/doc/quick_start.rst +++ b/doc/quick_start.rst @@ -194,7 +194,7 @@ Configuring logging will lets us see the internal interactions. # OR # client.anonymous_login() - msg = client.wait_event(EMsg.ClientAccountInfo) + msg, = client.wait_event(EMsg.ClientAccountInfo) print "Logged on as: %s" % msg.body.persona_name print "SteamID: %s" % repr(client.steamid) @@ -214,7 +214,7 @@ Example of sending a protobuf message and handling the response. message = MsgProto(EMsg.ClientRequestWebAPIAuthenticateUserNonce) client.send(message) - resp = client.wait_event(EMsg.ClientRequestWebAPIAuthenticateUserNonceResponse) + resp, = client.wait_event(EMsg.ClientRequestWebAPIAuthenticateUserNonceResponse) if resp.body.eresult == EResult.OK: print "WebAPI Nonce: %s" % repr(resp.body.webapi_authenticate_user_nonce) diff --git a/requirements.txt b/requirements.txt index e77cd7e..49952ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ coverage==4.0.3 +gevent-eventemitter==1.1 enum34==1.1.2 gevent==1.1rc3 mock==1.3.0 diff --git a/setup.py b/setup.py index 268c170..ad38e0e 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ install_requires = [ 'vdf>=1.10', 'pycrypto>=2.6.1', 'gevent>=1.1rc3', + 'gevent-eventemitter>=1.1', 'protobuf>=2.6.1', ] diff --git a/steam/client/__init__.py b/steam/client/__init__.py index a6f826b..324ef44 100644 --- a/steam/client/__init__.py +++ b/steam/client/__init__.py @@ -1,6 +1,6 @@ import logging import gevent -from steam.util.events import EventEmitter +from eventemitter import EventEmitter from steam.enums.emsg import EMsg from steam.enums import EResult from steam.core.msg import MsgProto diff --git a/steam/client/gc.py b/steam/client/gc.py index ae30a9e..db81da3 100644 --- a/steam/client/gc.py +++ b/steam/client/gc.py @@ -1,6 +1,6 @@ import logging import gevent -from steam.util.events import EventEmitter +from eventemitter import EventEmitter from steam.util import set_proto_bit, clear_proto_bit, is_proto from steam.enums.emsg import EMsg from steam.enums import EResult diff --git a/steam/client/jobs.py b/steam/client/jobs.py index 1dc91a6..e91511a 100644 --- a/steam/client/jobs.py +++ b/steam/client/jobs.py @@ -1,6 +1,6 @@ import logging from gevent import event -from steam.util.events import EventEmitter +from eventemitter import EventEmitter from steam.enums.emsg import EMsg logger = logging.getLogger("JobManager") diff --git a/steam/core/cm.py b/steam/core/cm.py index bd7ef03..9e3e923 100644 --- a/steam/core/cm.py +++ b/steam/core/cm.py @@ -20,7 +20,7 @@ from steam.enums.emsg import EMsg from steam.core import crypto from steam.core.connection import TCPConnection from steam.core.msg import Msg, MsgProto -from steam.util.events import EventEmitter +from eventemitter import EventEmitter from steam.util import ip_from_int, is_proto, clear_proto_bit @@ -202,9 +202,8 @@ class CMClient(EventEmitter): self.send_message(resp) - try: - msg = self.wait_event(EMsg.ChannelEncryptResult, timeout=15) - except gevent.Timeout: + msg, = self.wait_event(EMsg.ChannelEncryptResult, timeout=5) + if msg is None: gevent.spawn(self.disconnect, True) return diff --git a/steam/util/events.py b/steam/util/events.py deleted file mode 100644 index 25c2901..0000000 --- a/steam/util/events.py +++ /dev/null @@ -1,113 +0,0 @@ -from collections import defaultdict -import gevent -from gevent.event import AsyncResult - - -class EventEmitter(object): - """ - Implements event emitter using ``gevent`` module. - Other modules can inherit from this object. - - .. code:: python - - class SomeClass(EventEmitter): - pass - - """ - - def emit(self, event, *args): - """ - Emit event with some arguments - - :type event: any - :param args: any or no arguments - """ - - gevent.idle() - - if hasattr(self, '_EventEmitter__callbacks'): - if event in self.__callbacks: - for callback in list(self.__callbacks[event]): - if isinstance(callback, AsyncResult): - self.remove_listener(event, callback) - - result = args - if len(args) == 1: - result = args[0] - - callback.set(result) - else: - gevent.spawn(callback, *args) - - gevent.idle() - - # every event is also emitted as None - if event is not None: - self.emit(None, event, *args) - - def remove_listener(self, event, callback): - """ - Removes callback for the specified event - - :param event: event identifier - :param callback: callback reference - :type callback: function, method or :py:class:`gevent.event.AsyncResult` - """ - - if not hasattr(self, '_EventEmitter__callbacks'): - return - - if event in self.__callbacks: - del self.__callbacks[event][callback] - - if not self.__callbacks[event]: - del self.__callbacks[event] - - def wait_event(self, event, timeout=None): - """ - Blocks until an event and returns the results - - :param event: event identifier - :param timeout: seconds to wait before raising an exception - :type timeout: int - :return: returns event arguments, if any. If there are many, returns tuple. - :rtype: None, any, or tuple - :raises: gevent.Timeout - """ - result = AsyncResult() - self.on(event, result) - return result.get(True, timeout) - - def on(self, event, callback=None): - """ - Registers a callback for the specified event - - :param event: event name - :param callback: callback function - - Can be as function decorator if only event is specified. - - .. code:: python - - @instaceOfSomeClass.on("some event") - def handle_event(): - pass - - instaceOfSomeClass.on("some event", handle_event) - - To listen for any event, use :py:class:`None` as event identifier. - """ - - if not hasattr(self, '_EventEmitter__callbacks'): - self.__callbacks = defaultdict(dict) - - # when used function - if callback: - self.__callbacks[event][callback] = None - return - - # as decorator - def wrapper(callback): - self.__callbacks[event][callback] = None - return callback - return wrapper