diff --git a/session.py b/session.py index 3128098..5c3c687 100644 --- a/session.py +++ b/session.py @@ -5,11 +5,14 @@ User actions import aiohttp import asyncio from datetime import datetime, timedelta +import logging from pathlib import Path from pytz import timezone from typing import TYPE_CHECKING, Optional, Union from slidge import BaseSession, GatewayUser, LegacyContact, LegacyRoster +log = logging.getLogger(__name__) + class Contact(LegacyContact[str]): session: "Session" @@ -38,10 +41,12 @@ ASSETS_DIR = Path(__file__).parent / "assets" class Session(BaseSession[str, Contact]): def __init__(self, user: GatewayUser): self.httpsession = aiohttp.ClientSession() + self.stop_loop = False super().__init__(user) - - def shutdown(self): - super().shutdown() + + async def logout(self): + self.stop_loop = True + await asyncio.sleep(10) # ensure the loop is dead self.httpsession.close() async def login(self): @@ -55,22 +60,30 @@ class Session(BaseSession[str, Contact]): }) as response: json = await response.json() if json['status'] == 'success': + self.xmpp.loop.create_task(self.poll_loop()) return f"Connected as {json['dids'][0]['did']}" else: return f"Failure! {json['status']}" - async def poll_loop(): - while True: - last_15s = datetime.now() - timedelta(seconds=15) - messages = await get_messages(last_15s) + async def poll_loop(self): + last_run_ids = [] + last_run_time = datetime.now() - timedelta(seconds=10) + log.debug('poll loop initiated') + while not self.stop_loop: + current_run_time = datetime.now() + messages = await self.get_messages(last_run_time - timedelta(seconds=2)) - for message in messages: - if 'col_media1' in message: - self.xmpp.send_file(file_url=message['col1_media'], legacy_message_id=message['id']) - elif 'message' in message: - self.xmpp.send_text(message['message'], legacy_msg_id=message['id']) - await asyncio.sleep(15) - + new_messages = [message for message in messages if message['id'] not in last_run_ids] + last_run_ids = [message['id'] for message in messages] + + for message in new_messages: + contact = await self.contacts.by_legacy_id(message['contact']) + if message['col_media1'] != '': + contact.send_file(file_url=message['col1_media'], legacy_message_id=message['id']) + elif message['message'] != '': + contact.send_text(message['message'], legacy_msg_id=message['id']) + last_run_time = current_run_time + await asyncio.sleep(10) # See this issue for timezone explanation https://github.com/michaelkourlas/voipms-sms-client/issues/35 async def get_messages(self, from_time: datetime): @@ -87,16 +100,13 @@ class Session(BaseSession[str, Contact]): 'content_type': 'json', }) as response: json = await response.json() + log.debug(f"received messages from voipms {json}") if json['status'] != 'success': return [] else: return json['sms'] - # SMS doesn't care about presence - async def on_presence(resource: str, show, status: str, resources, merged_resource): - pass - async def on_file(self, chat: Contact, url: str, **_kwargs): f = self.user.registration_form async with self.httpsession.get(API_URL, params={