Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-stomp.py for openSUSE:Factory checked in at 2021-04-19 21:06:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-stomp.py (Old) and /work/SRC/openSUSE:Factory/.python-stomp.py.new.12324 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-stomp.py" Mon Apr 19 21:06:51 2021 rev:10 rq:886731 version:7.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-stomp.py/python-stomp.py.changes 2020-07-21 15:50:06.988275349 +0200 +++ /work/SRC/openSUSE:Factory/.python-stomp.py.new.12324/python-stomp.py.changes 2021-04-19 21:07:29.220163188 +0200 @@ -1,0 +2,26 @@ +Mon Apr 12 15:26:52 UTC 2021 - Sebastian Wagner <sebix+novell....@sebix.at> + +- update to version 7.0.0: +(from v6.1.1): + * Add host bind port patch (https://github.com/jasonrbriggs/stomp.py/issues/331) + * Tidy up based on pycharm suggestions + * Change quotes to be consistent (" rather than ') +(from v6.1.0): + * Remove traceback logging (https://github.com/jasonrbriggs/stomp.py/pull/290) + * Add support for \r\n EOL handling (as per [stomp protocol v1.2](http://stomp.github.io/stomp-specification-1.2.html#Augmented_BNF)) + * Remove heartbeat loop sleep (issue https://github.com/jasonrbriggs/stomp.py/issues/297, https://github.com/jasonrbriggs/stomp.py/pull/298) + * Update version number using the makefile and the poetry version command + * Add `original_headers` access to the Frame so that you can get the original value of a header even if a listener modifies it (issue: https://github.com/jasonrbriggs/stomp.py/issues/300, PR https://github.com/jasonrbriggs/stomp.py/pull/309) + * Fix for reconnect failures (https://github.com/jasonrbriggs/stomp.py/pull/295) + * Fix for double disconnect notifications causing issues with reconnection + * Add 'verbose' to stomp.logging (and defaulting the value to False). Log lines which dump the stacktrace now use that variable - except for a couple of cases (set stomp.logging.verbose = True to change back to the previous behaviour) + +------------------------------------------------------------------- +Mon Apr 5 19:10:50 UTC 2021 - Sebastian Wagner <sebix+novell....@sebix.at> + +- update to version 6.1.1: + * Add host bind port patch (https://github.com/jasonrbriggs/stomp.py/issues/331) + * Tidy up based on pycharm suggestions + * Change quotes to be consistent (" rather than ') + +------------------------------------------------------------------- Old: ---- python-stomp.py-6.1.0.tar.gz stomp.py-6.1.0.tar.gz New: ---- python-stomp.py-7.0.0.tar.gz stomp.py-7.0.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-stomp.py.spec ++++++ --- /var/tmp/diff_new_pack.RQxD0k/_old 2021-04-19 21:07:29.680163877 +0200 +++ /var/tmp/diff_new_pack.RQxD0k/_new 2021-04-19 21:07:29.684163883 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-stomp.py # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define skip_python2 1 Name: python-stomp.py -Version: 6.1.0 +Version: 7.0.0 Release: 0 Summary: Python STOMP client License: Apache-2.0 @@ -31,7 +31,7 @@ BuildRequires: python-rpm-macros Requires: python-docopt >= 0.6.2 Requires(post): update-alternatives -Requires(postun): update-alternatives +Requires(postun):update-alternatives BuildArch: noarch %python_subpackages ++++++ python-stomp.py-6.1.0.tar.gz -> python-stomp.py-7.0.0.tar.gz ++++++ ++++ 1705 lines of diff (skipped) ++++++ stomp.py-6.1.0.tar.gz -> stomp.py-7.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/PKG-INFO new/stomp.py-7.0.0/PKG-INFO --- old/stomp.py-6.1.0/PKG-INFO 2020-04-13 13:38:46.096743000 +0200 +++ new/stomp.py-7.0.0/PKG-INFO 2021-04-08 23:32:19.045912700 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: stomp.py -Version: 6.1.0 +Version: 7.0.0 Summary: Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of the protocol Home-page: https://github.com/jasonrbriggs/stomp.py License: Apache-2.0 @@ -73,16 +73,23 @@ There is also legacy 3.1.7 version using the old 3-series code (see `3.1.7 on PyPi`_ and `3.1.7 on GitHub`_). This is no longer supported, but (at least as of 2018) there were still a couple of reports of this version still being used in the wild. +Note: stomp.py now follows `semantic versioning`_: + +- MAJOR version for incompatible API changes, +- MINOR version for functionality added in a backwards compatible manner, and +- PATCH version for backwards compatible bug fixes. + + Testing ======= stomp.py has been perfunctorily tested on: -- Pivotal `RabbitMQ`_ (`rabbitmq_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/rabbitmq_test.py>`_) -- Apache `ActiveMQ`_ (`activemq_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/activemq_test.py>`_) -- Apache ActiveMQ `Artemis`_ (`artemis_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/artemis_test.py>`_) -- `stompserver`_ (`stompserver_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/stompserver_test.py>`_) +- Pivotal `RabbitMQ`_ (`test_rabbitmq.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_rabbitmq.py>`_) +- Apache `ActiveMQ`_ (`test_activemq.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_activemq.py>`_) +- Apache ActiveMQ `Artemis`_ (`test_artemis.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_artemis.py>`_) +- `stompserver`_ (`test_stompserver.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_stompserver.py>`_) For testing locally, you'll need to install docker. Once installed: @@ -121,3 +128,5 @@ .. _`buy me a coffee`: https://www.paypal.me/jasonrbriggs +.. _`semantic versioning`: https://semver.org/ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/README.rst new/stomp.py-7.0.0/README.rst --- old/stomp.py-6.1.0/README.rst 2020-02-15 16:24:05.247170200 +0100 +++ new/stomp.py-7.0.0/README.rst 2021-04-01 22:46:33.122966000 +0200 @@ -51,16 +51,23 @@ There is also legacy 3.1.7 version using the old 3-series code (see `3.1.7 on PyPi`_ and `3.1.7 on GitHub`_). This is no longer supported, but (at least as of 2018) there were still a couple of reports of this version still being used in the wild. +Note: stomp.py now follows `semantic versioning`_: + +- MAJOR version for incompatible API changes, +- MINOR version for functionality added in a backwards compatible manner, and +- PATCH version for backwards compatible bug fixes. + + Testing ======= stomp.py has been perfunctorily tested on: -- Pivotal `RabbitMQ`_ (`rabbitmq_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/rabbitmq_test.py>`_) -- Apache `ActiveMQ`_ (`activemq_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/activemq_test.py>`_) -- Apache ActiveMQ `Artemis`_ (`artemis_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/artemis_test.py>`_) -- `stompserver`_ (`stompserver_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/stompserver_test.py>`_) +- Pivotal `RabbitMQ`_ (`test_rabbitmq.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_rabbitmq.py>`_) +- Apache `ActiveMQ`_ (`test_activemq.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_activemq.py>`_) +- Apache ActiveMQ `Artemis`_ (`test_artemis.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_artemis.py>`_) +- `stompserver`_ (`test_stompserver.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_stompserver.py>`_) For testing locally, you'll need to install docker. Once installed: @@ -98,3 +105,5 @@ .. _`stompserver`: http://stompserver.rubyforge.org .. _`buy me a coffee`: https://www.paypal.me/jasonrbriggs + +.. _`semantic versioning`: https://semver.org/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/pyproject.toml new/stomp.py-7.0.0/pyproject.toml --- old/stomp.py-6.1.0/pyproject.toml 2020-04-13 13:33:37.759791600 +0200 +++ new/stomp.py-7.0.0/pyproject.toml 2021-04-08 00:15:42.023734300 +0200 @@ -1,6 +1,6 @@ [tool.poetry] name = "stomp.py" -version = "6.1.0" +version = "7.0.0" description = "Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of the protocol" authors = ["Jason R Briggs <jasonrbri...@gmail.com>"] license = "Apache-2.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/setup.py new/stomp.py-7.0.0/setup.py --- old/stomp.py-6.1.0/setup.py 2020-04-13 13:38:46.095874300 +0200 +++ new/stomp.py-7.0.0/setup.py 2021-04-08 23:32:19.045352700 +0200 @@ -15,9 +15,9 @@ setup_kwargs = { 'name': 'stomp.py', - 'version': '6.1.0', + 'version': '7.0.0', 'description': 'Python STOMP client, supporting versions 1.0, 1.1 and 1.2 of the protocol', - 'long_description': '========\nstomp.py\n========\n\n.. image:: https://badge.fury.io/py/stomp.py.svg\n :target: https://badge.fury.io/py/stomp.py\n :alt: PyPI version\n\n.. image:: https://travis-ci.org/jasonrbriggs/stomp.py.svg\n :target: https://travis-ci.org/jasonrbriggs/stomp.py\n :alt: Build Status\n\n"stomp.py" is a Python client library for accessing messaging servers (such as ActiveMQ_, Artemis_ or RabbitMQ_) using the STOMP_ protocol (`STOMP v1.0`_, `STOMP v1.1`_ and `STOMP v1.2`_). It can also be run as a standalone, command-line client for testing. NOTE: Stomp.py has officially ended support for Python2.x. See `python3statement.org`_ for more information. \n\n**If you find this project useful, why not** `buy me a coffee`_.\n\n.. contents:: \\ \n :depth: 1\n\n\nQuick Start\n===========\n\nYou can connect to a message broker running on the local machine, and send a message using the following example.\n\n.. code-block:: python\n\n import stomp\n\n con n = stomp.Connection()\n conn.connect(\'admin\', \'password\', wait=True)\n conn.send(body=\' \'.join(sys.argv[1:]), destination=\'/queue/test\')\n conn.disconnect()\n\n\nDocumentation and Resources\n===========================\n\n- `Main documentation`_\n- `API documentation`_ (see `stomp.github.io`_ for details on the STOMP protocol itself)\n- A basic example of using stomp.py with a message listener can be found in the `quick start`_ section of the main documentation\n- Description of the `command-line interface`_\n- `Travis`_ for continuous integration builds\n- Current `test coverage report`_\n- `PyPi stomp.py page`_\n\nThe current version of stomp.py supports:\n\n- Python 3.x (Python2 support ended as of Jan 2020)\n- STOMP version 1.0, 1.1 and 1.2\n\nThere is also legacy 3.1.7 version using the old 3-series code (see `3.1.7 on PyPi`_ and `3.1.7 on GitHub`_). This is no longer supported, but (at least as of 2018) there were still a couple of reports of this version still bei ng used in the wild.\n\n\nTesting\n=======\n\nstomp.py has been perfunctorily tested on:\n\n- Pivotal `RabbitMQ`_ (`rabbitmq_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/rabbitmq_test.py>`_)\n- Apache `ActiveMQ`_ (`activemq_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/activemq_test.py>`_)\n- Apache ActiveMQ `Artemis`_ (`artemis_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/artemis_test.py>`_)\n- `stompserver`_ (`stompserver_test.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/stomp/test/stompserver_test.py>`_)\n\nFor testing locally, you\'ll need to install docker. Once installed:\n\n#. Create the docker image:\n make docker-image\n#. Run the container:\n make run-docker\n#. Run stomp.py unit tests:\n make test\n#. Cleanup the container afterwards if you don\'t need it any more:\n make remove-docker\n\n\n.. _`STOMP`: http://stomp.github.io\n.. _`STOMP v1.0`: http://stomp .github.io/stomp-specification-1.0.html\n.. _`STOMP v1.1`: http://stomp.github.io/stomp-specification-1.1.html\n.. _`STOMP v1.2`: http://stomp.github.io/stomp-specification-1.2.html\n.. _`python3statement.org`: http://python3statement.org/\n\n.. _`Main documentation`: http://jasonrbriggs.github.io/stomp.py/index.html\n.. _`stomp.github.io`: http://stomp.github.io/\n.. _`quick start`: http://jasonrbriggs.github.io/stomp.py/quickstart.html\n.. _`command-line interface`: http://jasonrbriggs.github.io/stomp.py/commandline.html\n.. _`PyPi stomp.py page`: https://pypi.org/project/stomp.py/\n.. _`API documentation`: http://jasonrbriggs.github.io/stomp.py/api.html\n.. _`test coverage report`: http://jasonrbriggs.github.io/stomp.py/htmlcov/\n.. _`Travis`: https://travis-ci.org/jasonrbriggs/stomp.py\n\n.. _`3.1.7 on PyPi`: https://pypi.org/project/stomp.py/3.1.7/\n.. _`3.1.7 on GitHub`: https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series\n\n.. _`ActiveMQ`: http://activemq.apache.or g/\n.. _`Artemis`: https://activemq.apache.org/components/artemis/\n.. _`RabbitMQ`: http://www.rabbitmq.com\n.. _`stompserver`: http://stompserver.rubyforge.org\n\n.. _`buy me a coffee`: https://www.paypal.me/jasonrbriggs\n', + 'long_description': '========\nstomp.py\n========\n\n.. image:: https://badge.fury.io/py/stomp.py.svg\n :target: https://badge.fury.io/py/stomp.py\n :alt: PyPI version\n\n.. image:: https://travis-ci.org/jasonrbriggs/stomp.py.svg\n :target: https://travis-ci.org/jasonrbriggs/stomp.py\n :alt: Build Status\n\n"stomp.py" is a Python client library for accessing messaging servers (such as ActiveMQ_, Artemis_ or RabbitMQ_) using the STOMP_ protocol (`STOMP v1.0`_, `STOMP v1.1`_ and `STOMP v1.2`_). It can also be run as a standalone, command-line client for testing. NOTE: Stomp.py has officially ended support for Python2.x. See `python3statement.org`_ for more information. \n\n**If you find this project useful, why not** `buy me a coffee`_.\n\n.. contents:: \\ \n :depth: 1\n\n\nQuick Start\n===========\n\nYou can connect to a message broker running on the local machine, and send a message using the following example.\n\n.. code-block:: python\n\n import stomp\n\n con n = stomp.Connection()\n conn.connect(\'admin\', \'password\', wait=True)\n conn.send(body=\' \'.join(sys.argv[1:]), destination=\'/queue/test\')\n conn.disconnect()\n\n\nDocumentation and Resources\n===========================\n\n- `Main documentation`_\n- `API documentation`_ (see `stomp.github.io`_ for details on the STOMP protocol itself)\n- A basic example of using stomp.py with a message listener can be found in the `quick start`_ section of the main documentation\n- Description of the `command-line interface`_\n- `Travis`_ for continuous integration builds\n- Current `test coverage report`_\n- `PyPi stomp.py page`_\n\nThe current version of stomp.py supports:\n\n- Python 3.x (Python2 support ended as of Jan 2020)\n- STOMP version 1.0, 1.1 and 1.2\n\nThere is also legacy 3.1.7 version using the old 3-series code (see `3.1.7 on PyPi`_ and `3.1.7 on GitHub`_). This is no longer supported, but (at least as of 2018) there were still a couple of reports of this version still bei ng used in the wild.\n\nNote: stomp.py now follows `semantic versioning`_:\n\n- MAJOR version for incompatible API changes,\n- MINOR version for functionality added in a backwards compatible manner, and\n- PATCH version for backwards compatible bug fixes.\n\n\n\nTesting\n=======\n\nstomp.py has been perfunctorily tested on:\n\n- Pivotal `RabbitMQ`_ (`test_rabbitmq.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_rabbitmq.py>`_)\n- Apache `ActiveMQ`_ (`test_activemq.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_activemq.py>`_)\n- Apache ActiveMQ `Artemis`_ (`test_artemis.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_artemis.py>`_)\n- `stompserver`_ (`test_stompserver.py <https://github.com/jasonrbriggs/stomp.py/blob/dev/tests/test_stompserver.py>`_)\n\nFor testing locally, you\'ll need to install docker. Once installed:\n\n#. Create the docker image:\n make docker-image\n#. Run the container:\n make run-docker\ n#. Run stomp.py unit tests:\n make test\n#. Cleanup the container afterwards if you don\'t need it any more:\n make remove-docker\n\n\n.. _`STOMP`: http://stomp.github.io\n.. _`STOMP v1.0`: http://stomp.github.io/stomp-specification-1.0.html\n.. _`STOMP v1.1`: http://stomp.github.io/stomp-specification-1.1.html\n.. _`STOMP v1.2`: http://stomp.github.io/stomp-specification-1.2.html\n.. _`python3statement.org`: http://python3statement.org/\n\n.. _`Main documentation`: http://jasonrbriggs.github.io/stomp.py/index.html\n.. _`stomp.github.io`: http://stomp.github.io/\n.. _`quick start`: http://jasonrbriggs.github.io/stomp.py/quickstart.html\n.. _`command-line interface`: http://jasonrbriggs.github.io/stomp.py/commandline.html\n.. _`PyPi stomp.py page`: https://pypi.org/project/stomp.py/\n.. _`API documentation`: http://jasonrbriggs.github.io/stomp.py/api.html\n.. _`test coverage report`: http://jasonrbriggs.github.io/stomp.py/htmlcov/\n.. _`Travis`: https://travis-ci.org/j asonrbriggs/stomp.py\n\n.. _`3.1.7 on PyPi`: https://pypi.org/project/stomp.py/3.1.7/\n.. _`3.1.7 on GitHub`: https://github.com/jasonrbriggs/stomp.py/tree/stomppy-3series\n\n.. _`ActiveMQ`: http://activemq.apache.org/\n.. _`Artemis`: https://activemq.apache.org/components/artemis/\n.. _`RabbitMQ`: http://www.rabbitmq.com\n.. _`stompserver`: http://stompserver.rubyforge.org\n\n.. _`buy me a coffee`: https://www.paypal.me/jasonrbriggs\n\n.. _`semantic versioning`: https://semver.org/\n', 'author': 'Jason R Briggs', 'author_email': 'jasonrbri...@gmail.com', 'maintainer': None, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/__init__.py new/stomp.py-7.0.0/stomp/__init__.py --- old/stomp.py-6.1.0/stomp/__init__.py 2020-04-13 13:36:24.352790600 +0200 +++ new/stomp.py-7.0.0/stomp/__init__.py 2021-04-08 23:32:05.949437400 +0200 @@ -14,7 +14,7 @@ import stomp.listener as listener import stomp.logging as logging -__version__ = (6, 1, 0) +__version__ = (7, 0, 0) ## # Alias for STOMP 1.0 connections. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/__main__.py new/stomp.py-7.0.0/stomp/__main__.py --- old/stomp.py-6.1.0/stomp/__main__.py 2020-02-15 16:24:05.255170000 +0100 +++ new/stomp.py-7.0.0/stomp/__main__.py 1980-01-01 01:00:00.000000000 +0100 @@ -40,9 +40,9 @@ from docopt import docopt sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) -from stomp.adapter.multicast import MulticastConnection import stomp.colours import stomp.utils +from stomp.adapter.multicast import MulticastConnection from stomp.connect import StompConnection10, StompConnection11, StompConnection12 from stomp.listener import ConnectionListener, StatsListener @@ -68,9 +68,10 @@ A command line interface to the stomp.py client. See :py:class:`stomp.connect.StompConnection11` for more information on establishing a connection to a stomp server. """ - def __init__(self, host='localhost', port=61613, user='', passcode='', ver='1.1', prompt='> ', verbose=True, - heartbeats=(0, 0), use_ssl=False, ssl_key_file=None, ssl_cert_file=None, ssl_ca_file=None, stdin=sys.stdin, stdout=sys.stdout): - Cmd.__init__(self, 'Tab', stdin, stdout) + def __init__(self, host="localhost", port=61613, user="", passcode="", ver="1.1", prompt="> ", verbose=True, + heartbeats=(0, 0), use_ssl=False, ssl_key_file=None, ssl_cert_file=None, ssl_ca_file=None, + stdin=sys.stdin, stdout=sys.stdout): + Cmd.__init__(self, "Tab", stdin, stdout) ConnectionListener.__init__(self) self.__start = True self.prompt = prompt @@ -90,7 +91,7 @@ raise RuntimeError("Unknown version") if use_ssl: self.conn.set_ssl([(host, port)], key_file=ssl_key_file, cert_file=ssl_cert_file, ca_certs=ssl_ca_file) - self.conn.set_listener('', self) + self.conn.set_listener("", self) self.conn.connect(self.user, self.passcode, wait=True) self.transaction_id = None self.version = ver @@ -101,7 +102,7 @@ self.__subscriptions = {} self.__subscription_id = 1 - def __print_async(self, frame_type, headers, body): + def __print_async(self, frame_type, frame): """ Utility function to print a message and setup the command prompt for the next input @@ -110,18 +111,18 @@ return if self.verbose: self.__sysout(frame_type) - for k, v in headers.items(): + for k, v in frame.headers.items(): self.__sysout("%s: %s" % (k, v)) else: - if "message-id" in headers: - self.__sysout("message-id: %s" % headers["message-id"]) - if "subscription" in headers: - self.__sysout("subscription: %s" % headers["subscription"]) - if self.prompt != '': - self.__sysout('') - self.__sysout(body) + if "message-id" in frame.headers: + self.__sysout("message-id: %s" % frame.headers["message-id"]) + if "subscription" in frame.headers: + self.__sysout("subscription: %s" % frame.headers["subscription"]) + if self.prompt != "": + self.__sysout("") + self.__sysout(frame.body) if not self.__start: - self.__sysout(self.prompt, end='') + self.__sysout(self.prompt, end="") else: self.__start = False self.stdout.flush() @@ -147,43 +148,42 @@ if not self.__quit: self.__error("lost connection") - def on_message(self, headers, body): + def on_message(self, frame): """ See :py:meth:`ConnectionListener.on_message` Special case: if the header 'filename' is present, the content is written out as a file """ - self.__sysout('') - if "filename" in headers: - content = base64.b64decode(body.encode()) - if os.path.exists(headers["filename"]): - fname = "%s.%s" % (headers["filename"], int(time.time())) + self.__sysout("") + if "filename" in frame.headers: + content = base64.b64decode(frame.body.encode()) + if os.path.exists(frame.headers["filename"]): + fname = "%s.%s" % (frame.headers["filename"], int(time.time())) else: - fname = headers["filename"] - with open(fname, 'wb') as f: + fname = frame.headers["filename"] + with open(fname, "wb") as f: f.write(content) - self.__print_async("MESSAGE", headers, "Saved file: %s" % fname) - else: - self.__print_async("MESSAGE", headers, body) + frame.body = "Saved file: %s" % fname + self.__print_async("MESSAGE", frame) - def on_error(self, headers, body): + def on_error(self, frame): """ See :py:meth:`ConnectionListener.on_error` """ - self.__print_async("ERROR", headers, body) + self.__print_async("ERROR", frame) - def on_receipt(self, headers, body): + def on_receipt(self, frame): """ See :py:meth:`ConnectionListener.on_receipt` """ - self.__print_async("RECEIPT", headers, body) + self.__print_async("RECEIPT", frame) - def on_connected(self, headers, body): + def on_connected(self, frame): """ See :py:meth:`ConnectionListener.on_connected` """ - self.__print_async("CONNECTED", headers, body) + self.__print_async("CONNECTED", frame) def on_send(self, frame): if self.verbose: @@ -211,11 +211,11 @@ "optional": oparams.rstrip() } - if rparams.rstrip() != '': + if rparams.rstrip() != "": rparams = '''%(hl)sRequired Parameters:%(nc)s%(required)s\n\n''' % m m["required"] = rparams - if oparams.rstrip() != '': + if oparams.rstrip() != "": oparams = '''%(hl)sOptional Parameters:%(nc)s%(optional)s\n\n''' % m m["optional"] = oparams @@ -291,12 +291,12 @@ if len(args) < 2: self.__error("Expecting: send <destination> <message>") elif not self.transaction_id: - self.conn.send(args[0], ' '.join(args[1:])) + self.conn.send(args[0], " ".join(args[1:])) else: - self.conn.send(args[0], ' '.join(args[1:]), transaction=self.transaction_id) + self.conn.send(args[0], " ".join(args[1:]), transaction=self.transaction_id) - def complete_send(self, text, line, begidx, endidx): - mline = line.split(' ')[1] + def complete_send(self, text, line): + mline = line.split(" ")[1] offs = len(mline) - len(text) return [s[offs:] for s in self.__subscriptions if s.startswith(mline)] complete_unsubscribe = complete_send @@ -314,9 +314,9 @@ if len(args) < 2: self.__error("Expecting: sendrec <destination> <message>") elif not self.transaction_id: - self.conn.send(args[0], ' '.join(args[1:]), receipt=receipt_id) + self.conn.send(args[0], " ".join(args[1:]), receipt=receipt_id) else: - self.conn.send(args[0], ' '.join(args[1:]), transaction=self.transaction_id, receipt=receipt_id) + self.conn.send(args[0], " ".join(args[1:]), transaction=self.transaction_id, receipt=receipt_id) def help_sendrec(self): self.help("sendrec <destination> <message>", @@ -328,7 +328,7 @@ if len(args) < 3: self.__error("Expecting: sendreply <destination> <correlation-id> <message>") else: - self.conn.send(args[0], "%s\n" % ' '.join(args[2:]), headers={"correlation-id": args[1]}) + self.conn.send(args[0], "%s\n" % " ".join(args[2:]), headers={"correlation-id": args[1]}) def help_sendreply(self): self.help("sendreply <destination> <correlation-id> <message>", @@ -350,11 +350,11 @@ self.__error("File %s does not exist" % args[2]) return self.__sysout("Loading %s" % args[2]) - with open(args[2], mode='rb') as jf: + with open(args[2], mode="rb") as jf: headers = json.load(jf) self.__sysout("Using headers %s" % str(headers)) - with open(args[1], mode='rb') as f: + with open(args[1], mode="rb") as f: s = f.read() msg = base64.b64encode(s).decode() if not self.transaction_id: @@ -379,13 +379,13 @@ def check_ack_nack(self, acknackfunc, args): if self.nversion >= 1.2 and len(args) < 1: - self.__error("Expecting: %s <ack-id>" % cmd) + self.__error("Expecting: %s <ack-id>" % acknackfunc) return None elif self.nversion == 1.1 and len(args) < 2: - self.__error("Expecting: %s <message-id> <subscription-id>" % cmd) + self.__error("Expecting: %s <message-id> <subscription-id>" % acknackfunc) return None elif len(args) < 1: - self.__error("Expecting: %s <message-id>" % cmd) + self.__error("Expecting: %s <message-id>" % acknackfunc) return None if self.nversion == 1.1: @@ -507,9 +507,9 @@ arguments = docopt(__doc__, version=version_string) if arguments["--listen"] is not None: - prompt = '' + prompt = "" else: - prompt = '> ' + prompt = "> " if not heartbeat_pattern.match(arguments["--heartbeats"]): print("Invalid heartbeats, expecting cx,cy") @@ -518,11 +518,11 @@ heartbeats = tuple(map(int, arguments["--heartbeats"].split(","))) st = StompCLI(arguments["--host"], arguments["--port"], arguments["--user"], arguments["--password"], arguments["--protocol"], - prompt, arguments["--verbose"], heartbeats=heartbeats, - use_ssl=arguments["--ssl"], - ssl_key_file=arguments["--ssl-key-file"], - ssl_cert_file=arguments["--ssl-cert-file"], - ssl_ca_file=arguments["--ssl-ca-file"]) + prompt, arguments["--verbose"], heartbeats=heartbeats, + use_ssl=arguments["--ssl"], + ssl_key_file=arguments["--ssl-key-file"], + ssl_cert_file=arguments["--ssl-cert-file"], + ssl_ca_file=arguments["--ssl-ca-file"]) if arguments["--listen"] is not None: st.do_subscribe(arguments["--listen"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/adapter/multicast.py new/stomp.py-7.0.0/stomp/adapter/multicast.py --- old/stomp.py-6.1.0/stomp/adapter/multicast.py 2020-02-15 16:24:05.255170000 +0100 +++ new/stomp.py-7.0.0/stomp/adapter/multicast.py 1980-01-01 01:00:00.000000000 +0100 @@ -35,7 +35,7 @@ self.receiver_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) self.receiver_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.receiver_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - self.receiver_socket.bind(('', MCAST_PORT)) + self.receiver_socket.bind(("", MCAST_PORT)) mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) self.receiver_socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) @@ -76,8 +76,8 @@ if frame_type == "message": if f.headers["destination"] not in self.subscriptions.values(): return - (f.headers, f.body) = self.notify("before_message", f.headers, f.body) - self.notify(frame_type, f.headers, f.body) + self.notify("before_message", f) + self.notify(frame_type, f) if "receipt" in f.headers: receipt_frame = Frame("RECEIPT", {"receipt-id": f.headers["receipt"]}) lines = convert_frame(receipt_frame) @@ -140,7 +140,7 @@ Protocol12.disconnect(self, receipt, headers, **keyword_headers) self.transport.stop() - def send_frame(self, cmd, headers=None, body=''): + def send_frame(self, cmd, headers=None, body=""): """ :param str cmd: :param dict headers: @@ -148,18 +148,18 @@ """ if headers is None: headers = {} - frame = utils.Frame(cmd, headers, body) + frame = Frame(cmd, headers, body) if cmd == CMD_BEGIN: trans = headers[HDR_TRANSACTION] if trans in self.transactions: - self.notify("error", {}, "Transaction %s already started" % trans) + self.notify("error", Frame(None, {}, "Transaction %s already started" % trans)) else: self.transactions[trans] = [] elif cmd == CMD_COMMIT: trans = headers[HDR_TRANSACTION] if trans not in self.transactions: - self.notify("error", {}, "Transaction %s not started" % trans) + self.notify("error", Frame(None, {}, "Transaction %s not started" % trans)) else: for f in self.transactions[trans]: self.transport.transmit(f) @@ -171,7 +171,7 @@ if "transaction" in headers: trans = headers["transaction"] if trans not in self.transactions: - self.transport.notify("error", {}, "Transaction %s not started" % trans) + self.transport.notify("error", Frame(None, {}, "Transaction %s not started" % trans)) return else: self.transactions[trans].append(frame) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/connect.py new/stomp.py-7.0.0/stomp/connect.py --- old/stomp.py-6.1.0/stomp/connect.py 2020-04-13 13:32:44.543436500 +0200 +++ new/stomp.py-7.0.0/stomp/connect.py 1980-01-01 01:00:00.000000000 +0100 @@ -27,17 +27,19 @@ self.set_listener("ZZZZZ-disconnect-listener", self.disconnect_listener) return self + def disconnect(self, receipt=None, headers=None, **keyword_headers): pass + def __exit__(self, exc_type, exc_val, exc_tb): self.disconnect(self.disconnect_receipt_id) self.disconnect_listener.wait_on_receipt() self.disconnect_listener.wait_on_disconnected() - def set_listener(self, name, lstnr): + def set_listener(self, name, listener): """ :param str name: - :param ConnectionListener lstnr: + :param ConnectionListener listener: """ - self.transport.set_listener(name, lstnr) + self.transport.set_listener(name, listener) def remove_listener(self, name): """ @@ -94,12 +96,12 @@ auto_decode=True, encoding="utf-8", auto_content_length=True, - recv_bytes=1024): + bind_host_port=None): transport = Transport(host_and_ports, prefer_localhost, try_loopback_connect, reconnect_sleep_initial, reconnect_sleep_increase, reconnect_sleep_jitter, reconnect_sleep_max, reconnect_attempts_max, use_ssl, ssl_key_file, ssl_cert_file, ssl_ca_certs, ssl_cert_validator, ssl_version, timeout, - keepalive, None, auto_decode, encoding) + keepalive, None, auto_decode, encoding, bind_host_port=bind_host_port) BaseConnection.__init__(self, transport) Protocol10.__init__(self, transport, auto_content_length) @@ -148,14 +150,15 @@ encoding="utf-8", auto_content_length=True, heart_beat_receive_scale=1.5, - recv_byte=1024): + bind_host_port=None): transport = Transport(host_and_ports, prefer_localhost, try_loopback_connect, reconnect_sleep_initial, reconnect_sleep_increase, reconnect_sleep_jitter, reconnect_sleep_max, reconnect_attempts_max, use_ssl, ssl_key_file, ssl_cert_file, ssl_ca_certs, ssl_cert_validator, ssl_version, timeout, - keepalive, vhost, auto_decode, encoding) + keepalive, vhost, auto_decode, encoding, bind_host_port=bind_host_port) BaseConnection.__init__(self, transport) - Protocol11.__init__(self, transport, heartbeats, auto_content_length, heart_beat_receive_scale=heart_beat_receive_scale) + Protocol11.__init__(self, transport, heartbeats, auto_content_length, + heart_beat_receive_scale=heart_beat_receive_scale) def connect(self, *args, **kwargs): self.transport.start() @@ -202,14 +205,15 @@ encoding="utf-8", auto_content_length=True, heart_beat_receive_scale=1.5, - recv_bytes=1024): + bind_host_port=None): transport = Transport(host_and_ports, prefer_localhost, try_loopback_connect, reconnect_sleep_initial, reconnect_sleep_increase, reconnect_sleep_jitter, reconnect_sleep_max, reconnect_attempts_max, use_ssl, ssl_key_file, ssl_cert_file, ssl_ca_certs, ssl_cert_validator, ssl_version, timeout, - keepalive, vhost, auto_decode, encoding, is_eol_fc=self.is_eol) + keepalive, vhost, auto_decode, encoding, bind_host_port=bind_host_port) BaseConnection.__init__(self, transport) - Protocol12.__init__(self, transport, heartbeats, auto_content_length, heart_beat_receive_scale=heart_beat_receive_scale) + Protocol12.__init__(self, transport, heartbeats, auto_content_length, + heart_beat_receive_scale=heart_beat_receive_scale) def connect(self, *args, **kwargs): self.transport.start() @@ -227,5 +231,6 @@ if receipt is not None: self.transport.stop() - def is_eol(self, c): - return c == b'\x0a' or c == b'\x0d\x0a' \ No newline at end of file + @staticmethod + def is_eol(c): + return c == b"\x0a" or c == b"\x0d\x0a" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/exception.py new/stomp.py-7.0.0/stomp/exception.py --- old/stomp.py-6.1.0/stomp/exception.py 2020-01-11 22:51:04.332160000 +0100 +++ new/stomp.py-7.0.0/stomp/exception.py 1980-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,7 @@ """Errors thrown by stomp.py connections. """ + class StompException(Exception): """ Common exception class. All specific stomp.py exceptions are subclasses diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/listener.py new/stomp.py-7.0.0/stomp/listener.py --- old/stomp.py-6.1.0/stomp/listener.py 2020-04-08 20:52:36.609415300 +0200 +++ new/stomp.py-7.0.0/stomp/listener.py 1980-01-01 01:00:00.000000000 +0100 @@ -1,7 +1,6 @@ """Various listeners for using with stomp.py connections. """ -import os import sys import threading import time @@ -51,6 +50,7 @@ This class should be used as a base class for objects registered using Connection.set_listener(). """ + def on_connecting(self, host_and_port): """ Called by the STOMP connection once a TCP/IP connection to the @@ -64,14 +64,19 @@ """ pass - def on_connected(self, headers, body): + def on_connected(self, frame): """ Called by the STOMP connection when a CONNECTED frame is received (after a connection has been established or re-established). - :param dict headers: a dictionary containing all headers sent by the server as key/value pairs. - :param body: the frame's payload. This is usually empty for CONNECTED frames. + :param Frame frame: the stomp frame + """ + pass + + def on_disconnecting(self): + """ + Called before a DISCONNECT frame is sent. """ pass @@ -90,42 +95,38 @@ """ pass - def on_before_message(self, headers, body): + def on_before_message(self, frame): """ Called by the STOMP connection before a message is returned to the client app. Returns a tuple containing the headers and body (so that implementing listeners can pre-process the content). - :param dict headers: the message headers - :param body: the message body + :param Frame frame: the stomp frame """ - return headers, body + pass - def on_message(self, headers, body): + def on_message(self, frame): """ Called by the STOMP connection when a MESSAGE frame is received. - :param dict headers: a dictionary containing all headers sent by the server as key/value pairs. - :param body: the frame's payload - the message body. + :param Frame frame: the stomp frame """ pass - def on_receipt(self, headers, body): + def on_receipt(self, frame): """ Called by the STOMP connection when a RECEIPT frame is received, sent by the server if requested by the client using the 'receipt' header. - :param dict headers: a dictionary containing all headers sent by the server as key/value pairs. - :param body: the frame's payload. This is usually empty for RECEIPT frames. + :param Frame frame: the stomp frame """ pass - def on_error(self, headers, body): + def on_error(self, frame): """ Called by the STOMP connection when an ERROR frame is received. - :param dict headers: a dictionary containing all headers sent by the server as key/value pairs. - :param body: the frame's payload - usually a detailed error description. + :param Frame frame: the stomp frame """ pass @@ -133,7 +134,7 @@ """ Called by the STOMP connection when it is in the process of sending a message - :param Frame frame: the frame to be sent + :param Frame frame: the stomp frame """ pass @@ -143,7 +144,7 @@ """ pass - def on_receiver_loop_completed(self, headers, body): + def on_receiver_loop_completed(self, frame): """ Called when the connection receiver_loop has finished. """ @@ -163,19 +164,20 @@ self.next_outbound_heartbeat = None self.heart_beat_receive_scale = heart_beat_receive_scale self.heartbeat_terminate_event = threading.Event() + self.disconnecting = False - def on_connected(self, headers, body): + def on_connected(self, frame): """ Once the connection is established, and 'heart-beat' is found in the headers, we calculate the real heartbeat numbers (based on what the server sent and what was specified by the client) - if the heartbeats are not 0, we start up the heartbeat loop accordingly. - :param dict headers: headers in the connection message - :param body: the message body + :param Frame frame: the stomp frame """ - if "heart-beat" in headers: + self.disconnecting = False + if "heart-beat" in frame.headers: self.heartbeats = utils.calculate_heartbeats( - headers["heart-beat"].replace(' ', '').split(','), self.heartbeats) + frame.headers["heart-beat"].replace(" ", "").split(","), self.heartbeats) logging.debug("Heartbeats calculated %s", str(self.heartbeats)) if self.heartbeats != (0, 0): self.send_sleep = self.heartbeats[0] / 1000 @@ -200,12 +202,14 @@ self.running = False self.heartbeat_terminate_event.set() - def on_message(self, headers, body): + def on_disconnecting(self): + self.disconnecting = True + + def on_message(self, frame): """ Reset the last received time whenever a message is received. - :param dict headers: headers in the message - :param body: the message content + :param Frame frame: the stomp frame """ # reset the heartbeat for any received message self.__update_heartbeat() @@ -279,7 +283,7 @@ now = monotonic() - if not self.transport.is_connected(): + if not self.transport.is_connected() or self.disconnecting: time.sleep(self.send_sleep) continue @@ -299,7 +303,7 @@ if diff_receive > self.receive_sleep: # heartbeat timeout logging.warning("Heartbeat timeout: diff_receive=%s, time=%s, lastrec=%s", - diff_receive, now, self.received_heartbeat) + diff_receive, now, self.received_heartbeat) self.transport.set_connected(False) self.transport.disconnect_socket() self.transport.stop() @@ -326,14 +330,13 @@ self.received = False self.disconnected = False - def on_receipt(self, headers, body): + def on_receipt(self, frame): """ If the receipt id can be found in the headers, then notify the waiting thread. - :param dict headers: headers in the message - :param body: the message content + :param Frame frame: the stomp frame """ - if "receipt-id" in headers and headers["receipt-id"] == self.receipt: + if "receipt-id" in frame.headers and frame.headers["receipt-id"] == self.receipt: with self.receipt_condition: self.received = True self.receipt_condition.notify() @@ -360,6 +363,7 @@ while not self.disconnected: self.disconnect_condition.wait() + class StatsListener(ConnectionListener): """ A connection listener for recording statistics on messages sent and received. @@ -387,17 +391,16 @@ self.disconnects += 1 logging.info("disconnected (x %s)", self.disconnects) - def on_error(self, headers, body): + def on_error(self, frame): """ Increment the error count. See :py:meth:`ConnectionListener.on_error` - :param dict headers: headers in the message - :param body: the message content + :param Frame frame: the stomp frame """ if logging.isEnabledFor(logging.DEBUG): - logging.debug("received an error %s [%s]", body, headers) + logging.debug("received an error %s [%s]", frame.body, frame.headers) else: - logging.info("received an error %s", body) + logging.info("received an error %s", frame.body) self.errors += 1 def on_connecting(self, host_and_port): @@ -409,12 +412,11 @@ logging.info("connecting %s %s (x %s)", host_and_port[0], host_and_port[1], self.connections) self.connections += 1 - def on_message(self, headers, body): + def on_message(self, frame): """ Increment the message received count. See :py:meth:`ConnectionListener.on_message` - :param dict headers: headers in the message - :param body: the message content + :param Frame frame: the stomp frame """ self.messages += 1 @@ -449,7 +451,8 @@ Messages sent: %s Messages received: %s Heartbeats received: %s -Errors: %s''' % (self.connections, self.disconnects, self.messages_sent, self.messages, self.heartbeat_count, self.errors) +Errors: %s''' % (self.connections, self.disconnects, self.messages_sent, self.messages, + self.heartbeat_count, self.errors) class PrintingListener(ConnectionListener): @@ -468,12 +471,11 @@ """ self.__print("on_connecting %s %s", *host_and_port) - def on_connected(self, headers, body): + def on_connected(self, frame): """ - :param dict headers: - :param body: + :param Frame frame: the stomp frame """ - self.__print("on_connected %s %s", headers, body) + self.__print("on_connected %s %s", frame.headers, frame.body) def on_disconnected(self): self.__print("on_disconnected") @@ -481,38 +483,33 @@ def on_heartbeat_timeout(self): self.__print("on_heartbeat_timeout") - def on_before_message(self, headers, body): + def on_before_message(self, frame): """ - :param dict headers: - :param body: + :param Frame frame: the stomp frame """ - self.__print("on_before_message %s %s", headers, body) - return headers, body + self.__print("on_before_message %s %s", frame.headers, frame.body) - def on_message(self, headers, body): + def on_message(self, frame): """ - :param dict headers: - :param body: + :param Frame frame: the stomp frame """ - self.__print("on_message %s %s", headers, body) + self.__print("on_message %s %s", frame.headers, frame.body) - def on_receipt(self, headers, body): + def on_receipt(self, frame): """ - :param dict headers: - :param body: + :param Frame frame: the stomp frame """ - self.__print("on_receipt %s %s", headers, body) + self.__print("on_receipt %s %s", frame.headers, frame.body) - def on_error(self, headers, body): + def on_error(self, frame): """ - :param dict headers: - :param body: + :param Frame frame: the stomp frame """ - self.__print("on_error %s %s", headers, body) + self.__print("on_error %s %s", frame.headers, frame.body) def on_send(self, frame): """ - :param Frame frame: + :param Frame frame: the stomp frame """ self.__print("on_send %s %s %s", frame.cmd, utils.clean_headers(frame.headers), frame.body) @@ -553,16 +550,15 @@ self.heartbeat_condition.wait() self.heartbeat_received = False - def on_connecting(self, host_and_port): StatsListener.on_connecting(self, host_and_port) PrintingListener.on_connecting(self, host_and_port) WaitingListener.on_connecting(self, host_and_port) - def on_connected(self, headers, body): - StatsListener.on_connected(self, headers, body) - PrintingListener.on_connected(self, headers, body) - WaitingListener.on_connected(self, headers, body) + def on_connected(self, frame): + StatsListener.on_connected(self, frame) + PrintingListener.on_connected(self, frame) + WaitingListener.on_connected(self, frame) def on_disconnected(self): StatsListener.on_disconnected(self) @@ -574,32 +570,31 @@ PrintingListener.on_heartbeat_timeout(self) WaitingListener.on_heartbeat_timeout(self) - def on_before_message(self, headers, body): - StatsListener.on_before_message(self, headers, body) - PrintingListener.on_before_message(self, headers, body) - WaitingListener.on_before_message(self, headers, body) - - def on_message(self, headers, message): - """ - :param dict headers: - :param message: - """ - StatsListener.on_message(self, headers, message) - PrintingListener.on_message(self, headers, message) - self.message_list.append((headers, message)) + def on_before_message(self, frame): + StatsListener.on_before_message(self, frame) + PrintingListener.on_before_message(self, frame) + WaitingListener.on_before_message(self, frame) + + def on_message(self, frame): + """ + :param Frame frame: the stomp frame + """ + StatsListener.on_message(self, frame) + PrintingListener.on_message(self, frame) + self.message_list.append((frame.headers, frame.body)) with self.message_condition: self.message_received = True self.message_condition.notify() - def on_receipt(self, headers, body): - StatsListener.on_receipt(self, headers, body) - PrintingListener.on_receipt(self, headers, body) - WaitingListener.on_receipt(self, headers, body) - - def on_error(self, headers, body): - StatsListener.on_error(self, headers, body) - PrintingListener.on_error(self, headers, body) - WaitingListener.on_error(self, headers, body) + def on_receipt(self, frame): + StatsListener.on_receipt(self, frame) + PrintingListener.on_receipt(self, frame) + WaitingListener.on_receipt(self, frame) + + def on_error(self, frame): + StatsListener.on_error(self, frame) + PrintingListener.on_error(self, frame) + WaitingListener.on_error(self, frame) def on_send(self, frame): StatsListener.on_send(self, frame) @@ -613,7 +608,7 @@ self.heartbeat_received = True self.heartbeat_condition.notify() - def on_receiver_loop_completed(self, headers, body): - StatsListener.on_receiver_loop_completed(self, headers, body) - PrintingListener.on_receiver_loop_completed(self, headers, body) - WaitingListener.on_receiver_loop_completed(self, headers, body) + def on_receiver_loop_completed(self, frame): + StatsListener.on_receiver_loop_completed(self, frame) + PrintingListener.on_receiver_loop_completed(self, frame) + WaitingListener.on_receiver_loop_completed(self, frame) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/logging.py new/stomp.py-7.0.0/stomp/logging.py --- old/stomp.py-6.1.0/stomp/logging.py 2020-02-15 16:24:05.259170000 +0100 +++ new/stomp.py-7.0.0/stomp/logging.py 1980-01-01 01:00:00.000000000 +0100 @@ -3,6 +3,8 @@ DEBUG = logging.DEBUG INFO = logging.INFO +verbose = False + __logger = logging.getLogger("stomp.py") debug = __logger.debug info = __logger.info diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/protocol.py new/stomp.py-7.0.0/stomp/protocol.py --- old/stomp.py-6.1.0/stomp/protocol.py 2020-02-20 22:33:18.120868400 +0100 +++ new/stomp.py-7.0.0/stomp/protocol.py 1980-01-01 01:00:00.000000000 +0100 @@ -1,7 +1,6 @@ """Provides the 1.0, 1.1 and 1.2 protocol classes. """ -import stomp.utils as utils from stomp.exception import ConnectFailedException from stomp.listener import * @@ -13,7 +12,8 @@ Most users should not instantiate the protocol directly. See :py:mod:`stomp.connect` for connection classes. :param transport: - :param bool auto_content_length: Whether to calculate and send the content-length header automatically if it has not been set + :param bool auto_content_length: Whether to calculate and send the content-length header + automatically if it has not been set """ def __init__(self, transport, auto_content_length=True): self.transport = transport @@ -21,7 +21,7 @@ transport.set_listener("protocol-listener", self) self.version = "1.0" - def send_frame(self, cmd, headers=None, body=''): + def send_frame(self, cmd, headers=None, body=""): """ Encode and send a stomp frame through the underlying transport. @@ -206,8 +206,10 @@ :param transport: :param (int,int) heartbeats: - :param bool auto_content_length: Whether to calculate and send the content-length header automatically if it has not been set - :param float heart_beat_receive_scale: how long to wait for a heartbeat before timing out, as a scale factor of receive time + :param bool auto_content_length: Whether to calculate and send the content-length header + automatically if it has not been set + :param float heart_beat_receive_scale: how long to wait for a heartbeat before timing out, + as a scale factor of receive time """ def __init__(self, transport, heartbeats=(0, 0), auto_content_length=True, heart_beat_receive_scale=1.5): HeartbeatListener.__init__(self, transport, heartbeats, heart_beat_receive_scale) @@ -227,7 +229,7 @@ pass headers[key] = val - def send_frame(self, cmd, headers=None, body=''): + def send_frame(self, cmd, headers=None, body=""): """ Encode and send a stomp frame through the underlying transport: @@ -377,9 +379,11 @@ def send(self, destination, body, content_type=None, headers=None, **keyword_headers): """ - Send a message to a destination in the messaging system (as per https://stomp.github.io/stomp-specification-1.2.html#SEND) + Send a message to a destination in the messaging system (as per + https://stomp.github.io/stomp-specification-1.2.html#SEND) - :param str destination: the destination (such as a message queue - for example '/queue/test' - or a message topic) + :param str destination: the destination (such as a message queue - for example + '/queue/test' - or a message topic) :param body: the content of the message :param str content_type: the MIME type of message :param dict headers: additional headers to send in the message frame @@ -401,7 +405,8 @@ :param str destination: the topic or queue to subscribe to :param str id: the identifier to uniquely identify the subscription - :param str ack: either auto, client or client-individual (see https://stomp.github.io/stomp-specification-1.2.html#SUBSCRIBE for more info) + :param str ack: either auto, client or client-individual + (see https://stomp.github.io/stomp-specification-1.2.html#SUBSCRIBE for more info) :param dict headers: a map of any additional headers to send with the subscription :param keyword_headers: any additional headers to send with the subscription """ @@ -435,11 +440,14 @@ :param transport: :param (int,int) heartbeats: - :param bool auto_content_length: Whether to calculate and send the content-length header automatically if it has not been set - :param float heart_beat_receive_scale: how long to wait for a heartbeat before timing out, as a scale factor of receive time + :param bool auto_content_length: Whether to calculate and send the content-length header + automatically if it has not been set + :param float heart_beat_receive_scale: how long to wait for a heartbeat before timing out, + as a scale factor of receive time """ def __init__(self, transport, heartbeats=(0, 0), auto_content_length=True, heart_beat_receive_scale=1.5): - Protocol11.__init__(self, transport, heartbeats, auto_content_length, heart_beat_receive_scale=heart_beat_receive_scale) + Protocol11.__init__(self, transport, heartbeats, auto_content_length, + heart_beat_receive_scale=heart_beat_receive_scale) self.version = "1.2" def _escape_headers(self, headers): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/transport.py new/stomp.py-7.0.0/stomp/transport.py --- old/stomp.py-6.1.0/stomp/transport.py 2020-04-13 13:32:44.547436700 +0200 +++ new/stomp.py-7.0.0/stomp/transport.py 1980-01-01 01:00:00.000000000 +0100 @@ -1,4 +1,5 @@ -"""Provides the underlying transport functionality (for stomp message transmission) - (mostly) independent from the actual STOMP protocol +"""Provides the underlying transport functionality (for stomp message transmission) - (mostly) independent +from the actual STOMP protocol """ import errno @@ -18,9 +19,11 @@ except (ImportError, AttributeError): ssl = None + class SSLError(object): pass + DEFAULT_SSL_VERSION = None try: @@ -55,18 +58,19 @@ __content_length_re = re.compile(b"^content-length[:]\\s*(?P<value>[0-9]+)", re.MULTILINE) def __init__(self, auto_decode=True, encoding="utf-8", is_eol_fc=is_eol_default): - self.__recvbuf = b'' + self.__recvbuf = b"" self.listeners = {} self.running = False self.blocking = None self.connected = False self.connection_error = False + self.disconnecting = False self.__receipts = {} self.current_host_and_port = None - + self.bind_host_port = None # flag used when we receive the disconnect receipt self.__disconnect_receipt = None - self.__notified_on_disconnect = False + self.notified_on_disconnect = False # function for creating threads used by the connection self.create_thread_fc = default_create_thread @@ -129,6 +133,7 @@ with self.__connect_wait_condition: self.connected = connected if connected: + self.disconnecting = False self.__connect_wait_condition.notify() def set_receipt(self, receipt_id, value): @@ -180,26 +185,25 @@ frame_type = f.cmd.lower() if frame_type in ["connected", "message", "receipt", "error", "heartbeat"]: if frame_type == "message": - (f.headers, f.body) = self.notify("before_message", f.headers, f.body) + self.notify("before_message", f) if logging.isEnabledFor(logging.DEBUG): logging.debug("Received frame: %r, headers=%r, body=%r", f.cmd, f.headers, f.body) else: logging.info("Received frame: %r, len(body)=%r", f.cmd, length(f.body)) - self.notify(frame_type, f.headers, f.body) + self.notify(frame_type, f) else: logging.warning("Unknown response frame type: '%s' (frame length was %d)", frame_type, length(frame_str)) - def notify(self, frame_type, headers=None, body=None): + def notify(self, frame_type, frame=None): """ Utility function for notifying listeners of incoming and outgoing messages :param str frame_type: the type of message - :param dict headers: the map of headers associated with the message - :param body: the content of the message + :param Frame frame: the stomp frame """ if frame_type == "receipt": # logic for wait-on-receipt notification - receipt = headers["receipt-id"] + receipt = frame.headers["receipt-id"] receipt_value = self.__receipts.get(receipt) with self.__send_wait_condition: self.set_receipt(receipt, None) @@ -216,7 +220,7 @@ self.set_connected(True) elif frame_type == "disconnected": - self.__notified_on_disconnect = True + self.notified_on_disconnect = True self.set_connected(False) with self.__listeners_change_condition: @@ -239,10 +243,7 @@ self.connection_error = True self.__connect_wait_condition.notify() - rtn = notify_func(headers, body) - if rtn: - (headers, body) = rtn - return (headers, body) + notify_func(frame) def transmit(self, frame): """ @@ -348,7 +349,7 @@ # # Clear out any half-received messages after losing connection # - self.__recvbuf = b'' + self.__recvbuf = b"" self.running = False notify_disconnected = True break @@ -360,10 +361,11 @@ self.__receiver_thread_exit_condition.notifyAll() logging.info("Receiver loop ended") self.notify("receiver_loop_completed") - if notify_disconnected and not self.__notified_on_disconnect: + if notify_disconnected and not self.notified_on_disconnect: self.notify("disconnected") with self.__connect_wait_condition: self.__connect_wait_condition.notifyAll() + self.notified_on_disconnect = False def __read(self): """ @@ -381,8 +383,8 @@ logging.debug("socket read interrupted, restarting") continue except Exception: - logging.debug("socket read error", exc_info=True) - c = b'' + logging.debug("socket read error", exc_info=logging.verbose) + c = b"" if c is None or len(c) == 0: logging.debug("nothing received, raising CCE") raise exception.ConnectionClosedException() @@ -396,7 +398,7 @@ fastbuf.close() return [c] fastbuf.write(c) - if b'\x00' in c: + if b"\x00" in c: # # Possible end of frame # @@ -407,7 +409,7 @@ if self.__recvbuf and self.running: while True: - pos = self.__recvbuf.find(b'\x00') + pos = self.__recvbuf.find(b"\x00") if pos >= 0: frame = self.__recvbuf[0:pos] @@ -515,11 +517,12 @@ auto_decode=True, encoding="utf-8", recv_bytes=1024, - is_eol_fc=is_eol_default - ): + is_eol_fc=is_eol_default, + bind_host_port=None): BaseTransport.__init__(self, auto_decode, encoding, is_eol_fc) if host_and_ports is None: + logging.debug("No hosts_and_ports specified, adding default localhost") host_and_ports = [("localhost", 61613)] sorted_host_and_ports = [] @@ -542,7 +545,8 @@ for host_and_port in sorted_host_and_ports: if is_localhost(host_and_port) == 1: port = host_and_port[1] - if not (("127.0.0.1", port) in sorted_host_and_ports or ("localhost", port) in sorted_host_and_ports): + if not (("127.0.0.1", port) in sorted_host_and_ports or ( + "localhost", port) in sorted_host_and_ports): loopback_host_and_ports.append(("127.0.0.1", port)) # @@ -551,6 +555,7 @@ self.__host_and_ports = [] self.__host_and_ports.extend(loopback_host_and_ports) self.__host_and_ports.extend(sorted_host_and_ports) + self.__bind_host_port = bind_host_port self.__reconnect_sleep_initial = reconnect_sleep_initial self.__reconnect_sleep_increase = reconnect_sleep_increase @@ -628,7 +633,8 @@ logging.warning("Unable to close socket because of error '%s'", e) self.current_host_and_port = None self.socket = None - self.notify("disconnected") + if not self.notified_on_disconnect: + self.notify("disconnected") def send(self, encoded_frame): """ @@ -640,7 +646,7 @@ self.socket.sendall(encoded_frame) except Exception: _, e, _ = sys.exc_info() - logging.error("Error sending frame", exc_info=1) + logging.error("Error sending frame", exc_info=True) raise e else: raise exception.NotConnectedException() @@ -728,13 +734,15 @@ connect_count = 0 logging.info("attempt reconnection (%s, %s, %s)", self.running, self.socket, connect_count) - while self.running and self.socket is None and ( - connect_count < self.__reconnect_attempts_max or - self.__reconnect_attempts_max == -1 ): + while self.running and self.socket is None and (connect_count < self.__reconnect_attempts_max or + self.__reconnect_attempts_max == -1): for host_and_port in self.__host_and_ports: try: logging.info("Attempting connection to host %s, port %s", host_and_port[0], host_and_port[1]) - self.socket = socket.create_connection(host_and_port, self.__timeout) + if self.__bind_host_port: + self.socket = socket.create_connection(host_and_port, self.__timeout, self.__bind_host_port) + else: + self.socket = socket.create_connection(host_and_port, self.__timeout) self.__enable_keepalive() need_ssl = self.__need_ssl(host_and_port) @@ -791,7 +799,8 @@ except socket.error: self.socket = None connect_count += 1 - logging.warning("Could not connect to host %s, port %s", host_and_port[0], host_and_port[1], exc_info=1) + logging.warning("Could not connect to host %s, port %s", host_and_port[0], host_and_port[1], + exc_info=logging.verbose) if self.socket is None: sleep_duration = (min(self.__reconnect_sleep_max, @@ -834,6 +843,7 @@ as returned by ssl.SSLSocket.getpeercert() :param ssl_version: SSL protocol to use for the connection. This should be one of the PROTOCOL_x constants provided by the ssl module. The default is ssl.PROTOCOL_TLSv1 + :param password: SSL password """ if not ssl: raise Exception("SSL connection requested, but SSL library not found") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stomp.py-6.1.0/stomp/utils.py new/stomp.py-7.0.0/stomp/utils.py --- old/stomp.py-6.1.0/stomp/utils.py 2020-04-13 13:32:44.547436700 +0200 +++ new/stomp.py-7.0.0/stomp/utils.py 1980-01-01 01:00:00.000000000 +0100 @@ -16,7 +16,7 @@ # preferred targets. LOCALHOST_NAMES = ["localhost", "127.0.0.1"] -NULL = b'\x00' +NULL = b"\x00" if not os.environ.get("STOMP_SKIP_HOSTNAME_SCAN"): try: @@ -40,6 +40,7 @@ Decode the byte data to a string if not None. :param bytes byte_data: the data to decode + :param string encoding: character encoding :rtype: str """ @@ -53,6 +54,7 @@ Encode the parameter as a byte string. :param char_data: the data to encode + :param string encoding: character encoding :rtype: bytes """ @@ -72,7 +74,7 @@ :rtype: bytes """ - return b''.join(pieces) + return b"".join(pieces) def join(chars=()): @@ -83,11 +85,12 @@ :rtype: str """ - return b''.join(chars).decode() + return b"".join(chars).decode() def is_eol_default(c): - return c == b'\x0a' + return c == b"\x0a" + ## # Used to parse STOMP header lines in the format "key:value", @@ -143,10 +146,10 @@ _HEADER_ESCAPES = { - '\r': '\\r', - '\n': '\\n', - ':': '\\c', - '\\': '\\\\', + "\r": "\\r", + "\n": "\\n", + ":": "\\c", + "\\": "\\\\", } _HEADER_UNESCAPES = dict((value, key) for (key, value) in _HEADER_ESCAPES.items()) @@ -174,10 +177,10 @@ header_match = HEADER_LINE_RE.match(header_line) if header_match: key = header_match.group("key") - key = re.sub(r'\\.', _unescape_header, key) + key = re.sub(r"\\.", _unescape_header, key) if key not in headers: value = header_match.group("value") - value = re.sub(r'\\.', _unescape_header, value) + value = re.sub(r"\\.", _unescape_header, value) headers[key] = value return headers @@ -190,7 +193,6 @@ :rtype: Frame """ - f = Frame() mat = PREAMBLE_END_RE.search(frame) if mat: preamble_end = mat.start() @@ -201,7 +203,7 @@ preamble = decode(frame[0:preamble_end]) preamble_lines = LINE_END_RE.split(preamble) preamble_len = len(preamble_lines) - f.body = frame[body_start:] + body = frame[body_start:] # Skip any leading newlines first_line = 0 @@ -212,12 +214,12 @@ return None # Extract frame type/command - f.cmd = preamble_lines[first_line] + cmd = preamble_lines[first_line] # Put headers into a key/value map - f.headers = parse_headers(preamble_lines, first_line + 1) + headers = parse_headers(preamble_lines, first_line + 1) - return f + return Frame(cmd, headers, body) def merge_headers(header_map_list): @@ -262,9 +264,9 @@ (cx, cy) = chb x = 0 y = 0 - if cx != 0 and sy != '0': + if cx != 0 and sy != "0": x = max(cx, int(sy)) - if cy != 0 and sx != '0': + if cy != 0 and sx != "0": y = max(cy, int(sx)) return x, y @@ -326,9 +328,10 @@ :param dict headers: a map of headers for the frame :param body: the content of the frame. """ - def __init__(self, cmd=None, headers=None, body=None): + def __init__(self, cmd, headers=None, body=None): self.cmd = cmd self.headers = headers if headers is not None else {} + self.original_headers = copy.copy(self.headers) self.body = body def __str__(self): @@ -351,4 +354,4 @@ return e.args[0] -HEARTBEAT_FRAME = Frame("heartbeat") \ No newline at end of file +HEARTBEAT_FRAME = Frame("heartbeat")