Various fixes, added bot leave command, handle left rooms in polling modules.

This commit is contained in:
Ville Ranki 2020-01-26 19:20:03 +02:00
parent 5b81671691
commit 1e97742e13
6 changed files with 60 additions and 23 deletions

View File

@ -24,6 +24,7 @@ Bot management commands.
* !bot quit - quit the bot process (Must be done as bot owner) * !bot quit - quit the bot process (Must be done as bot owner)
* !bot reload - reload all bot modules (Must be done as bot owner) * !bot reload - reload all bot modules (Must be done as bot owner)
* !bot stats - show statistics on matrix users seen by bot * !bot stats - show statistics on matrix users seen by bot
* !bot leave - ask bot to leave this room (Must be done as admin in room)
### Help ### Help

5
bot.py
View File

@ -239,6 +239,11 @@ class Bot:
self.client.access_token) self.client.access_token)
await self.client.sync() await self.client.sync()
for roomid in self.client.rooms:
print(f'Bot is on {roomid} with {len(self.client.rooms[roomid].users)} users')
if len(self.client.rooms[roomid].users) == 1:
print(f'Room {roomid} has no other users - leaving it.')
print(await self.client.room_leave(roomid))
self.start() self.start()

View File

@ -45,6 +45,12 @@ class MatrixModule:
homeservers = homeservers[0:10] homeservers = homeservers[0:10]
await bot.send_text(room, f'I\'m seeing {usercount} users in {roomcount} rooms. Top ten homeservers: {homeservers}') await bot.send_text(room, f'I\'m seeing {usercount} users in {roomcount} rooms. Top ten homeservers: {homeservers}')
elif args[1]=='leave':
bot.must_be_admin(room, event)
print(f'{event.sender} asked bot to leave room {room.room_id}')
await bot.send_text(room, f'By your command.')
await bot.client.room_leave(room.room_id)
else: else:
await bot.send_text(room, 'Unknown command, sorry.') await bot.send_text(room, 'Unknown command, sorry.')

View File

@ -9,6 +9,8 @@ class PollingService:
self.account_rooms = dict() # Roomid -> [account, account..] self.account_rooms = dict() # Roomid -> [account, account..]
self.next_poll_time = dict() # Roomid -> datetime, None = not polled yet self.next_poll_time = dict() # Roomid -> datetime, None = not polled yet
self.service_name = "Service" self.service_name = "Service"
self.poll_interval_min = 30 # TODO: Configurable
self.poll_interval_random = 30
async def matrix_poll(self, bot, pollcount): async def matrix_poll(self, bot, pollcount):
if len(self.account_rooms): if len(self.account_rooms):
@ -16,16 +18,23 @@ class PollingService:
async def poll_all_accounts(self, bot): async def poll_all_accounts(self, bot):
now = datetime.now() now = datetime.now()
delete_rooms = []
for roomid in self.account_rooms: for roomid in self.account_rooms:
send_messages = True if roomid in bot.client.rooms:
# First poll send_messages = True
if not self.next_poll_time.get(roomid, None): # First poll
self.next_poll_time[roomid] = now + timedelta(hours=-1) if not self.next_poll_time.get(roomid, None):
send_messages = False self.next_poll_time[roomid] = now + timedelta(hours=-1)
if now >= self.next_poll_time.get(roomid): send_messages = False
accounts = self.account_rooms[roomid] if now >= self.next_poll_time.get(roomid):
for account in accounts: accounts = self.account_rooms[roomid]
await self.poll_account(bot, account, roomid, send_messages) for account in accounts:
await self.poll_account(bot, account, roomid, send_messages)
else:
print(f'Bot is no longer in room {roomid} - deleting it from {self.service_name} room list')
delete_rooms.append(roomid)
for roomid in delete_rooms:
self.account_rooms.pop(roomid, None)
self.first_run = False self.first_run = False
@ -33,7 +42,7 @@ class PollingService:
pass pass
async def poll_account(self, bot, account, roomid, send_messages): async def poll_account(self, bot, account, roomid, send_messages):
polldelay = timedelta(minutes=30 + randrange(30)) polldelay = timedelta(minutes=self.poll_interval_min + randrange(self.poll_interval_random))
self.next_poll_time[roomid] = datetime.now() + polldelay self.next_poll_time[roomid] = datetime.now() + polldelay
await self.poll_implementation(bot, account, roomid, send_messages) await self.poll_implementation(bot, account, roomid, send_messages)
@ -45,13 +54,15 @@ class PollingService:
if len(args) == 2: if len(args) == 2:
if args[1] == 'list': if args[1] == 'list':
await bot.send_text(room, f'{self.service_name} accounts in this room: {self.account_rooms.get(room.room_id) or []}') await bot.send_text(room, f'{self.service_name} accounts in this room: {self.account_rooms.get(room.room_id) or []}')
if args[1] == 'debug': elif args[1] == 'debug':
await bot.send_text(room, f"{self.service_name} accounts: {self.account_rooms.get(room.room_id) or []} - known ids: {self.known_ids}\n" \ await bot.send_text(room, f"{self.service_name} accounts: {self.account_rooms.get(room.room_id) or []} - known ids: {self.known_ids}\n" \
f"Next poll in this room at {self.next_poll_time.get(room.room_id)} - in {self.next_poll_time.get(room.room_id) - datetime.now()}") f"Next poll in this room at {self.next_poll_time.get(room.room_id)} - in {self.next_poll_time.get(room.room_id) - datetime.now()}")
elif args[1] == 'poll': elif args[1] == 'poll':
bot.must_be_owner(event) bot.must_be_owner(event)
print(f'{self.service_name} force polling requested by {event.sender}')
# Faking next poll times to force poll
for roomid in self.account_rooms: for roomid in self.account_rooms:
self.next_poll_time[roomid] = datetime.now() self.next_poll_time[roomid] = datetime.now() - timedelta(hours=1)
await self.poll_all_accounts(bot) await self.poll_all_accounts(bot)
elif args[1] == 'clear': elif args[1] == 'clear':
bot.must_be_admin(room, event) bot.must_be_admin(room, event)

View File

@ -40,11 +40,18 @@ class MatrixModule:
self.daily_commands = data['daily_commands'] self.daily_commands = data['daily_commands']
async def matrix_poll(self, bot, pollcount): async def matrix_poll(self, bot, pollcount):
delete_rooms = []
if self.last_hour != datetime.now().hour: if self.last_hour != datetime.now().hour:
self.last_hour = datetime.now().hour self.last_hour = datetime.now().hour
for room_id in self.daily_commands: for room_id in self.daily_commands:
commands = self.daily_commands[room_id] if room_id in bot.client.rooms:
for command in commands: commands = self.daily_commands[room_id]
if int(command['time']) == self.last_hour: for command in commands:
await bot.send_text(bot.get_room_by_id(room_id), command['command']) if int(command['time']) == self.last_hour:
await bot.send_text(bot.get_room_by_id(room_id), command['command'])
else:
delete_rooms.append(room_id)
for roomid in delete_rooms:
self.daily_commands.pop(roomid, None)

View File

@ -90,14 +90,21 @@ class MatrixModule:
return('Polls teamup calendar.') return('Polls teamup calendar.')
async def poll_all_calendars(self, bot): async def poll_all_calendars(self, bot):
delete_rooms = []
for roomid in self.calendar_rooms: for roomid in self.calendar_rooms:
calendars = self.calendar_rooms[roomid] if roomid in bot.client.rooms:
for calendarid in calendars: calendars = self.calendar_rooms[roomid]
events, timestamp = self.poll_server( for calendarid in calendars:
self.calendars[calendarid]) events, timestamp = self.poll_server(
self.calendars[calendarid].timestamp = timestamp self.calendars[calendarid])
for event in events: self.calendars[calendarid].timestamp = timestamp
await bot.send_text(bot.get_room_by_id(roomid), 'Calendar: ' + self.eventToString(event)) for event in events:
await bot.send_text(bot.get_room_by_id(roomid), 'Calendar: ' + self.eventToString(event))
else:
delete_rooms.append(roomid)
for roomid in delete_rooms:
self.calendar_rooms.pop(roomid, None)
def poll_server(self, calendar): def poll_server(self, calendar):
events, timestamp = calendar.get_changed_events(calendar.timestamp) events, timestamp = calendar.get_changed_events(calendar.timestamp)