Example #1
0
async def test_multiple_channels(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    ch1 = 'test-where-now-asyncio-ch1'
    ch2 = 'test-where-now-asyncio-ch2'
    uuid = 'test-where-now-asyncio-uuid'
    pubnub.config.uuid = uuid

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels([ch1, ch2]).execute()

    await callback.wait_for_connect()

    await sleeper(7)

    env = await pubnub.where_now() \
        .uuid(uuid) \
        .future()

    channels = env.result.channels

    assert len(channels) == 2
    assert ch1 in channels
    assert ch2 in channels

    pubnub.unsubscribe().channels([ch1, ch2]).execute()
    await callback.wait_for_disconnect()

    await pubnub.stop()
async def test_timeout_event_on_broken_heartbeat(event_loop):
    ch = helper.gen_channel("heartbeat-test")

    pubnub = PubNubAsyncio(messenger_config, custom_event_loop=event_loop)
    pubnub_listener = PubNubAsyncio(listener_config,
                                    custom_event_loop=event_loop)

    pubnub.config.uuid = helper.gen_channel("messenger")
    pubnub_listener.config.uuid = helper.gen_channel("listener")

    # - connect to :ch-pnpres
    callback_presence = SubscribeListener()
    pubnub_listener.add_listener(callback_presence)
    pubnub_listener.subscribe().channels(ch).with_presence().execute()
    await callback_presence.wait_for_connect()

    envelope = await callback_presence.wait_for_presence_on(ch)
    assert ch == envelope.channel
    assert 'join' == envelope.event
    assert pubnub_listener.uuid == envelope.uuid

    # - connect to :ch
    callback_messages = SubscribeListener()
    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channels(ch).execute()

    useless_connect_future = callback_messages.wait_for_connect()
    presence_future = asyncio.ensure_future(
        callback_presence.wait_for_presence_on(ch))

    # - assert join event
    await asyncio.wait([useless_connect_future, presence_future])

    prs_envelope = presence_future.result()

    assert ch == prs_envelope.channel
    assert 'join' == prs_envelope.event
    assert pubnub.uuid == prs_envelope.uuid

    # wait for one heartbeat call
    await asyncio.sleep(8)

    # - break messenger heartbeat loop
    pubnub._subscription_manager._stop_heartbeat_timer()

    # - assert for timeout
    envelope = await callback_presence.wait_for_presence_on(ch)
    assert ch == envelope.channel
    assert 'timeout' == envelope.event
    assert pubnub.uuid == envelope.uuid

    pubnub.unsubscribe().channels(ch).execute()
    await callback_messages.wait_for_disconnect()

    # - disconnect from :ch-pnpres
    pubnub_listener.unsubscribe().channels(ch).execute()
    await callback_presence.wait_for_disconnect()

    await pubnub.stop()
    await pubnub_listener.stop()
async def test_cg_subscribe_unsubscribe(event_loop, sleeper=asyncio.sleep):
    ch = "test-subscribe-asyncio-channel"
    gr = "test-subscribe-asyncio-group"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    envelope = await pubnub.add_channel_to_channel_group().channel_group(
        gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await sleeper(3)

    callback_messages = SubscribeListener()
    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channel_groups(gr).execute()
    await callback_messages.wait_for_connect()

    pubnub.unsubscribe().channel_groups(gr).execute()
    await callback_messages.wait_for_disconnect()

    envelope = await pubnub.remove_channel_from_channel_group().channel_group(
        gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await pubnub.stop()
Example #4
0
def test_multiple_channels(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    ch1 = 'test-where-now-asyncio-ch1'
    ch2 = 'test-where-now-asyncio-ch2'
    uuid = 'test-where-now-asyncio-uuid'
    pubnub.config.uuid = uuid

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels([ch1, ch2]).execute()

    yield from callback.wait_for_connect()

    yield from sleeper(7)

    env = yield from pubnub.where_now() \
        .uuid(uuid) \
        .future()

    channels = env.result.channels

    assert len(channels) == 2
    assert ch1 in channels
    assert ch2 in channels

    pubnub.unsubscribe().channels([ch1, ch2]).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
async def test_subscribe_unsubscribe(event_loop):
    channel = "test-subscribe-asyncio-ch"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    callback = SubscribeListener()
    pubnub.add_listener(callback)

    pubnub.subscribe().channels(channel).execute()
    assert channel in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 1

    await callback.wait_for_connect()
    assert channel in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 1

    pubnub.unsubscribe().channels(channel).execute()
    assert channel not in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 0

    # await callback.wait_for_disconnect()
    assert channel not in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 0

    await pubnub.stop()
Example #6
0
def test_single_channel_with_subscription(event_loop, sleeper=asyncio.sleep):
    pnconf = pnconf_sub_copy()
    pnconf.set_presence_timeout(12)
    pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop)
    ch = 'test-state-asyncio-ch'
    pubnub.config.uuid = 'test-state-asyncio-uuid'
    state = {"name": "Alex", "count": 5}

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels(ch).execute()

    yield from callback.wait_for_connect()
    yield from sleeper(20)

    env = yield from pubnub.set_state() \
        .channels(ch) \
        .state(state) \
        .future()

    assert env.result.state['name'] == "Alex"
    assert env.result.state['count'] == 5

    env = yield from pubnub.get_state() \
        .channels(ch) \
        .future()

    assert env.result.channels[ch]['name'] == "Alex"
    assert env.result.channels[ch]['count'] == 5

    pubnub.unsubscribe().channels(ch).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
Example #7
0
def test_single_channel_with_subscription(event_loop, sleeper=asyncio.sleep):
    pnconf = pnconf_sub_copy()
    pnconf.set_presence_timeout(12)
    pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop)
    ch = "test-state-asyncio-ch"
    pubnub.config.uuid = "test-state-asyncio-uuid"
    state = {"name": "Alex", "count": 5}

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels(ch).execute()

    yield from callback.wait_for_connect()
    yield from sleeper(20)

    env = yield from pubnub.set_state().channels(ch).state(state).future()

    assert env.result.state["name"] == "Alex"
    assert env.result.state["count"] == 5

    env = yield from pubnub.get_state().channels(ch).future()

    assert env.result.channels[ch]["name"] == "Alex"
    assert env.result.channels[ch]["count"] == 5

    pubnub.unsubscribe().channels(ch).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
Example #8
0
def test_subscribe_unsubscribe(event_loop):
    channel = "test-subscribe-asyncio-ch"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    callback = SubscribeListener()
    pubnub.add_listener(callback)

    pubnub.subscribe().channels(channel).execute()
    assert channel in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 1

    yield from callback.wait_for_connect()
    assert channel in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 1

    pubnub.unsubscribe().channels(channel).execute()
    assert channel not in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 0

    yield from callback.wait_for_disconnect()
    assert channel not in pubnub.get_subscribed_channels()
    assert len(pubnub.get_subscribed_channels()) == 0

    pubnub.stop()
Example #9
0
def test_single_channel(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    ch = 'test-where-now-asyncio-ch'
    uuid = 'test-where-now-asyncio-uuid'
    pubnub.config.uuid = uuid

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels(ch).execute()

    yield from callback.wait_for_connect()

    yield from sleeper(2)

    env = yield from pubnub.where_now() \
        .uuid(uuid) \
        .future()

    channels = env.result.channels

    assert len(channels) == 1
    assert channels[0] == ch

    pubnub.unsubscribe().channels(ch).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
Example #10
0
def test_timeout_event_on_broken_heartbeat(event_loop):
    ch = helper.gen_channel("heartbeat-test")

    pubnub = PubNubAsyncio(messenger_config, custom_event_loop=event_loop)
    pubnub_listener = PubNubAsyncio(listener_config, custom_event_loop=event_loop)

    pubnub.config.uuid = helper.gen_channel("messenger")
    pubnub_listener.config.uuid = helper.gen_channel("listener")

    # - connect to :ch-pnpres
    callback_presence = SubscribeListener()
    pubnub_listener.add_listener(callback_presence)
    pubnub_listener.subscribe().channels(ch).with_presence().execute()
    yield from callback_presence.wait_for_connect()

    envelope = yield from callback_presence.wait_for_presence_on(ch)
    assert ch == envelope.channel
    assert 'join' == envelope.event
    assert pubnub_listener.uuid == envelope.uuid

    # - connect to :ch
    callback_messages = SubscribeListener()
    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channels(ch).execute()

    useless_connect_future = callback_messages.wait_for_connect()
    presence_future = asyncio.ensure_future(callback_presence.wait_for_presence_on(ch))

    # - assert join event
    yield from asyncio.wait([useless_connect_future, presence_future])

    prs_envelope = presence_future.result()

    assert ch == prs_envelope.channel
    assert 'join' == prs_envelope.event
    assert pubnub.uuid == prs_envelope.uuid

    # wait for one heartbeat call
    yield from asyncio.sleep(8)

    # - break messenger heartbeat loop
    pubnub._subscription_manager._stop_heartbeat_timer()

    # - assert for timeout
    envelope = yield from callback_presence.wait_for_presence_on(ch)
    assert ch == envelope.channel
    assert 'timeout' == envelope.event
    assert pubnub.uuid == envelope.uuid

    pubnub.unsubscribe().channels(ch).execute()
    yield from callback_messages.wait_for_disconnect()

    # - disconnect from :ch-pnpres
    pubnub_listener.unsubscribe().channels(ch).execute()
    yield from callback_presence.wait_for_disconnect()

    pubnub.stop()
    pubnub_listener.stop()
Example #11
0
def async_create_pubnub(user_uuid, subscriptions):
    """Create a pubnub subscription."""
    pnconfig = PNConfiguration()
    pnconfig.subscribe_key = AUGUST_CHANNEL
    pnconfig.uuid = f"pn-{str(user_uuid).upper()}"
    pubnub = PubNubAsyncio(pnconfig)
    pubnub.add_listener(subscriptions)
    pubnub.subscribe().channels(subscriptions.channels).execute()

    def _unsub():
        pubnub.unsubscribe().channels(subscriptions.channels).execute()

    return _unsub
async def test_join_leave(event_loop):
    channel = "test-subscribe-asyncio-join-leave-ch"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub_listener = PubNubAsyncio(pnconf_sub_copy(),
                                    custom_event_loop=event_loop)

    patch_pubnub(pubnub)
    patch_pubnub(pubnub_listener)

    pubnub.config.uuid = "test-subscribe-asyncio-messenger"
    pubnub_listener.config.uuid = "test-subscribe-asyncio-listener"

    callback_presence = VCR599Listener(1)
    callback_messages = VCR599Listener(1)

    pubnub_listener.add_listener(callback_presence)
    pubnub_listener.subscribe().channels(channel).with_presence().execute()

    await callback_presence.wait_for_connect()

    envelope = await callback_presence.wait_for_presence_on(channel)
    assert envelope.channel == channel
    assert envelope.event == 'join'
    assert envelope.uuid == pubnub_listener.uuid

    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channels(channel).execute()
    await callback_messages.wait_for_connect()

    envelope = await callback_presence.wait_for_presence_on(channel)
    assert envelope.channel == channel
    assert envelope.event == 'join'
    assert envelope.uuid == pubnub.uuid

    pubnub.unsubscribe().channels(channel).execute()
    await callback_messages.wait_for_disconnect()

    envelope = await callback_presence.wait_for_presence_on(channel)

    assert envelope.channel == channel
    assert envelope.event == 'leave'
    assert envelope.uuid == pubnub.uuid

    pubnub_listener.unsubscribe().channels(channel).execute()
    await callback_presence.wait_for_disconnect()

    await pubnub.stop()
    pubnub_listener.stop()
Example #13
0
def test_access_denied_unsubscribe_operation(event_loop):
    channel = "not-permitted-channel"
    pnconf = pnconf_pam_copy()
    pnconf.secret_key = None
    pnconf.enable_subscribe = True

    pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop)

    callback = AccessDeniedListener()
    pubnub.add_listener(callback)

    pubnub.subscribe().channels(channel).execute()
    yield from callback.access_denied_event.wait()

    pubnub.stop()
def test_access_denied_unsubscribe_operation(event_loop):
    channel = "not-permitted-channel"
    pnconf = pnconf_pam_copy()
    pnconf.secret_key = None
    pnconf.enable_subscribe = True

    pubnub = PubNubAsyncio(pnconf, custom_event_loop=event_loop)

    callback = AccessDeniedListener()
    pubnub.add_listener(callback)

    pubnub.subscribe().channels(channel).execute()
    yield from callback.access_denied_event.wait()

    pubnub.stop()
Example #15
0
def test_join_leave(event_loop):
    channel = "test-subscribe-asyncio-join-leave-ch"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub_listener = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    patch_pubnub(pubnub)
    patch_pubnub(pubnub_listener)

    pubnub.config.uuid = "test-subscribe-asyncio-messenger"
    pubnub_listener.config.uuid = "test-subscribe-asyncio-listener"

    callback_presence = VCR599Listener(1)
    callback_messages = VCR599Listener(1)

    pubnub_listener.add_listener(callback_presence)
    pubnub_listener.subscribe().channels(channel).with_presence().execute()

    yield from callback_presence.wait_for_connect()

    envelope = yield from callback_presence.wait_for_presence_on(channel)
    assert envelope.channel == channel
    assert envelope.event == 'join'
    assert envelope.uuid == pubnub_listener.uuid

    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channels(channel).execute()
    yield from callback_messages.wait_for_connect()

    envelope = yield from callback_presence.wait_for_presence_on(channel)
    assert envelope.channel == channel
    assert envelope.event == 'join'
    assert envelope.uuid == pubnub.uuid

    pubnub.unsubscribe().channels(channel).execute()
    yield from callback_messages.wait_for_disconnect()

    envelope = yield from callback_presence.wait_for_presence_on(channel)

    assert envelope.channel == channel
    assert envelope.event == 'leave'
    assert envelope.uuid == pubnub.uuid

    pubnub_listener.unsubscribe().channels(channel).execute()
    yield from callback_presence.wait_for_disconnect()

    pubnub.stop()
    pubnub_listener.stop()
async def test_unsubscribe_all(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    pubnub.config.uuid = "test-subscribe-asyncio-messenger"

    ch = "test-subscribe-asyncio-unsubscribe-all-ch"
    ch1 = "test-subscribe-asyncio-unsubscribe-all-ch1"
    ch2 = "test-subscribe-asyncio-unsubscribe-all-ch2"
    ch3 = "test-subscribe-asyncio-unsubscribe-all-ch3"
    gr1 = "test-subscribe-asyncio-unsubscribe-all-gr1"
    gr2 = "test-subscribe-asyncio-unsubscribe-all-gr2"

    envelope = await pubnub.add_channel_to_channel_group().channel_group(
        gr1).channels(ch).future()
    assert envelope.status.original_response['status'] == 200
    envelope = await pubnub.add_channel_to_channel_group().channel_group(
        gr2).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await sleeper(1)

    callback_messages = VCR599Listener(1)
    pubnub.add_listener(callback_messages)

    pubnub.subscribe().channels([ch1, ch2,
                                 ch3]).channel_groups([gr1, gr2]).execute()
    await callback_messages.wait_for_connect()

    assert len(pubnub.get_subscribed_channels()) == 3
    assert len(pubnub.get_subscribed_channel_groups()) == 2

    pubnub.unsubscribe_all()

    await callback_messages.wait_for_disconnect()

    assert len(pubnub.get_subscribed_channels()) == 0
    assert len(pubnub.get_subscribed_channel_groups()) == 0

    envelope = await pubnub.remove_channel_from_channel_group().channel_group(
        gr1).channels(ch).future()
    assert envelope.status.original_response['status'] == 200
    envelope = await pubnub.remove_channel_from_channel_group().channel_group(
        gr2).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await pubnub.stop()
Example #17
0
def test_subscribe_publish_unsubscribe(event_loop):
    pubnub_sub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub_pub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    patch_pubnub(pubnub_sub)
    patch_pubnub(pubnub_pub)

    pubnub_sub.config.uuid = 'test-subscribe-asyncio-uuid-sub'
    pubnub_pub.config.uuid = 'test-subscribe-asyncio-uuid-pub'

    callback = VCR599Listener(1)
    channel = "test-subscribe-asyncio-ch"
    message = "hey"
    pubnub_sub.add_listener(callback)
    pubnub_sub.subscribe().channels(channel).execute()

    yield from callback.wait_for_connect()

    publish_future = asyncio.ensure_future(pubnub_pub.publish().channel(channel).message(message).future())
    subscribe_message_future = asyncio.ensure_future(callback.wait_for_message_on(channel))

    yield from asyncio.wait([
        publish_future,
        subscribe_message_future
    ])

    publish_envelope = publish_future.result()
    subscribe_envelope = subscribe_message_future.result()

    assert isinstance(subscribe_envelope, PNMessageResult)
    assert subscribe_envelope.channel == channel
    assert subscribe_envelope.subscription is None
    assert subscribe_envelope.message == message
    assert subscribe_envelope.timetoken > 0

    assert isinstance(publish_envelope, AsyncioEnvelope)
    assert publish_envelope.result.timetoken > 0
    assert publish_envelope.status.original_response[0] == 1

    pubnub_sub.unsubscribe().channels(channel).execute()
    yield from callback.wait_for_disconnect()

    pubnub_pub.stop()
    pubnub_sub.stop()
async def test_subscribe_publish_unsubscribe(event_loop):
    pubnub_sub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub_pub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    patch_pubnub(pubnub_sub)
    patch_pubnub(pubnub_pub)

    pubnub_sub.config.uuid = 'test-subscribe-asyncio-uuid-sub'
    pubnub_pub.config.uuid = 'test-subscribe-asyncio-uuid-pub'

    callback = VCR599Listener(1)
    channel = "test-subscribe-asyncio-ch"
    message = "hey"
    pubnub_sub.add_listener(callback)
    pubnub_sub.subscribe().channels(channel).execute()

    await callback.wait_for_connect()

    publish_future = asyncio.ensure_future(
        pubnub_pub.publish().channel(channel).message(message).future())
    subscribe_message_future = asyncio.ensure_future(
        callback.wait_for_message_on(channel))

    await asyncio.wait([publish_future, subscribe_message_future])

    publish_envelope = publish_future.result()
    subscribe_envelope = subscribe_message_future.result()

    assert isinstance(subscribe_envelope, PNMessageResult)
    assert subscribe_envelope.channel == channel
    assert subscribe_envelope.subscription is None
    assert subscribe_envelope.message == message
    assert subscribe_envelope.timetoken > 0

    assert isinstance(publish_envelope, AsyncioEnvelope)
    assert publish_envelope.result.timetoken > 0
    assert publish_envelope.status.original_response[0] == 1

    pubnub_sub.unsubscribe().channels(channel).execute()
    # await callback.wait_for_disconnect()

    pubnub_pub.stop()
    pubnub_sub.stop()
async def test_cg_subscribe_publish_unsubscribe(event_loop,
                                                sleeper=asyncio.sleep):
    ch = "test-subscribe-asyncio-channel"
    gr = "test-subscribe-asyncio-group"
    message = "hey"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    envelope = await pubnub.add_channel_to_channel_group().channel_group(
        gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await sleeper(1)

    callback_messages = VCR599Listener(1)
    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channel_groups(gr).execute()
    await callback_messages.wait_for_connect()

    subscribe_future = asyncio.ensure_future(
        callback_messages.wait_for_message_on(ch))
    publish_future = asyncio.ensure_future(
        pubnub.publish().channel(ch).message(message).future())
    await asyncio.wait([subscribe_future, publish_future])

    sub_envelope = subscribe_future.result()
    pub_envelope = publish_future.result()

    assert pub_envelope.status.original_response[0] == 1
    assert pub_envelope.status.original_response[1] == 'Sent'

    assert sub_envelope.channel == ch
    assert sub_envelope.subscription == gr
    assert sub_envelope.message == message

    pubnub.unsubscribe().channel_groups(gr).execute()
    await callback_messages.wait_for_disconnect()

    envelope = await pubnub.remove_channel_from_channel_group().channel_group(
        gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await pubnub.stop()
Example #20
0
def test_unsubscribe_all(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    pubnub.config.uuid = "test-subscribe-asyncio-messenger"

    ch = "test-subscribe-asyncio-unsubscribe-all-ch"
    ch1 = "test-subscribe-asyncio-unsubscribe-all-ch1"
    ch2 = "test-subscribe-asyncio-unsubscribe-all-ch2"
    ch3 = "test-subscribe-asyncio-unsubscribe-all-ch3"
    gr1 = "test-subscribe-asyncio-unsubscribe-all-gr1"
    gr2 = "test-subscribe-asyncio-unsubscribe-all-gr2"

    envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr1).channels(ch).future()
    assert envelope.status.original_response['status'] == 200
    envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr2).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    yield from sleeper(1)

    callback_messages = VCR599Listener(1)
    pubnub.add_listener(callback_messages)

    pubnub.subscribe().channels([ch1, ch2, ch3]).channel_groups([gr1, gr2]).execute()
    yield from callback_messages.wait_for_connect()

    assert len(pubnub.get_subscribed_channels()) == 3
    assert len(pubnub.get_subscribed_channel_groups()) == 2

    pubnub.unsubscribe_all()

    yield from callback_messages.wait_for_disconnect()

    assert len(pubnub.get_subscribed_channels()) == 0
    assert len(pubnub.get_subscribed_channel_groups()) == 0

    envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr1).channels(ch).future()
    assert envelope.status.original_response['status'] == 200
    envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr2).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    pubnub.stop()
def test_blah():
    pnconf = pnconf_sub_copy()
    assert isinstance(pnconf, PNConfiguration)
    pnconf.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL
    pubnub = PubNubAsyncio(pnconf)
    time_until_open_again = 8

    @asyncio.coroutine
    def close_soon():
        yield from asyncio.sleep(2)
        pubnub._connector.close()
        print(">>> connection is broken")

    @asyncio.coroutine
    def open_again():
        yield from asyncio.sleep(time_until_open_again)
        pubnub.set_connector(aiohttp.TCPConnector(conn_timeout=pubnub.config.connect_timeout, verify_ssl=True))
        print(">>> connection is open again")

    @asyncio.coroutine
    def countdown():
        asyncio.sleep(2)
        opened = False
        count = time_until_open_again

        while not opened:
            print(">>> %ds to open again" % count)
            count -= 1
            if count <= 0:
                break
            yield from asyncio.sleep(1)

    my_listener = MySubscribeCallback()
    pubnub.add_listener(my_listener)
    pubnub.subscribe().channels('my_channel').execute()

    asyncio.ensure_future(close_soon())
    asyncio.ensure_future(open_again())
    asyncio.ensure_future(countdown())

    yield from asyncio.sleep(1000)
Example #22
0
    async def message_pump(self):
        pnconfig = PNConfiguration()
        pnconfig.subscribe_key = config['cardsubkey']
        # Why aren't these the default settings?
        pnconfig.ssl = True
        pnconfig.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL

        pubnub = PubNubAsyncio(pnconfig)

        listener = SubscribeListener()
        pubnub.add_listener(listener)

        pubnub.subscribe().channels(config['cardviewerchannel']).execute()
        await listener.wait_for_connect()
        log.info("Connected to PubNub")

        message_future = asyncio.ensure_future(
            listener.wait_for_message_on(config['cardviewerchannel']))

        while True:
            await asyncio.wait([self.stop_future, message_future],
                               return_when=asyncio.FIRST_COMPLETED)
            if message_future.done():
                message = message_future.result().message
                log.info("Message from PubNub: %r", message)

                card_id = self._extract(message)
                if card_id is not None:
                    await self._card(card_id)

                message_future = asyncio.ensure_future(
                    listener.wait_for_message_on(config['cardviewerchannel']))
            if self.stop_future.done():
                break
        if not message_future.done():
            message_future.cancel()

        pubnub.unsubscribe().channels(config['cardviewerchannel']).execute()
        await listener.wait_for_disconnect()
        pubnub.stop()
        log.info("Disconnected from PubNub")
Example #23
0
async def test_multiple_channels(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub.config.uuid = 'test-here-now-asyncio-uuid1'

    ch1 = "test-here-now-asyncio-ch1"
    ch2 = "test-here-now-asyncio-ch2"

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels([ch1, ch2]).execute()

    await callback.wait_for_connect()

    await sleeper(5)

    env = await pubnub.here_now() \
        .channels([ch1, ch2]) \
        .future()

    assert env.result.total_channels == 2
    assert env.result.total_occupancy >= 1

    channels = env.result.channels

    assert len(channels) == 2
    assert channels[0].occupancy == 1
    assert channels[0].occupants[0].uuid == pubnub.uuid
    assert channels[1].occupancy == 1
    assert channels[1].occupants[0].uuid == pubnub.uuid

    result = await pubnub.here_now() \
        .channels([ch1, ch2]) \
        .include_state(True) \
        .result()

    assert result.total_channels == 2

    pubnub.unsubscribe().channels([ch1, ch2]).execute()
    await callback.wait_for_disconnect()

    pubnub.stop()
Example #24
0
def test_blah():
    pnconf = pnconf_sub_copy()
    assert isinstance(pnconf, PNConfiguration)
    pnconf.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL
    pubnub = PubNubAsyncio(pnconf)
    time_until_open_again = 8

    @asyncio.coroutine
    def close_soon():
        yield from asyncio.sleep(2)
        pubnub._connector.close()
        print(">>> connection is broken")

    @asyncio.coroutine
    def open_again():
        yield from asyncio.sleep(time_until_open_again)
        pubnub.set_connector(aiohttp.TCPConnector(conn_timeout=pubnub.config.connect_timeout, verify_ssl=True))
        print(">>> connection is open again")

    @asyncio.coroutine
    def countdown():
        asyncio.sleep(2)
        opened = False
        count = time_until_open_again

        while not opened:
            print(">>> %ds to open again" % count)
            count -= 1
            if count <= 0:
                break
            yield from asyncio.sleep(1)

    my_listener = MySubscribeCallback()
    pubnub.add_listener(my_listener)
    pubnub.subscribe().channels("my_channel").execute()

    asyncio.ensure_future(close_soon())
    asyncio.ensure_future(open_again())
    asyncio.ensure_future(countdown())

    yield from asyncio.sleep(1000)
Example #25
0
def test_multiple_channels(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub.config.uuid = 'test-here-now-asyncio-uuid1'

    ch1 = "test-here-now-asyncio-ch1"
    ch2 = "test-here-now-asyncio-ch2"

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels([ch1, ch2]).execute()

    yield from callback.wait_for_connect()

    yield from sleeper(5)
    env = yield from pubnub.here_now() \
        .channels([ch1, ch2]) \
        .future()

    assert env.result.total_channels == 2
    assert env.result.total_occupancy >= 1

    channels = env.result.channels

    assert len(channels) == 2
    assert channels[0].occupancy == 1
    assert channels[0].occupants[0].uuid == pubnub.uuid
    assert channels[1].occupancy == 1
    assert channels[1].occupants[0].uuid == pubnub.uuid

    result = yield from pubnub.here_now() \
        .channels([ch1, ch2]) \
        .include_state(True) \
        .result()

    assert result.total_channels == 2

    pubnub.unsubscribe().channels([ch1, ch2]).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
Example #26
0
def test_single_channel(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub.config.uuid = 'test-here-now-asyncio-uuid1'
    ch = "test-here-now-asyncio-ch"

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels(ch).execute()

    yield from callback.wait_for_connect()

    yield from sleeper(5)

    env = yield from pubnub.here_now() \
        .channels(ch) \
        .include_uuids(True) \
        .future()

    assert env.result.total_channels == 1
    assert env.result.total_occupancy >= 1

    channels = env.result.channels

    assert len(channels) == 1
    assert channels[0].occupancy == 1
    assert channels[0].occupants[0].uuid == pubnub.uuid

    result = yield from pubnub.here_now() \
        .channels(ch) \
        .include_state(True) \
        .result()

    assert result.total_channels == 1
    assert result.total_occupancy == 1

    pubnub.unsubscribe().channels(ch).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
async def test_encrypted_subscribe_publish_unsubscribe(event_loop):
    pubnub = PubNubAsyncio(pnconf_enc_sub_copy(), custom_event_loop=event_loop)
    pubnub.config.uuid = 'test-subscribe-asyncio-uuid'

    with patch("pubnub.crypto.PubNubCryptodome.get_initialization_vector",
               return_value="knightsofni12345"):
        callback = VCR599Listener(1)
        channel = "test-subscribe-asyncio-ch"
        message = "hey"
        pubnub.add_listener(callback)
        pubnub.subscribe().channels(channel).execute()

        await callback.wait_for_connect()

        publish_future = asyncio.ensure_future(
            pubnub.publish().channel(channel).message(message).future())
        subscribe_message_future = asyncio.ensure_future(
            callback.wait_for_message_on(channel))

        await asyncio.wait([publish_future, subscribe_message_future])

        publish_envelope = publish_future.result()
        subscribe_envelope = subscribe_message_future.result()

        assert isinstance(subscribe_envelope, PNMessageResult)
        assert subscribe_envelope.channel == channel
        assert subscribe_envelope.subscription is None
        assert subscribe_envelope.message == message
        assert subscribe_envelope.timetoken > 0

        assert isinstance(publish_envelope, AsyncioEnvelope)
        assert publish_envelope.result.timetoken > 0
        assert publish_envelope.status.original_response[0] == 1

        pubnub.unsubscribe().channels(channel).execute()
        await callback.wait_for_disconnect()

    await pubnub.stop()
Example #28
0
	async def message_pump(self):
		pnconfig = PNConfiguration()
		pnconfig.subscribe_key = config['cardsubkey']
		# Why aren't these the default settings?
		pnconfig.ssl = True
		pnconfig.reconnect_policy = PNReconnectionPolicy.EXPONENTIAL

		pubnub = PubNubAsyncio(pnconfig)

		listener = SubscribeListener()
		pubnub.add_listener(listener)

		pubnub.subscribe().channels(config['cardviewerchannel']).execute()
		await listener.wait_for_connect()
		log.info("Connected to PubNub")

		message_future = asyncio.ensure_future(listener.wait_for_message_on(config['cardviewerchannel']))

		while True:
			await asyncio.wait([self.stop_future, message_future], return_when=asyncio.FIRST_COMPLETED)
			if message_future.done():
				message = message_future.result().message
				log.info("Message from PubNub: %r", message)

				card_id = self._extract(message)
				if card_id is not None:
					await self._card(card_id)

				message_future = asyncio.ensure_future(listener.wait_for_message_on(config['cardviewerchannel']))
			if self.stop_future.done():
				break
		if not message_future.done():
			message_future.cancel()

		pubnub.unsubscribe().channels(config['cardviewerchannel']).execute()
		await listener.wait_for_disconnect()
		pubnub.stop()
		log.info("Disconnected from PubNub")
Example #29
0
def test_cg_subscribe_publish_unsubscribe(event_loop, sleeper=asyncio.sleep):
    ch = "test-subscribe-asyncio-channel"
    gr = "test-subscribe-asyncio-group"
    message = "hey"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    yield from sleeper(1)

    callback_messages = VCR599Listener(1)
    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channel_groups(gr).execute()
    yield from callback_messages.wait_for_connect()

    subscribe_future = asyncio.ensure_future(callback_messages.wait_for_message_on(ch))
    publish_future = asyncio.ensure_future(pubnub.publish().channel(ch).message(message).future())
    yield from asyncio.wait([subscribe_future, publish_future])

    sub_envelope = subscribe_future.result()
    pub_envelope = publish_future.result()

    assert pub_envelope.status.original_response[0] == 1
    assert pub_envelope.status.original_response[1] == 'Sent'

    assert sub_envelope.channel == ch
    assert sub_envelope.subscription == gr
    assert sub_envelope.message == message

    pubnub.unsubscribe().channel_groups(gr).execute()
    yield from callback_messages.wait_for_disconnect()

    envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    pubnub.stop()
Example #30
0
def test_cg_subscribe_unsubscribe(event_loop, sleeper=asyncio.sleep):
    ch = "test-subscribe-asyncio-channel"
    gr = "test-subscribe-asyncio-group"

    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    yield from sleeper(3)

    callback_messages = SubscribeListener()
    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channel_groups(gr).execute()
    yield from callback_messages.wait_for_connect()

    pubnub.unsubscribe().channel_groups(gr).execute()
    yield from callback_messages.wait_for_disconnect()

    envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    pubnub.stop()
async def test_subscribe_publish_unsubscribe(event_loop):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    callback = SubscribeListener()
    channel = helper.gen_channel("test-sub-pub-unsub")
    message = "hey"
    pubnub.add_listener(callback)
    pubnub.subscribe().channels(channel).execute()

    await callback.wait_for_connect()

    publish_future = asyncio.ensure_future(pubnub.publish().channel(channel).message(message).future())
    subscribe_message_future = asyncio.ensure_future(callback.wait_for_message_on(channel))

    await asyncio.wait([
        publish_future,
        subscribe_message_future
    ])

    publish_envelope = publish_future.result()
    subscribe_envelope = subscribe_message_future.result()

    assert isinstance(subscribe_envelope, PNMessageResult)
    assert subscribe_envelope.channel == channel
    assert subscribe_envelope.subscription is None
    assert subscribe_envelope.message == message
    assert subscribe_envelope.timetoken > 0

    assert isinstance(publish_envelope, AsyncioEnvelope)
    assert publish_envelope.result.timetoken > 0
    assert publish_envelope.status.original_response[0] == 1

    pubnub.unsubscribe().channels(channel).execute()
    await callback.wait_for_disconnect()

    pubnub.stop()
Example #32
0
async def test_global(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub.config.uuid = 'test-here-now-asyncio-uuid1'

    ch1 = "test-here-now-asyncio-ch1"
    ch2 = "test-here-now-asyncio-ch2"

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels([ch1, ch2]).execute()

    await callback.wait_for_connect()

    await sleeper(5)

    env = await pubnub.here_now().future()

    assert env.result.total_channels >= 2
    assert env.result.total_occupancy >= 1

    pubnub.unsubscribe().channels([ch1, ch2]).execute()
    await callback.wait_for_disconnect()

    pubnub.stop()
Example #33
0
def test_global(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub.config.uuid = 'test-here-now-asyncio-uuid1'

    ch1 = "test-here-now-asyncio-ch1"
    ch2 = "test-here-now-asyncio-ch2"

    callback = VCR599Listener(1)
    pubnub.add_listener(callback)
    pubnub.subscribe().channels([ch1, ch2]).execute()

    yield from callback.wait_for_connect()

    yield from sleeper(5)

    env = yield from pubnub.here_now().future()

    assert env.result.total_channels >= 2
    assert env.result.total_occupancy >= 1

    pubnub.unsubscribe().channels([ch1, ch2]).execute()
    yield from callback.wait_for_disconnect()

    pubnub.stop()
Example #34
0
class Messages:
    """Manage connexion with external device"""
    def __init__(self, subkey, pubkey, id):
        """Class constructor
        :param subkey: PubNub subscription key
        :param pubkey: PubNub publish key
        :param id: device id (UUID)
        """
        class MySubscribeListener(SubscribeListener):
            def __init__(self):
                self._logger = logging.getLogger('sprinkler')
                super().__init__()

            def status(self, pubnub, status):
                if status.category == PNStatusCategory.PNUnexpectedDisconnectCategory:
                    # This event happens when radio / connectivity is lost
                    self._logger.error("Unexpected disconnection")

                elif status.category == PNStatusCategory.PNConnectedCategory:
                    # Connect event. You can do stuff like publish, and know you'll get it.
                    # Or just use the connected event to confirm you are subscribed for
                    # UI / internal notifications, etc
                    self._logger.info("Connection OK")

                elif status.category == PNStatusCategory.PNReconnectedCategory:
                    # Happens as part of our regular operation. This event happens when
                    # radio / connectivity is lost, then regained.
                    self._logger.info("Reconnection OK")
                elif status.category == PNStatusCategory.PNDecryptionErrorCategory:
                    # Handle message decryption error. Probably client configured to
                    # encrypt messages and on live data feed it received plain text.
                    self._logger.error("Decryption error")
                super().status(pubnub, status)

            def message(self, pubnub, message):
                if message.publisher != pubnub.uuid:
                    self._logger.debug(f"RECV from {message.publisher}: \
                        {json.dumps(message.message['content'])}")
                    super().message(pubnub, message.message['content'])

        self._logger = logging.getLogger('sprinkler')
        self.message_listener = MySubscribeListener()
        self.messages = self.message_listener.message_queue

        pnconfig = PNConfiguration()
        pnconfig.subscribe_key = subkey
        pnconfig.publish_key = pubkey
        pnconfig.uuid = id
        pnconfig.ssl = True
        pnconfig.reconnect_policy = PNReconnectionPolicy.LINEAR
        pnconfig.subscribe_timeout = 20
        self.pubnub = PubNubAsyncio(pnconfig)
        self.pubnub.add_listener(self.message_listener)
        self.pubnub.subscribe().channels('sprinkler').execute()

    def publish_callback(self, task):
        exception = task.exception()
        if exception is not None:
            self._logger.error(f"Sending error: {str(exception)}")

    async def send(self, msg):
        asyncio.create_task(self.pubnub.publish().channel("sprinkler").message({'content': msg}).future()). \
            add_done_callback(self.publish_callback)
        self._logger.debug(f"SEND from {self.pubnub.uuid}: {json.dumps(msg)}")

    def stop(self):
        self.pubnub.unsubscribe().channels('sprinkler').execute()
        try:
            self.message_listener.wait_for_disconnect()
        except:
            # Already disconnected
            pass
        self.pubnub.stop()
        self._logger.debug("Message manager stopped")

    async def get_message(self):
        return await self.messages.get()

    def is_message(self):
        return not self.messages.empty()
Example #35
0
                # There was an error with the heartbeat operation, handle here
            else:
                pass
                # Heartbeat operation was successful
        else:
            pass
            # Encountered unknown status type

    def presence(self, pubnub, presence):
        pass  # handle incoming presence data

    def message(self, pubnub, message):
        pass  # handle incoming messages


pubnub.add_listener(MySubscribeCallback())

# > remove listener snippet
my_listener = MySubscribeCallback()

pubnub.add_listener(my_listener)

# some time later
pubnub.remove_listener(my_listener)


# > handle disconnect snippet
class HandleDisconnectsCallback(SubscribeCallback):
    def status(self, pubnub, status):
        if status.category == PNStatusCategory.PNUnexpectedDisconnectCategory:
            # internet got lost, do some magic and call reconnect when ready
Example #36
0
class BeekeeperBot:
    def __init__(self, beekeeper_client, event_loop):
        """
        Args:
            beekeeper_client (BeekeeperClient): client
            event_loop
        """
        self._client = beekeeper_client
        self._event_loop = event_loop or asyncio.get_event_loop()

        self._pubnub = None
        self._is_running = False
        self._callbacks = []
        self.conversation_data = {}

        try:
            self._pubnub_key = self._client.user_config['tenant'][
                'integrations']['pubnub']['subscribe_key']
            self._pubnub_channel_name = self._client.user_config[
                'enc_channel']['channel']
            self._pubnub_channel_key = self._client.user_config['enc_channel'][
                'key']
        except KeyError:
            raise BeekeeperBotException('Failed to retrieve PubNub settings')

    async def __aenter__(self):
        message_decrypter = BeekeeperBotMessageDecrypter(
            base64.b64decode(self._pubnub_channel_key))
        message_listener = BeekeeperBotMessageListener(
            bot=self, decrypter=message_decrypter)

        pubnub_config = PNConfiguration()
        pubnub_config.subscribe_key = self._pubnub_key
        pubnub_config.reconnect_policy = PNReconnectionPolicy.LINEAR
        pubnub_config.connect_timeout = 30

        self._pubnub = PubNubAsyncio(config=pubnub_config)
        self._pubnub.add_listener(message_listener)
        self._pubnub.subscribe().channels([self._pubnub_channel_name
                                           ]).execute()

        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        self._pubnub.unsubscribe_all()
        self._pubnub.stop()

    def on_message(self, message):
        """
        Called by the message listener when there is a new message, this function will call callbacks as well
        Args:
            message (Message): new message
        Returns:
            None
        """
        futures = [cb(self, message) for cb in self._callbacks]
        asyncio.ensure_future(*futures, loop=self._event_loop)

    def get_client(self):
        """
        Returns:
            BeekeeperClient: beekeeper client object
        """
        return self._client

    def add_callback(self, callback):
        """
        Adds a callback for when a message arrives
        Args:
            callback (func): callback function to call
        Returns:
            None
        """
        self._callbacks.append(callback)
Example #37
0
class Vivint:
    """Class for interacting with VivintSky API using asyncio"""

    def __init__(
        self,
        username: str,
        password: str,
        client_session: Optional[aiohttp.ClientSession] = None,
    ):
        self.__pubnub: pubnub.pubnub_asyncio.PubNubAsyncio = None
        self.vivintskyapi = VivintSkyApi(username, password, client_session)
        self.systems: List[pyvivint.system.System] = []

    async def connect(
        self,
        load_devices: bool = False,
        subscribe_for_realtime_updates: bool = False,
    ) -> None:
        """Connects to vivintsky cloud service."""

        _LOGGER.debug("connecting to vivintsky")
        # initialize the vivintsky cloud session
        authuser_data = await self.vivintskyapi.connect()

        # load all systems, panels and devices
        if load_devices:
            _LOGGER.debug("loading devices")
            await self.refresh(authuser_data)

        # subscribe to pubnub for realtime updates
        if subscribe_for_realtime_updates:
            _LOGGER.debug("subscribing to pubnub for realtime updates")
            await self.subscribe_for_realtime_updates(authuser_data)

    async def disconnect(self) -> None:
        _LOGGER.debug("disconnecting from vivintsky")
        await self.vivintskyapi.disconnect()

    async def refresh(self, authuser_data: dict = None) -> None:
        # make a call to vivint's authuser endpoint to get a list of all the system_accounts (locations) & panels if not supplied
        if not authuser_data:
            authuser_data = await self.vivintskyapi.get_authuser_data()

        # for each system_account, make another call to load all the devices
        for system_data in authuser_data["u"]["system"]:
            # is this an existing account_system?
            system = first_or_none(
                self.systems, lambda system: system.id == system_data["panid"]
            )
            if system:
                await system.refresh()
            else:
                full_system_data = await self.vivintskyapi.get_system_data(
                    system_data["panid"]
                )
                self.systems.append(
                    System(system_data.get("sn"), full_system_data, self.vivintskyapi)
                )

        _LOGGER.debug(f"loaded {len(self.systems)} system(s)")

    async def subscribe_for_realtime_updates(self, authuser_data: dict = None) -> None:
        """Subscribes to PubNub for realtime updates."""
        # make a call to vivint's authuser endpoint to get message broadcast channel if not supplied
        if not authuser_data:
            authuser_data = await self.vivintskyapi.get_authuser_data()

        pubnub.set_stream_logger("pubnub", logging.INFO)

        pnconfig = PNConfiguration()
        pnconfig.subscribe_key = PN_SUBSCRIBE_KEY
        pnconfig.ssl = True
        pnconfig.reconnect_policy = PNReconnectionPolicy.LINEAR
        pnconfig.heartbeat_notification_options = PNHeartbeatNotificationOptions.ALL

        self.__pubnub = PubNubAsyncio(pnconfig)
        self.__pubnub.add_listener(
            VivintPubNubSubscribeListener(self.handle_pubnub_message)
        )

        pn_channel = f"{PN_CHANNEL}#{authuser_data[AuthUserAttribute.USERS][AuthUserAttribute.UserAttribute.MESSAGE_BROADCAST_CHANNEL]}"
        self.__pubnub.subscribe().channels(pn_channel).with_presence().execute()

    def handle_pubnub_message(self, message: dict) -> None:
        """Handles a pubnub message."""
        _LOGGER.info(f"message: {json.dumps(message)}")

        panel_id = message.get(MessageAttributes.PANEL_ID)
        if not panel_id:
            _LOGGER.info("ignoring pubnub message. No panel_id specified")
            return

        system = first_or_none(self.systems, lambda system: system.id == panel_id)
        if not system:
            _LOGGER.info(f"no system found with id {panel_id}")
            return

        system.handle_pubnub_message(message)
async def test_cg_join_leave(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub_listener = PubNubAsyncio(pnconf_sub_copy(),
                                    custom_event_loop=event_loop)

    pubnub.config.uuid = "test-subscribe-asyncio-messenger"
    pubnub_listener.config.uuid = "test-subscribe-asyncio-listener"

    ch = "test-subscribe-asyncio-join-leave-cg-channel"
    gr = "test-subscribe-asyncio-join-leave-cg-group"

    envelope = await pubnub.add_channel_to_channel_group().channel_group(
        gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await sleeper(1)

    callback_messages = VCR599Listener(1)
    callback_presence = VCR599Listener(1)

    pubnub_listener.add_listener(callback_presence)
    pubnub_listener.subscribe().channel_groups(gr).with_presence().execute()
    await callback_presence.wait_for_connect()

    prs_envelope = await callback_presence.wait_for_presence_on(ch)
    assert prs_envelope.event == 'join'
    assert prs_envelope.uuid == pubnub_listener.uuid
    assert prs_envelope.channel == ch
    assert prs_envelope.subscription == gr

    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channel_groups(gr).execute()

    callback_messages_future = asyncio.ensure_future(
        callback_messages.wait_for_connect())
    presence_messages_future = asyncio.ensure_future(
        callback_presence.wait_for_presence_on(ch))
    await asyncio.wait([callback_messages_future, presence_messages_future])
    prs_envelope = presence_messages_future.result()

    assert prs_envelope.event == 'join'
    assert prs_envelope.uuid == pubnub.uuid
    assert prs_envelope.channel == ch
    assert prs_envelope.subscription == gr

    pubnub.unsubscribe().channel_groups(gr).execute()

    callback_messages_future = asyncio.ensure_future(
        callback_messages.wait_for_disconnect())
    presence_messages_future = asyncio.ensure_future(
        callback_presence.wait_for_presence_on(ch))
    await asyncio.wait([callback_messages_future, presence_messages_future])
    prs_envelope = presence_messages_future.result()

    assert prs_envelope.event == 'leave'
    assert prs_envelope.uuid == pubnub.uuid
    assert prs_envelope.channel == ch
    assert prs_envelope.subscription == gr

    pubnub_listener.unsubscribe().channel_groups(gr).execute()
    await callback_presence.wait_for_disconnect()

    envelope = await pubnub.remove_channel_from_channel_group().channel_group(
        gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    await pubnub.stop()
    pubnub_listener.stop()
Example #39
0
class Vivint:
    """Class for interacting with VivintSky API using asyncio"""

    def __init__(
            self,
            username: str,
            password: str,
            loop: Optional[asyncio.events.AbstractEventLoop] = None,
            client_session: Optional[aiohttp.ClientSession] = None
    ):
        self.__loop: asyncio.events.AbstractEventLoop = loop or asyncio.get_event_loop()
        self.__pubnub: pubnub.pubnub_asyncio.PubNubAsyncio = None
        self.vivintskyapi = VivintSkyApi(username, password, self.__loop, client_session)
        self.systems: List[pyvivint.system.System] = []

    async def connect(
        self,
        load_devices: bool = False,
        subscribe_for_realtime_updates: bool = False,
        enable_token_auto_refresh: bool = False
    ) -> None:
        """Connects to vivintsky cloud service."""

        _LOGGER.debug('connecting to vivintsky')
        # initialize the vivintsky cloud session
        await self.vivintskyapi.connect()

        # load all systems, panels and devices
        if load_devices:
            _LOGGER.debug('loading devices')
            await self.refresh()

        # set up loop to periodically refresh the token
        if enable_token_auto_refresh:
            _LOGGER.debug('setting up token auto refresh loop')
            self.setup_token_refresh_handler()

        # subscript to pubnub for realtime updates
        if subscribe_for_realtime_updates:
            _LOGGER.debug('subscribing to pubnub for realtime updates')
            await self.subscripbe_for_realtime_updates()

    async def disconnect(self) -> None:
        _LOGGER.debug('disconnecting from vivintsky')
        await self.vivintskyapi.disconnect()

    async def refresh(self) -> None:
        # make a call to vivint's userauth endpoint to get a list of all the system_accounts (locations) & panels
        authuser_data = await self.vivintskyapi.get_authuser_data()

        # for each system_account, make another call to load all the devices
        for system_data in authuser_data['u']['system']:
            # is this an existing account_system?
            system = first_or_none(self.systems, lambda system: system.id == system_data['panid'])
            if system:
                await system.refresh()
            else:
                full_system_data = await self.vivintskyapi.get_system_data(system_data['panid'])
                self.systems.append(System(full_system_data, self.vivintskyapi))

        _LOGGER.debug(f'loaded {len(self.systems)} system(s)')

    def setup_token_refresh_handler(self) -> None:
        """Set up the token refresh handler."""
        add_async_job(self.__token_refresh_handler)

    async def __token_refresh_handler(self) -> None:
        """Periodically refreshes the idtoken."""
        while True:
            id_token = self.vivintskyapi.parse_id_token(self.vivintskyapi.id_token)
            if id_token['payload']['exp'] - time.time() < 60:
                await self.vivintskyapi.refresh_token()

            await asyncio.sleep(1)

    async def subscripbe_for_realtime_updates(self) -> None:
        """Subscribes to PubNub for realtime updates."""
        # make a call to vivint's userauth endpoint
        authuser_data = await self.vivintskyapi.get_authuser_data()

        pubnub.set_stream_logger("pubnub", logging.INFO)

        pnconfig = PNConfiguration()
        pnconfig.subscribe_key = PN_SUBSCRIBE_KEY
        pnconfig.ssl = True
        pnconfig.reconnect_policy = PNReconnectionPolicy.LINEAR
        pnconfig.heartbeat_notification_options = PNHeartbeatNotificationOptions.ALL

        self.__pubnub = PubNubAsyncio(pnconfig)
        self.__pubnub.add_listener(
            VivintPubNubSubscribeListener(self.handle_pubnub_message)
        )

        pn_channel = f'{PN_CHANNEL}#{authuser_data[AuthUserAttributes.Users][AuthUserAttributes.UsersAttributes.MessageBroadcastChannel]}'  # noqa
        self.__pubnub.subscribe().channels(pn_channel).with_presence().execute()

    def handle_pubnub_message(self, message: dict) -> None:
        """Handles a pubnub message."""
        _LOGGER.info(f"message: {json.dumps(message)}")

        panel_id = message.get(MessageAttributes.PanelId)
        if not panel_id:
            _LOGGER.info('ignoring pubnub message. No panel_id specified')
            return

        system = first_or_none(self.systems, lambda system: system.id == panel_id)
        if not system:
            _LOGGER.info(f'no system found with id {panel_id}')
            return

        system.handle_pubnub_message(message)
Example #40
0
def test_cg_join_leave(event_loop, sleeper=asyncio.sleep):
    pubnub = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)
    pubnub_listener = PubNubAsyncio(pnconf_sub_copy(), custom_event_loop=event_loop)

    pubnub.config.uuid = "test-subscribe-asyncio-messenger"
    pubnub_listener.config.uuid = "test-subscribe-asyncio-listener"

    ch = "test-subscribe-asyncio-join-leave-cg-channel"
    gr = "test-subscribe-asyncio-join-leave-cg-group"

    envelope = yield from pubnub.add_channel_to_channel_group().channel_group(gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    yield from sleeper(1)

    callback_messages = VCR599Listener(1)
    callback_presence = VCR599Listener(1)

    pubnub_listener.add_listener(callback_presence)
    pubnub_listener.subscribe().channel_groups(gr).with_presence().execute()
    yield from callback_presence.wait_for_connect()

    prs_envelope = yield from callback_presence.wait_for_presence_on(ch)
    assert prs_envelope.event == 'join'
    assert prs_envelope.uuid == pubnub_listener.uuid
    assert prs_envelope.channel == ch
    assert prs_envelope.subscription == gr

    pubnub.add_listener(callback_messages)
    pubnub.subscribe().channel_groups(gr).execute()

    callback_messages_future = asyncio.ensure_future(callback_messages.wait_for_connect())
    presence_messages_future = asyncio.ensure_future(callback_presence.wait_for_presence_on(ch))
    yield from asyncio.wait([callback_messages_future, presence_messages_future])
    prs_envelope = presence_messages_future.result()

    assert prs_envelope.event == 'join'
    assert prs_envelope.uuid == pubnub.uuid
    assert prs_envelope.channel == ch
    assert prs_envelope.subscription == gr

    pubnub.unsubscribe().channel_groups(gr).execute()

    callback_messages_future = asyncio.ensure_future(callback_messages.wait_for_disconnect())
    presence_messages_future = asyncio.ensure_future(callback_presence.wait_for_presence_on(ch))
    yield from asyncio.wait([callback_messages_future, presence_messages_future])
    prs_envelope = presence_messages_future.result()

    assert prs_envelope.event == 'leave'
    assert prs_envelope.uuid == pubnub.uuid
    assert prs_envelope.channel == ch
    assert prs_envelope.subscription == gr

    pubnub_listener.unsubscribe().channel_groups(gr).execute()
    yield from callback_presence.wait_for_disconnect()

    envelope = yield from pubnub.remove_channel_from_channel_group().channel_group(gr).channels(ch).future()
    assert envelope.status.original_response['status'] == 200

    pubnub.stop()
    pubnub_listener.stop()