From 82479dfc1899acfcc7f7a34bed69f3513cdd8b35 Mon Sep 17 00:00:00 2001 From: Nicolas Jouanin Date: Thu, 18 Jun 2015 10:22:46 +0200 Subject: [PATCH] Add Unsuscribe packet --- hbmqtt/mqtt/unsubscribe.py | 48 ++++++++++++++++++++++++++++++++++ tests/mqtt/test_unsubscribe.py | 29 ++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 hbmqtt/mqtt/unsubscribe.py create mode 100644 tests/mqtt/test_unsubscribe.py diff --git a/hbmqtt/mqtt/unsubscribe.py b/hbmqtt/mqtt/unsubscribe.py new file mode 100644 index 0000000..ef7724c --- /dev/null +++ b/hbmqtt/mqtt/unsubscribe.py @@ -0,0 +1,48 @@ +# Copyright (c) 2015 Nicolas JOUANIN +# +# See the file license.txt for copying permission. +from hbmqtt.mqtt.packet import MQTTPacket, MQTTFixedHeader, PacketType, PacketIdVariableHeader, MQTTPayload, MQTTVariableHeader +from hbmqtt.errors import HBMQTTException +from hbmqtt.codecs import * + + +class UnubscribePayload(MQTTPayload): + def __init__(self, topics=[]): + super().__init__() + self.topics = topics + + def to_bytes(self, fixed_header: MQTTFixedHeader, variable_header: MQTTVariableHeader): + out = b'' + for topic in self.topics: + out += encode_string(topic) + return out + + @classmethod + @asyncio.coroutine + def from_stream(cls, reader: asyncio.StreamReader, fixed_header: MQTTFixedHeader, + variable_header: MQTTVariableHeader): + topics = [] + while True: + try: + topic = yield from decode_string(reader) + topics.append(topic) + except NoDataException: + break + return cls(topics) + + +class UnsubscribePacket(MQTTPacket): + VARIABLE_HEADER = PacketIdVariableHeader + PAYLOAD = UnubscribePayload + + def __init__(self, fixed: MQTTFixedHeader=None, variable_header: PacketIdVariableHeader=None, payload=None): + if fixed is None: + header = MQTTFixedHeader(PacketType.UNSUBSCRIBE, 0x00) + else: + if fixed.packet_type is not PacketType.UNSUBSCRIBE: + raise HBMQTTException("Invalid fixed packet type %s for UnsubscribePacket init" % fixed.packet_type) + header = fixed + + super().__init__(header) + self.variable_header = variable_header + self.payload = payload diff --git a/tests/mqtt/test_unsubscribe.py b/tests/mqtt/test_unsubscribe.py new file mode 100644 index 0000000..274da6d --- /dev/null +++ b/tests/mqtt/test_unsubscribe.py @@ -0,0 +1,29 @@ +# Copyright (c) 2015 Nicolas JOUANIN +# +# See the file license.txt for copying permission. +import unittest + +from hbmqtt.mqtt.unsubscribe import UnsubscribePacket, UnubscribePayload +from hbmqtt.mqtt.packet import PacketIdVariableHeader +from hbmqtt.codecs import * + +class SubscribePacketTest(unittest.TestCase): + def setUp(self): + self.loop = asyncio.new_event_loop() + + def test_from_stream(self): + data = b'\xa0\x0c\x00\n\x00\x03a/b\x00\x03c/d' + stream = asyncio.StreamReader(loop=self.loop) + stream.feed_data(data) + stream.feed_eof() + message = self.loop.run_until_complete(UnsubscribePacket.from_stream(stream)) + self.assertEqual(message.payload.topics[0], 'a/b') + self.assertEqual(message.payload.topics[1], 'c/d') + + def test_to_stream(self): + variable_header = PacketIdVariableHeader(10) + payload = UnubscribePayload(['a/b', 'c/d']) + publish = UnsubscribePacket(variable_header=variable_header, payload=payload) + out = publish.to_bytes() + print(out) + self.assertEqual(out, b'\xa0\x0c\x00\n\x00\x03a/b\x00\x03c/d') \ No newline at end of file