Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💥 iamlistening v3⬆️ 💄 TalkyTrendPlugin monitoring ♻️ Apprise #606

Merged
merged 24 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ asyncz==0.4.0 ; python_version >= "3.10" and python_version < "4.0"
attrs==23.1.0 ; python_version >= "3.10" and python_version < "4.0"
beautifulsoup4==4.12.2 ; python_version >= "3.10" and python_version < "4.0"
bitarray==2.8.0 ; python_version >= "3.10" and python_version < "4"
ccxt==4.0.36 ; python_version >= "3.10" and python_version < "4.0"
ccxt==4.0.38 ; python_version >= "3.10" and python_version < "4.0"
certifi==2023.7.22 ; python_version >= "3.10" and python_version < "4.0"
cffi==1.15.1 ; python_version >= "3.10" and python_version < "4.0"
charset-normalizer==3.2.0 ; python_version >= "3.10" and python_version < "4.0"
click==8.1.6 ; python_version >= "3.10" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows")
cryptography==41.0.2 ; python_version >= "3.10" and python_version < "4.0"
cytoolz==0.12.2 ; python_version >= "3.10" and python_version < "4" and implementation_name == "cpython"
dxsp==4.1.2 ; python_version >= "3.10" and python_version < "4.0"
dxsp==4.2.1 ; python_version >= "3.10" and python_version < "4.0"
dynaconf==3.2.0 ; python_version >= "3.10" and python_version < "4.0"
emoji==2.6.0 ; python_version >= "3.10" and python_version < "4.0"
emoji==2.7.0 ; python_version >= "3.10" and python_version < "4.0"
eth-abi==4.1.0 ; python_version >= "3.10" and python_version < "4"
eth-account==0.9.0 ; python_version >= "3.10" and python_version < "4"
eth-hash==0.5.2 ; python_version >= "3.10" and python_version < "4"
Expand All @@ -35,7 +35,7 @@ eth-typing==3.4.0 ; python_version >= "3.10" and python_version < "4"
eth-utils==2.2.0 ; python_version >= "3.10" and python_version < "4"
exceptiongroup==1.1.2 ; python_version >= "3.10" and python_version < "3.11"
fastapi==0.100.0 ; python_version >= "3.10" and python_version < "4.0"
findmyorder==1.6.1 ; python_version >= "3.10" and python_version < "4.0"
findmyorder==1.7.0 ; python_version >= "3.10" and python_version < "4.0"
frozendict==2.3.8 ; python_version >= "3.10" and python_version < "4.0"
frozenlist==1.4.0 ; python_version >= "3.10" and python_version < "4.0"
future==0.18.3 ; python_version >= "3.10" and python_version < "4.0"
Expand All @@ -47,7 +47,7 @@ html5lib==1.1 ; python_version >= "3.10" and python_version < "4.0"
httpcore==0.17.3 ; python_version >= "3.10" and python_version < "4.0"
httpx==0.24.1 ; python_version >= "3.10" and python_version < "4.0"
hyperframe==6.0.1 ; python_version >= "3.10" and python_version < "4.0"
iamlistening==2.1.0 ; python_version >= "3.10" and python_version < "4.0"
iamlistening==3.0.1 ; python_version >= "3.10" and python_version < "4.0"
idna==3.4 ; python_version >= "3.10" and python_version < "4.0"
jsonschema-specifications==2023.7.1 ; python_version >= "3.10" and python_version < "4.0"
jsonschema==4.18.4 ; python_version >= "3.10" and python_version < "4.0"
Expand Down Expand Up @@ -96,13 +96,13 @@ rocketchat-api==1.30.0 ; python_version >= "3.10" and python_version < "4.0"
rpds-py==0.9.2 ; python_version >= "3.10" and python_version < "4.0"
rsa==4.9 ; python_version >= "3.10" and python_version < "4"
setuptools==68.0.0 ; python_version >= "3.10" and python_version < "4.0"
simplematrixbotlib==2.9.0 ; python_version >= "3.10" and python_version < "4.0"
simplematrixbotlib==2.9.1 ; python_version >= "3.10" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
sniffio==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
soupsieve==2.4.1 ; python_version >= "3.10" and python_version < "4.0"
starlette==0.27.0 ; python_version >= "3.10" and python_version < "4.0"
talkytrend==1.11.0 ; python_version >= "3.10" and python_version < "4.0"
telethon==1.29.1 ; python_version >= "3.10" and python_version < "4.0"
talkytrend==1.12.1 ; python_version >= "3.10" and python_version < "4.0"
telethon==1.29.2 ; python_version >= "3.10" and python_version < "4.0"
toml==0.10.2 ; python_version >= "3.10" and python_version < "4.0"
toolz==0.12.0 ; python_version >= "3.10" and python_version < "4" and (implementation_name == "pypy" or implementation_name == "cpython")
tradingview-ta==3.3.0 ; python_version >= "3.10" and python_version < "4.0"
Expand Down
294 changes: 0 additions & 294 deletions docs/index.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ ping3 = "^4.0.4"
ccxt = "^4.0.0"
dxsp = "^4.1.0"
findmyorder = "^1.6.1"
iamlistening = "^2.0.0"
talkytrend = "^1.10.0"
iamlistening = "^3.0.1"
talkytrend = "^1.12.1"


[tool.poetry.group.dev.dependencies]
Expand Down Expand Up @@ -85,6 +85,7 @@ pytest = "^7.0"
pytest-cov = "^4.1"
pytest-asyncio = "^0.21.0"
pytest-mock = "^3.11.1"
pytest-loguru = "^0.2.0"

[tool.poetry.group.docs]
optional = true
Expand Down
16 changes: 0 additions & 16 deletions tests/conftest.py

This file was deleted.

8 changes: 4 additions & 4 deletions tests/test_talkytrend_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ async def test_plugin_tv(plugin):
@pytest.mark.asyncio
async def test_plugin_trend(plugin):
"""Test notification """
plugin.check_signal = AsyncMock()
plugin.fetch_signal = AsyncMock()
await plugin.handle_message(f"{settings.bot_prefix}{settings.bot_command_trend}")
plugin.check_signal.assert_awaited_once
plugin.fetch_signal.assert_awaited_once


@pytest.mark.asyncio
async def test_plugin_news(plugin):
"""Test notification """
plugin.fetch_key_feed = AsyncMock()
plugin.fetch_feed = AsyncMock()
await plugin.handle_message(f"{settings.bot_prefix}{settings.bot_command_news}")
plugin.fetch_key_feed.assert_awaited_once
plugin.fetch_feed.assert_awaited_once
32 changes: 23 additions & 9 deletions tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
from tt.bot import app
from tt.config import settings
from tt.plugins.plugin_manager import BasePlugin, PluginManager
from tt.utils import send_notification, start_listener, start_plugins
from tt.utils import send_notification, start_bot, start_plugins

#start_bot, run_bot

@pytest.fixture(scope="session", autouse=True)
def set_test_settings():
Expand All @@ -24,6 +23,10 @@
def listener_test():
return Listener()

@pytest.fixture(name="plugin_manager_obj")
def pluginmngr_test():
return PluginManager()

@pytest.fixture
def message():
return "Test message"
Expand Down Expand Up @@ -65,20 +68,31 @@
assert "json://localhost/" in caplog.text


@pytest.mark.asyncio
async def test_start_listener():
listener, task = await start_listener(max_iterations=1)
assert isinstance(listener, Listener)
assert isinstance(task, asyncio.Task)


@pytest.mark.asyncio
async def test_start_plugins():
plugin_manager = AsyncMock(spec=PluginManager)
await start_plugins(plugin_manager)
plugin_manager.load_plugins.assert_called_once()


@pytest.mark.asyncio
async def test_run_bot(listener_obj, plugin_manager_obj, caplog):
plugin_manager_obj.start_plugins = AsyncMock()
plugin_manager_obj.start_all_plugins = AsyncMock()
assert isinstance(listener_obj, Listener)
Fixed Show fixed Hide fixed
assert isinstance(plugin_manager_obj, PluginManager)
Fixed Show fixed Hide fixed
task = asyncio.create_task(start_bot(listener_obj, plugin_manager_obj))
print(start_bot)
print(task)
assert task is not None
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
assert start_bot is not None
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
# plugin_manager_obj.start_plugins.assert_awaited_once()
# assert any("Plugin loaded" in record.message for record in caplog.records)
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task


@pytest.mark.asyncio
async def test_baseplugins():
plugin = BasePlugin
Expand Down
57 changes: 41 additions & 16 deletions tt/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from asyncz.schedulers.asyncio import AsyncIOScheduler
from dynaconf import Dynaconf
from loguru import logger as log
from loguru import logger as loguru_logger

########################################
### ⚙️ Settings ###
Expand All @@ -36,37 +36,62 @@
default_env="default",
)


########################################
### 🧐 Logging ###
########################################

# logging.basicConfig(
# format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
# level=settings.loglevel
# )

# logger = logging.getLogger("TalkyTrader")
class InterceptHandler(logging.Handler):
def emit(self, record):
# Get corresponding Loguru level if it exists.
try:
level = logger.level(record.levelname).name
except ValueError:
level = record.levelno

# Find caller from where originated the logged message.
frame, depth = sys._getframe(6), 6
while frame and frame.f_code.co_filename == logging.__file__:
frame = frame.f_back
depth += 1

logger.opt(
depth=depth, exception=record.exc_info).log(
level, record.getMessage())

def loguru_setup():
log.remove()
loguru_logger.remove()
# log.configure(**config)
log.add(
log_filters = {
"discord": "INFO",
"telethon": "INFO",
"web3": "INFO",
"apprise": "INFO",
"urllib3": "INFO",
}
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
loguru_logger.add(
sink=sys.stderr,
level=settings.loglevel,
filter=log_filters,
)

return log
return loguru_logger

logger = loguru_setup()

if settings.loglevel == "DEBUG":
logging.getLogger("discord").setLevel(logging.ERROR)
logging.getLogger("telethon").setLevel(logging.ERROR)
logging.getLogger("urllib3").setLevel(logging.ERROR)
logging.getLogger("apprise").setLevel(logging.ERROR)
logging.getLogger("web3").setLevel(logging.ERROR)

# logging.basicConfig(
# format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
# level=settings.loglevel
# )
# logger = logging.getLogger("TalkyTrader")
# if settings.loglevel == "DEBUG":
# logging.getLogger("discord").setLevel(logging.ERROR)
# logging.getLogger("telethon").setLevel(logging.ERROR)
# logging.getLogger("urllib3").setLevel(logging.ERROR)
# logging.getLogger("apprise").setLevel(logging.ERROR)
# logging.getLogger("web3").setLevel(logging.ERROR)

########################################
### ⏱️ Scheduling ###
Expand Down
1 change: 0 additions & 1 deletion tt/plugins/default_plugins/dex_exchange_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,3 @@ async def handle_message(self, msg):
if command in command_mapping:
function = command_mapping[command]
await self.send_notification(f"{await function()}")

12 changes: 4 additions & 8 deletions tt/plugins/default_plugins/talkytrend_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ def __init__(self):
async def start(self):
"""Starts the TalkyTrend plugin"""
if self.enabled:
await self.plugin_notify_schedule_task(
user_name="talky_feed",
function=self.trend.fetch_key_feed)
await self.plugin_notify_cron_task(
user_name="talky_signal",
function=self.trend.check_signal)
user_name="talky_monitor",
function=self.trend.monitor)

async def stop(self):
"""Stops the TalkyTrend plugin"""
Expand All @@ -46,11 +43,10 @@ async def handle_message(self, msg):
settings.bot_command_help: self.trend.get_talkytrend_help,
settings.bot_command_info: self.trend.get_talkytrend_info,
settings.bot_command_tv: self.trend.get_tv,
settings.bot_command_trend: self.trend.check_signal,
settings.bot_command_news: self.trend.fetch_key_feed,
settings.bot_command_trend: self.trend.fetch_signal,
settings.bot_command_news: self.trend.fetch_feed,
}

if command in command_mapping:
function = command_mapping[command]
await self.send_notification(f"{await function()}")

2 changes: 1 addition & 1 deletion tt/plugins/plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ async def plugin_notify_cron_task(
user_timezone="UTC",
function=None):
"""Handles task cron scheduling for notification
monday to Friday at 8AM, 12PM and 4PM with time being UTC based"""
monday to Friday at 8AM, 12PM and 4PM UTC based"""
if function:
self.scheduler.add_task(
name=user_name,
Expand Down
3 changes: 1 addition & 2 deletions tt/talky_settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ talkytrend_commands = "📺 /live\n📰 /news\n📊 /trend"
bot_command_tv = "live"
bot_command_trend = "trend"
bot_command_news = "news"
scanner_frequency = 86400
enable_signals = true
assets = [
{ id ="EURUSD", exchange='FX_IDC',screener="forex"},
Expand Down Expand Up @@ -329,7 +328,7 @@ talkytrend_commands = "📺 /live\n📰 /news\n📊 /trend"
bot_command_tv = "live"
bot_command_trend = "trend"
bot_command_news = "news"
scanner_frequency = 86400

enable_signals = true
assets = [
{ id ="EURUSD", exchange='FX_IDC',screener="forex"},
Expand Down
20 changes: 7 additions & 13 deletions tt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@
body_format=msg_format)


async def start_listener(max_iterations=None):
"""
Start the chat listener.
"""
bot_listener = Listener()
task = asyncio.create_task(bot_listener.run_forever(max_iterations))
return bot_listener, task


async def start_plugins(plugin_manager):
"""
Start all plugins.
Expand All @@ -48,15 +39,19 @@
loop = asyncio.get_running_loop()
loop.create_task(plugin_manager.start_all_plugins())


async def start_bot(listener, plugin_manager):
"""
Listen to the message in the bot channel
and dispatch to plugins
"""
await listener.start()
await start_plugins(plugin_manager)

Check warning on line 49 in tt/utils.py

View check run for this annotation

Codecov / codecov/patch

tt/utils.py#L48-L49

Added lines #L48 - L49 were not covered by tests
while True:
try:
msg = await listener.get_latest_message()
msg = await listener.handler.get_latest_message()

Check warning on line 52 in tt/utils.py

View check run for this annotation

Codecov / codecov/patch

tt/utils.py#L52

Added line #L52 was not covered by tests
if msg and settings.plugin_enabled:
logger.debug("👂 listener: {}", msg)

Check warning on line 54 in tt/utils.py

View check run for this annotation

Codecov / codecov/patch

tt/utils.py#L54

Added line #L54 was not covered by tests
await plugin_manager.process_message(msg)
except Exception as error:
logger.error("👂 listener: {}", error)
Expand All @@ -68,7 +63,6 @@
"""
Run the chat bot & the plugins.
"""
listener, task = await start_listener(max_iterations)
listener = Listener()

Check warning on line 66 in tt/utils.py

View check run for this annotation

Codecov / codecov/patch

tt/utils.py#L66

Added line #L66 was not covered by tests
plugin_manager = PluginManager()
await start_plugins(plugin_manager)
await asyncio.gather(start_bot(listener, plugin_manager), task)
await asyncio.gather(start_bot(listener, plugin_manager))

Check warning on line 68 in tt/utils.py

View check run for this annotation

Codecov / codecov/patch

tt/utils.py#L68

Added line #L68 was not covered by tests