lanonna
This commit is contained in:
parent
d831c8c70a
commit
710d52ee3a
6 changed files with 90 additions and 11 deletions
|
@ -10,6 +10,7 @@ class Configuration(NamedTuple):
|
||||||
matrix_username: str
|
matrix_username: str
|
||||||
matrix_password: str
|
matrix_password: str
|
||||||
mq_url: str
|
mq_url: str
|
||||||
|
db_url: str
|
||||||
|
|
||||||
|
|
||||||
def init() -> Union[str | Configuration]:
|
def init() -> Union[str | Configuration]:
|
||||||
|
@ -28,7 +29,7 @@ def init() -> Union[str | Configuration]:
|
||||||
return missing_key('lanonna')
|
return missing_key('lanonna')
|
||||||
|
|
||||||
conf = conf['lanonna']
|
conf = conf['lanonna']
|
||||||
keys = ('matrix_url', 'matrix_username', 'matrix_password', 'mq_url')
|
keys = ('matrix_url', 'matrix_username', 'matrix_password', 'mq_url', 'db_url')
|
||||||
|
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if key not in conf:
|
if key not in conf:
|
||||||
|
|
25
lanonna/db.py
Normal file
25
lanonna/db.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import psycopg
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||||||
|
|
||||||
|
async def update_last_seen(db_conn: psycopg.AsyncConnection, now: datetime.datetime):
|
||||||
|
print('UPDATING LAST SEEN')
|
||||||
|
now_st = now.strftime(TIME_FORMAT)
|
||||||
|
query = f"""
|
||||||
|
UPDATE kv SET store = store || '"value" => "{now_st}"' where store->'key' = 'lanonna';
|
||||||
|
"""
|
||||||
|
print(query)
|
||||||
|
|
||||||
|
async with db_conn.cursor() as cur:
|
||||||
|
await cur.execute(query)
|
||||||
|
|
||||||
|
async def last_seen(db_conn: psycopg.AsyncConnection):
|
||||||
|
query = "select store->'value' from kv where store->'key' = 'lanonna';"
|
||||||
|
|
||||||
|
async with db_conn.cursor() as cur:
|
||||||
|
await cur.execute(query)
|
||||||
|
tp = await cur.fetchone()
|
||||||
|
time_st = tp[0]
|
||||||
|
print(time_st)
|
||||||
|
return datetime.datetime.strptime(time_st, TIME_FORMAT)
|
|
@ -1,23 +1,37 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
import psycopg
|
||||||
|
|
||||||
|
|
||||||
import matrix
|
import matrix
|
||||||
import mq
|
import mq
|
||||||
import protocol
|
import protocol
|
||||||
import config
|
import config
|
||||||
|
import db
|
||||||
|
|
||||||
logger = logging.getLogger('lanonna')
|
logger = logging.getLogger('lanonna')
|
||||||
logger.setLevel(logging.WARNING)
|
logger.setLevel(logging.WARNING)
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
async def matrixmain(matrix_client: matrix.MatrixClient, mq_client: mq.MQClient):
|
|
||||||
from nio import RoomMessageText
|
|
||||||
|
|
||||||
|
|
||||||
|
async def matrixmain(matrix_client: matrix.MatrixClient, mq_client: mq.MQClient, db_connection: psycopg.AsyncConnection):
|
||||||
|
from nio import RoomMessageText, MatrixRoom
|
||||||
|
|
||||||
|
last_seen = await db.last_seen(db_connection)
|
||||||
client = matrix_client.client
|
client = matrix_client.client
|
||||||
|
|
||||||
callback = lambda r, e: matrix.message_received_cb(matrix_client, mq_client, logger, r, e)
|
async def callback(room: MatrixRoom, event: RoomMessageText):
|
||||||
|
import datetime
|
||||||
|
server_timestamp = event.server_timestamp / 1000
|
||||||
|
dt_received = datetime.datetime.fromtimestamp(server_timestamp)
|
||||||
|
print(dt_received, ' >= ', last_seen)
|
||||||
|
if dt_received > last_seen:
|
||||||
|
handled = await matrix.message_received_cb(matrix_client, mq_client, logger, room, event)
|
||||||
|
if handled:
|
||||||
|
await db.update_last_seen(db_connection, dt_received)
|
||||||
|
|
||||||
client.add_event_callback(callback, RoomMessageText)
|
client.add_event_callback(callback, RoomMessageText)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -49,10 +63,11 @@ async def main(conf: config.Configuration):
|
||||||
mq_client = await mq.initialize(conf)
|
mq_client = await mq.initialize(conf)
|
||||||
matrix_client = await matrix.initialize(conf)
|
matrix_client = await matrix.initialize(conf)
|
||||||
|
|
||||||
await asyncio.gather(
|
async with await psycopg.AsyncConnection.connect(conf.db_url, autocommit=True) as db_connection:
|
||||||
mqmain(mq_client, matrix_client),
|
await asyncio.gather(
|
||||||
matrixmain(matrix_client, mq_client)
|
mqmain(mq_client, matrix_client),
|
||||||
)
|
matrixmain(matrix_client, mq_client, db_connection)
|
||||||
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
configuration = config.init()
|
configuration = config.init()
|
||||||
|
|
|
@ -42,7 +42,8 @@ async def message_received_cb(matrix_client: MatrixClient,
|
||||||
rabbit_client: mq.MQClient,
|
rabbit_client: mq.MQClient,
|
||||||
logger: logging.Logger,
|
logger: logging.Logger,
|
||||||
room: MatrixRoom,
|
room: MatrixRoom,
|
||||||
event: RoomMessageText):
|
event: RoomMessageText) -> bool:
|
||||||
|
'''Returns a boolean indicating if the message ct and could be handled'''
|
||||||
import mq
|
import mq
|
||||||
cmd = commands.parse(event.body)
|
cmd = commands.parse(event.body)
|
||||||
if cmd:
|
if cmd:
|
||||||
|
@ -58,5 +59,7 @@ async def message_received_cb(matrix_client: MatrixClient,
|
||||||
else:
|
else:
|
||||||
help_ = protocol.unknown_cmd_help_reply(swm)
|
help_ = protocol.unknown_cmd_help_reply(swm)
|
||||||
await send_text(matrix_client, help_)
|
await send_text(matrix_client, help_)
|
||||||
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"Can't route switchboard message: {swm}|{str(e)}")
|
logging.exception(f"Can't route switchboard message: {swm}|{str(e)}")
|
||||||
|
return False
|
||||||
|
|
38
lanonna/poetry.lock
generated
38
lanonna/poetry.lock
generated
|
@ -1,4 +1,4 @@
|
||||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aio-pika"
|
name = "aio-pika"
|
||||||
|
@ -666,6 +666,29 @@ files = [
|
||||||
dev = ["pre-commit", "tox"]
|
dev = ["pre-commit", "tox"]
|
||||||
testing = ["pytest", "pytest-benchmark"]
|
testing = ["pytest", "pytest-benchmark"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psycopg"
|
||||||
|
version = "3.1.18"
|
||||||
|
description = "PostgreSQL database adapter for Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "psycopg-3.1.18-py3-none-any.whl", hash = "sha256:4d5a0a5a8590906daa58ebd5f3cfc34091377354a1acced269dd10faf55da60e"},
|
||||||
|
{file = "psycopg-3.1.18.tar.gz", hash = "sha256:31144d3fb4c17d78094d9e579826f047d4af1da6a10427d91dfcfb6ecdf6f12b"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
typing-extensions = ">=4.1"
|
||||||
|
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
binary = ["psycopg-binary (==3.1.18)"]
|
||||||
|
c = ["psycopg-c (==3.1.18)"]
|
||||||
|
dev = ["black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.4.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"]
|
||||||
|
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||||
|
pool = ["psycopg-pool"]
|
||||||
|
test = ["anyio (>=3.6.2,<4.0)", "mypy (>=1.4.1)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycryptodome"
|
name = "pycryptodome"
|
||||||
version = "3.20.0"
|
version = "3.20.0"
|
||||||
|
@ -894,6 +917,17 @@ files = [
|
||||||
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
|
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tzdata"
|
||||||
|
version = "2024.1"
|
||||||
|
description = "Provider of IANA time zone data"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2"
|
||||||
|
files = [
|
||||||
|
{file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"},
|
||||||
|
{file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unpaddedbase64"
|
name = "unpaddedbase64"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
@ -1011,4 +1045,4 @@ multidict = ">=4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "a301f2cf3a027197e35c16424aed8999ab4b934342241bd489100078f6c05dc3"
|
content-hash = "77fdac2b28bc2f077d2a50f1a41dd80c3f494842f453f9da4e1d38c526716847"
|
||||||
|
|
|
@ -12,6 +12,7 @@ matrix-nio = "^0.23.0"
|
||||||
pika = "^1.3.2"
|
pika = "^1.3.2"
|
||||||
aio-pika = "^9.3.1"
|
aio-pika = "^9.3.1"
|
||||||
markdown = "^3.5.1"
|
markdown = "^3.5.1"
|
||||||
|
psycopg = "^3.1.18"
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
|
Loading…
Reference in a new issue