7 from inputparser import InputParser
 
  10     def __init__(self, room_name, fifo_path):
 
  11         self._input_parser = InputParser()
 
  12         self._room_name = room_name
 
  13         self._fifo_path = fifo_path
 
  14         self._joined_room_id = None
 
  16     async def run(self, client):
 
  17         self._log(logging.INFO, "Presence running")
 
  20         done, pending = await asyncio.wait(
 
  21             [asyncio.create_task( self._room_joining_loop(client) ),
 
  22              asyncio.create_task( self._message_loop(client) )],
 
  23             return_when = asyncio.FIRST_EXCEPTION
 
  29         self._log(logging.INFO, "Presence stopped")
 
  32         asyncio.get_running_loop().call_soon_threadsafe(
 
  33             Presence._do_stop, self
 
  40     async def _room_joining_loop(self, client):
 
  44             prior_joined_room_id = self._joined_room_id
 
  45             self._joined_room_id = await self._get_joined_room_id(client)
 
  47             if self._joined_room_id != None:
 
  48                 if self._joined_room_id != prior_joined_room_id:
 
  49                     self._log(logging.INFO, "Joined room")
 
  51                 if self._joined_room_id != prior_joined_room_id:
 
  52                     self._log(logging.INFO, "Got kicked out of room?")
 
  54                     self._log(logging.INFO, "Not yet a room member")
 
  56                 for room_id, room in client.invited_rooms.items():
 
  57                     if room.display_name == self._room_name:
 
  59                         self._log(logging.INFO, "Joining room")
 
  60                         await client.join(room_id)
 
  63                     self._log(logging.INFO, "Got no room invite yet")
 
  65             await asyncio.sleep(3.0)
 
  67     async def _message_loop(self, client):
 
  70         async for line in self._read_fifo(self._fifo_path):
 
  73             if self._joined_room_id != None:
 
  75                     self._input_parser.feed_line(line)
 
  76                 except Exception as e:
 
  77                     self._log(logging.WARNING, "Error parsing input: %s" % str(e))
 
  79                 for content in self._input_parser.fetch_decoded():
 
  80                     await client.room_send(
 
  81                         room_id=self._joined_room_id,
 
  82                         message_type="m.room.message",
 
  86                 self._log(logging.WARNING, "Dropping message cause no room joined")
 
  88     def _tickle_fifo(self):
 
  91             fifo = posix.open(self._fifo_path, posix.O_WRONLY | posix.O_NONBLOCK)
 
  92             posix.write(fifo, "\n".encode())
 
  94             if e.errno == errno.ENXIO:
 
 100     async def _get_joined_room_id(self, client):
 
 101         joined_room_ids = ( await client.joined_rooms() ).rooms
 
 102         for room_id, room in client.rooms.items():
 
 103             if room.display_name == self._room_name:
 
 104                 if room_id in joined_room_ids:
 
 108     def _log(self, level, msg, *args, **kwargs):
 
 109         logging.log(level, "P{%s}: %s" % (self._room_name, msg), *args, **kwargs)
 
 112     async def _read_fifo(file_path):
 
 114             async with aiofiles.open(file_path) as fifo:
 
 115                 async for line in fifo: