Skip to content

Commit

Permalink
[Version] v1.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Herklos committed May 9, 2020
1 parent 37457a1 commit 8d0598d
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.4.1] - 2020-05-09
### Added
- [ChannelInstances] Channel id support

## [1.4.0] - 2020-05-01
### Added
- Synchronous Channel
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# OctoBot-Channels [1.4.0](https://github.com/Drakkar-Software/OctoBot-Channels/blob/master/CHANGELOG.md)
# OctoBot-Channels [1.4.1](https://github.com/Drakkar-Software/OctoBot-Channels/blob/master/CHANGELOG.md)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/d6bc3f05475c463189dbd509cfc94afe)](https://app.codacy.com/gh/Drakkar-Software/OctoBot-Channels?utm_source=github.com&utm_medium=referral&utm_content=Drakkar-Software/OctoBot-Channels&utm_campaign=Badge_Grade_Dashboard)
[![PyPI](https://img.shields.io/pypi/v/OctoBot-Channels.svg)](https://pypi.python.org/pypi/OctoBot-Channels/)
[![Build Status](https://api.travis-ci.com/Drakkar-Software/OctoBot-Channels.svg?branch=master)](https://travis-ci.com/Drakkar-Software/OctoBot-Channels)
Expand Down
2 changes: 1 addition & 1 deletion octobot_channels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
# License along with this library.

PROJECT_NAME = "OctoBot-Channels"
VERSION = "1.4.0" # major.minor.revision
VERSION = "1.4.1" # major.minor.revision
2 changes: 2 additions & 0 deletions octobot_channels/channels/channel.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ from octobot_channels.producer cimport Producer
cdef class Channel(object):
cdef object logger

cdef public str chan_id

cdef public list producers
cdef public list consumers

Expand Down
3 changes: 3 additions & 0 deletions octobot_channels/channels/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class Channel:
def __init__(self):
self.logger = get_logger(self.__class__.__name__)

# Channel unique id
self.chan_id = None

# Channel subscribed producers list
self.producers = []

Expand Down
8 changes: 8 additions & 0 deletions octobot_channels/channels/channel_instances.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,13 @@
# License along with this library.
from octobot_commons.singleton.singleton_class cimport Singleton

from octobot_channels.channels.channel cimport Channel

cdef class ChannelInstances(Singleton):
cdef public dict channels

cpdef Channel get_chan_at_id(str chan_name, str chan_id)
cpdef dict get_channels(str chan_id)
cpdef void set_chan_at_id(Channel chan, str name)
cpdef void del_channel_container(str chan_id)
cpdef void del_chan_at_id(str name, str chan_id)
73 changes: 72 additions & 1 deletion octobot_channels/channels/channel_instances.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=E0611
# Drakkar-Software OctoBot-Channels
# Copyright (c) Drakkar-Software, All rights reserved.
#
Expand All @@ -13,7 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library.
# pylint: disable=E0611
from octobot_commons.logging.logging_util import get_logger
from octobot_commons.singleton.singleton_class import Singleton


Expand All @@ -24,3 +25,73 @@ class ChannelInstances(Singleton):

def __init__(self):
self.channels = {}


def set_chan_at_id(chan, name) -> None:
"""
Add a new channel to the channels instances dictionary at chan.id
:param chan: the channel instance
:param name: the channel name
"""
chan_name = chan.get_name() if name else name

try:
chan_instance = ChannelInstances.instance().channels[chan.chan_id]
except KeyError:
ChannelInstances.instance().channels[chan.chan_id] = {}
chan_instance = ChannelInstances.instance().channels[chan.chan_id]

if chan_name not in chan_instance:
chan_instance[chan_name] = chan
else:
raise ValueError(f"Channel {chan_name} already exists.")


def get_channels(chan_id) -> dict:
"""
Get channel instances by channel id
:param chan_id: the channel id
:return: the channel instances at channel id
"""
try:
return ChannelInstances.instance().channels[chan_id]
except KeyError:
raise KeyError(f"Channels not found with chan_id: {chan_id}")


def del_channel_container(chan_id) -> None:
"""
Delete all channel id instances
:param chan_id: the channel id
"""
try:
ChannelInstances.instance().channels.pop(chan_id, None)
except KeyError:
raise KeyError(f"Channels not found with chan_id: {chan_id}")


def get_chan_at_id(chan_name, chan_id) -> object:
"""
Get the channel instance that matches the name and the id
:param chan_name: the channel name
:param chan_id: the channel id
:return: the channel instance if any
"""
try:
return ChannelInstances.instance().channels[chan_id][chan_name]
except KeyError:
raise KeyError(f"Channel {chan_name} not found with chan_id: {chan_id}")


def del_chan_at_id(chan_name, chan_id) -> None:
"""
Delete the channel instance that matches the name and the id
:param chan_name: the channel name
:param chan_id: the channel id
"""
try:
ChannelInstances.instance().channels[chan_id].pop(chan_name, None)
except KeyError:
get_logger(ChannelInstances.__name__).warning(
f"Can't del chan {chan_name} with chan_id: {chan_id}"
)
10 changes: 10 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

TEST_CHANNEL = "Test"
EMPTY_TEST_CHANNEL = "EmptyTest"
EMPTY_TEST_WITH_ID_CHANNEL = "EmptyTestWithId"
CONSUMER_KEY = "test"


Expand Down Expand Up @@ -57,3 +58,12 @@ async def mock_was_called_once(mocked_method):
async def mock_was_not_called(mocked_method):
await asyncio.sleep(0.1)
mocked_method.assert_not_called()


class EmptyTestWithIdChannel(Channel):
CONSUMER_CLASS = EmptyTestConsumer
PRODUCER_CLASS = EmptyTestProducer

def __init__(self, test_id):
super().__init__()
self.chan_id = test_id
97 changes: 97 additions & 0 deletions tests/test_channel_instances.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Drakkar-Software OctoBot-Channels
# Copyright (c) Drakkar-Software, All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3.0 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library.
from uuid import uuid4

import pytest

from octobot_channels.channels.channel_instances import del_chan_at_id, get_chan_at_id, set_chan_at_id, \
del_channel_container, get_channels
from octobot_channels.util.channel_creator import create_channel_instance
from tests import EmptyTestWithIdChannel, EMPTY_TEST_WITH_ID_CHANNEL


@pytest.fixture()
async def chan_id():
channel_uuid = uuid4().hex
await create_channel_instance(EmptyTestWithIdChannel, set_chan_at_id, test_id=channel_uuid)
return channel_uuid


@pytest.yield_fixture()
async def channel_id():
channel_uuid = uuid4().hex
await create_channel_instance(EmptyTestWithIdChannel, set_chan_at_id, test_id=channel_uuid)
yield channel_uuid
await get_chan_at_id(EMPTY_TEST_WITH_ID_CHANNEL, channel_uuid).stop()
del_chan_at_id(EMPTY_TEST_WITH_ID_CHANNEL, channel_uuid)


@pytest.mark.asyncio
async def test_get_chan_at_id(channel_id):
assert get_chan_at_id(EMPTY_TEST_WITH_ID_CHANNEL, channel_id)


@pytest.mark.asyncio
async def test_del_channel_container(chan_id):
del_channel_container(chan_id)
with pytest.raises(KeyError):
get_chan_at_id(EMPTY_TEST_WITH_ID_CHANNEL, chan_id)
del_chan_at_id(EMPTY_TEST_WITH_ID_CHANNEL, chan_id)


@pytest.mark.asyncio
async def test_get_channels(chan_id):
class EmptyTestWithId2Channel(EmptyTestWithIdChannel):
pass

class EmptyTestWithId3Channel(EmptyTestWithIdChannel):
pass

class EmptyTestWithId4Channel(EmptyTestWithIdChannel):
pass

class EmptyTestWithId5Channel(EmptyTestWithIdChannel):
pass

class EmptyTestWithId6Channel(EmptyTestWithIdChannel):
pass

channel_4_id = uuid4().hex
channel_6_id = uuid4().hex
ch1 = get_chan_at_id(EMPTY_TEST_WITH_ID_CHANNEL, chan_id)
ch2 = await create_channel_instance(EmptyTestWithId2Channel, set_chan_at_id, test_id=chan_id)
ch3 = await create_channel_instance(EmptyTestWithId3Channel, set_chan_at_id, test_id=chan_id)
ch4 = await create_channel_instance(EmptyTestWithId4Channel, set_chan_at_id, test_id=channel_4_id)
ch5 = await create_channel_instance(EmptyTestWithId5Channel, set_chan_at_id, test_id=channel_4_id)
ch6 = await create_channel_instance(EmptyTestWithId6Channel, set_chan_at_id, test_id=channel_6_id)
assert len(get_channels(chan_id)) == 3
assert len(get_channels(channel_4_id)) == 2
assert len(get_channels(channel_6_id)) == 1
assert get_channels(chan_id) == {
"EmptyTestWithId": ch1,
"EmptyTestWithId2": ch2,
"EmptyTestWithId3": ch3
}
assert get_channels(channel_4_id) == {
"EmptyTestWithId4": ch4,
"EmptyTestWithId5": ch5
}
assert get_channels(channel_6_id) == {
"EmptyTestWithId6": ch6
}
del_channel_container(chan_id)
del_channel_container(channel_4_id)
del_channel_container(channel_6_id)

0 comments on commit 8d0598d

Please sign in to comment.