@asyncio.coroutine
def set_idle(idle):
- yield from client.change_status(idle = idle)
+ yield from client.change_presence(status = discord.Status.idle if idle else discord.Status.online)
for voice in list(client.voice_clients):
yield from voice.disconnect()
highest = role
return highest
-# Discord API 0.13 has is_superset() to do this.
-def equal_permission(x, y, *, strict = True):
+def lower_role_than(member, *, strict = False):
+ if server.me is None:
+ log.error("Can't call lower_role_than() a member on a server we aren't on!")
+ return False
+ if strict:
+ return member.top_role > server.me.top_role
+ else:
+ return member.top_role >= server.me.top_role
+
+def lower_role_on_server_than(server, id, *, strict = False):
+ member = server.get_member(id)
+ if member is None:
+ log.error("Can't call lower_role_on_server_than() a member not on the server!")
+ return False
+ return lower_role_than(member, strict = strict)
+
+def equal_permissions(x, y, *, strict = True):
if x == y:
return True
- if x and not y and not strict:
+ if x.is_subset(y) and not strict:
return True
return False
-# Discord API 0.13 has == to do this.
-def equal_permissions(x, y, *, strict = True):
- if not equal_permission(x.create_instant_invite, y.create_instant_invite, strict = strict):
- return False
- if not equal_permission(x.kick_members, y.kick_members, strict = strict):
- return False
- if not equal_permission(x.ban_members, y.ban_members, strict = strict):
- return False
- if not equal_permission(x.administrator, y.administrator, strict = strict):
- return False
- if not equal_permission(x.manage_channels, y.manage_channels, strict = strict):
- return False
- if not equal_permission(x.manage_server, y.manage_server, strict = strict):
- return False
- if not equal_permission(x.read_messages, y.read_messages, strict = strict):
- return False
- if not equal_permission(x.send_messages, y.send_messages, strict = strict):
- return False
- if not equal_permission(x.send_tts_messages, y.send_tts_messages, strict = strict):
- return False
- if not equal_permission(x.manage_messages, y.manage_messages, strict = strict):
- return False
- if not equal_permission(x.embed_links, y.embed_links, strict = strict):
- return False
- if not equal_permission(x.attach_files, y.attach_files, strict = strict):
- return False
- if not equal_permission(x.read_message_history, y.read_message_history, strict = strict):
- return False
- if not equal_permission(x.mention_everyone, y.mention_everyone, strict = strict):
- return False
- if not equal_permission(x.external_emojis, y.external_emojis, strict = strict):
- return False
- if not equal_permission(x.connect, y.connect, strict = strict):
- return False
- if not equal_permission(x.speak, y.speak, strict = strict):
- return False
- if not equal_permission(x.mute_members, y.mute_members, strict = strict):
- return False
- if not equal_permission(x.deafen_members, y.deafen_members, strict = strict):
- return False
- if not equal_permission(x.move_members, y.move_members, strict = strict):
- return False
- if not equal_permission(x.use_voice_activation, y.use_voice_activation, strict = strict):
- return False
- if not equal_permission(x.change_nickname, y.change_nickname, strict = strict):
- return False
- if not equal_permission(x.manage_nicknames, y.manage_nicknames, strict = strict):
- return False
- if not equal_permission(x.manage_roles, y.manage_roles, strict = strict):
- return False
- #if not equal_permission(x.manage_webhooks, y.manage_webhooks, strict = strict):
- #return False
- #if not equal_permission(x.manage_emojis, y.manage_emojis, strict = strict):
- #return False
- return True
-
@asyncio.coroutine
def overwrite_permissions(channel, whom, overwrite, *, strict = True):
permissions = channel.overwrites_for(whom)
- if equal_permissions(permissions, overwrite, strict = strict):
+ if equal_permissions(permissions.pair(), overwrite.pair(), strict = strict):
log.debug('Permissions for {} in {} are already correct.'.format(whom.name, channel.name))
return
log.info('Setting permissions for {} in {} to {}'.format(whom.name, channel.name, permissions.__dict__))
self.dbh.commit()
def get_all_feeds(self, client, servers = []):
- yield from self.get_all_from_table(client, 'feeds', servers)
+ for row in self.get_all_from_table(client, 'feeds', servers):
+ yield row
def get_feeds(self, client):
now = self.now()
else:
return k
- @asyncio.coroutine
- def set_rss_permissions(self, channel_id):
+ async def set_rss_permissions(self, channel_id):
channel = client.get_channel(channel_id)
if channel is None:
log.warning("Can't get channel {} for RSS feeds.".format(channel_id))
return
role = None
# My highest role.
- role = bot.highest_role(channel.server.me.roles)
+ role = channel.server.me.top_role
if role is not None:
# Permissions for bot.
overwrite = discord.PermissionOverwrite()
overwrite.send_tts_messages = True
overwrite.manage_messages = True
overwrite.attach_files = True
- yield from bot.overwrite_permissions(channel, role, overwrite, strict = False)
+ await bot.overwrite_permissions(channel, role, overwrite, strict = False)
# Permissions for @everyone.
overwrite = discord.PermissionOverwrite()
overwrite.read_messages = True
overwrite.read_message_history = True
overwrite.send_messages = False
overwrite.send_tts_messages = False
- yield from bot.overwrite_permissions(channel, channel.server.default_role, overwrite)
+ await bot.overwrite_permissions(channel, channel.server.default_role, overwrite)
- @asyncio.coroutine
- def do_rss(self, feeds):
+ async def do_rss(self, feeds):
channel_id = str(feeds[0]['channel_id'])
channel = client.get_channel(channel_id)
if not channel:
limit = max(len(all_entries) * 2, int(bot.get('message_limit') * 1.5))
digests = []
- logs = yield from client.logs_from(channel, limit = limit)
- for message in logs:
+ async for message in client.logs_from(channel, limit = limit):
digest = bot.digest(message.content)
log.debug('Saw previously posted RSS with digest {}'.format(digest))
if digest not in digests:
log.info('Dryrun: Not posting to {}: {}'.format(channel, formatted))
else:
log.info('Posting to {}: {}'.format(channel, formatted))
- message = yield from bot.say(channel, formatted)
+ message = await bot.say(channel, formatted)
digest = bot.digest(message.content)
digests.append(digest)
log.debug('Posted RSS with digest {}'.format(digest))
for id, update in updates.items():
self.update_feed(client, id, **update)
- @asyncio.coroutine
- def on_ready(self):
+ async def on_ready(self):
while True:
feeds = {}
for feed in list(self.get_feeds(client)):
feeds[feed['channel_id']].append(feed)
for channel_id in feeds.keys():
if any([bot.parse_boolean(feed['permissions']) for feed in feeds[channel_id]]):
- yield from self.set_rss_permissions(channel_id)
- yield from self.do_rss(feeds[channel_id])
- yield from asyncio.sleep(rsstime.value)
+ await self.set_rss_permissions(channel_id)
+ await self.do_rss(feeds[channel_id])
+ await asyncio.sleep(rsstime.value)
def valid_commands(self):
return ['news', 'feed']
- @asyncio.coroutine
- def handle_command(self, message, command, raw):
+ async def handle_command(self, message, command, raw):
if command not in self.valid_commands():
return PluginCommand.ignored
- yield from self.manage_feeds(message, shlex.split(raw)[1:])
+ await self.manage_feeds(message, shlex.split(raw)[1:])
return PluginCommand.exclusive
- @asyncio.coroutine
- def handle_help(self, message, command, *args):
- yield from self.help_feeds(message, *args)
+ async def handle_help(self, message, command, *args):
+ await self.help_feeds(message, *args)
- @asyncio.coroutine
- def manage_feeds(self, message, args):
+ async def manage_feeds(self, message, args):
if not len(args):
- yield from self.list_feeds(message)
+ await self.list_feeds(message)
return
command = args[0].lower()
if len(args) == 1:
if command == 'list':
- yield from self.list_feeds(message)
+ await self.list_feeds(message)
return
elif command == 'help':
- yield from self.help_feeds(message)
+ await self.help_feeds(message)
return
else:
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
return
if command == 'show':
- yield from self.show_feed(message, args[1])
+ await self.show_feed(message, args[1])
elif command == 'help':
- yield from self.help_feeds(message, args[1])
+ await self.help_feeds(message, args[1])
elif command == 'delete':
- yield from self.delete_existing_feed(message, args[1])
+ await self.delete_existing_feed(message, args[1])
elif command == 'pause':
- yield from self.schedule_feed(message, args[1], pause = True)
+ await self.schedule_feed(message, args[1], pause = True)
elif command == 'resume':
- yield from self.schedule_feed(message, args[1], pause = False)
+ await self.schedule_feed(message, args[1], pause = False)
elif command == 'create':
- yield from self.create_new_feed(message, args)
+ await self.create_new_feed(message, args)
elif command == 'edit':
- yield from self.edit_existing_feed(message, args)
+ await self.edit_existing_feed(message, args)
elif command == 'time':
- yield from self.set_poll_time(message, args[1])
+ await self.set_poll_time(message, args[1])
else:
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
- @asyncio.coroutine
- def can_manage_feeds(self, author, channel, command, **args):
+ async def can_manage_feeds(self, author, channel, command, **args):
# Anyone can list feeds.
if command == 'list':
log.debug('Anyone can list feeds.')
if feed is not None:
server = client.get_server(feed['server_id'])
member = server.get_member(author.id)
- bot_member = server.get_member(client.user.id)
- member_role = bot.highest_role(member.roles)
- bot_role = bot.highest_role(bot_member.roles)
- if member_role.position >= bot_role.position:
- log.debug('Member {} with role {} on server {} can manage feeds.'.format(member.name, member_role.name, server.name))
+ if bot.lower_role_than(member):
+ log.debug('Member {} with role {} on server {} can manage feeds.'.format(member.name, member.top_role, server.name))
return feed
if command in ['time']:
if bot.is_admin(member, member.server):
return True
- yield from cat.hiss(channel)
+ await cat.hiss(channel)
return False
- @asyncio.coroutine
- def list_feeds(self, message):
- result = yield from self.can_manage_feeds(message.author, message.channel, 'list')
+ async def list_feeds(self, message):
+ result = await self.can_manage_feeds(message.author, message.channel, 'list')
if not result:
return
results.append(text)
if len(results):
- yield from bot.say_many(message.channel, results)
+ await bot.say_many(message.channel, results)
else:
- yield from cat.shrug(message.channel)
+ await cat.shrug(message.channel)
- @asyncio.coroutine
- def show_feed(self, message, id):
- feed = yield from self.can_manage_feeds(message.author, message.channel, 'show', id = id)
+ async def show_feed(self, message, id):
+ feed = await self.can_manage_feeds(message.author, message.channel, 'show', id = id)
if not feed:
return
lines = []
text += "--link_json '{}'".format(feed['link_json'])
lines.append(text)
- yield from bot.say_many(message.channel, lines)
+ await bot.say_many(message.channel, lines)
- @asyncio.coroutine
- def parse_feed(self, message, args, editing = False):
+ async def parse_feed(self, message, args, editing = False):
parsed = {}
if editing:
command = 'edit'
else:
break
else:
- yield from bot.say(message.channel, 'What is {}?'.format(arg))
+ await bot.say(message.channel, 'What is {}?'.format(arg))
return
if ok:
if not ok:
log.info('Failed to parse feed. Got: {}'.format(parsed))
- yield from bot.say(message.channel, '{}?'.format(arg))
+ await bot.say(message.channel, '{}?'.format(arg))
return None
if 'channel_id' in parsed:
channel = client.get_channel(parsed['channel_id'])
if not channel:
- yield from bot.say(message.channel, 'Invalid channel!')
+ await bot.say(message.channel, 'Invalid channel!')
return None
server = channel.server
parsed['server_id'] = server.id
if editing:
if 'id' not in parsed:
- yield from bot.say(message.channel, 'Missing ID!')
+ await bot.say(message.channel, 'Missing ID!')
return None
else:
if 'channel_id' not in parsed:
- yield from bot.say(message.channel, 'Missing channel!')
+ await bot.say(message.channel, 'Missing channel!')
return None
if 'url' not in parsed:
- yield from bot.say(message.channel, 'Missing URL!')
+ await bot.say(message.channel, 'Missing URL!')
return None
if 'description' not in parsed:
- yield from bot.say(message.channel, 'Missing title!')
+ await bot.say(message.channel, 'Missing title!')
return None
if 'show_date' not in parsed:
parsed['show_date'] = True
return parsed
- @asyncio.coroutine
- def create_new_feed(self, message, *args):
+ async def create_new_feed(self, message, *args):
# feed create [params]: <text>
- create = yield from self.parse_feed(message, *args)
+ create = await self.parse_feed(message, *args)
if create is None:
return
- feed = yield from self.can_manage_feeds(message.author, message.channel, 'create', create = create)
+ feed = await self.can_manage_feeds(message.author, message.channel, 'create', create = create)
if not feed:
return
if id:
create['id'] = id
log.info('Created feed: {}'.format(create))
- yield from bot.say(message.channel, id)
- yield from cat.purr(None, bot.voice_channel_for_user(message.author), join = False)
+ await bot.say(message.channel, id)
+ await cat.purr(None, bot.voice_channel_for_user(message.author), join = False)
else:
log.info('Failed to create feed: {}'.format(create))
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
- @asyncio.coroutine
- def edit_existing_feed(self, message, *args):
- update = yield from self.parse_feed(message, *args, editing = True)
+ async def edit_existing_feed(self, message, *args):
+ update = await self.parse_feed(message, *args, editing = True)
if update is None:
return
id = update['id']
del(update['id'])
- feed = yield from self.can_manage_feeds(message.author, message.channel, 'edit', id = id)
+ feed = await self.can_manage_feeds(message.author, message.channel, 'edit', id = id)
if not feed:
return
if not len(update.keys()):
- yield from bot.say(message.channel, '?')
+ await bot.say(message.channel, '?')
return
if self.update_feed(client, id, **update):
log.info('Edited feed {}: {}'.format(id, update))
- yield from bot.say(message.channel, ', '.join([self.feed_key(k) for k in update]))
- yield from cat.purr(None, bot.voice_channel_for_user(message.author), join = False)
+ await bot.say(message.channel, ', '.join([self.feed_key(k) for k in update]))
+ await cat.purr(None, bot.voice_channel_for_user(message.author), join = False)
else:
log.info('Failed to edit feed {}: {}'.format(id, update))
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
- @asyncio.coroutine
- def delete_existing_feed(self, message, id):
- feed = yield from self.can_manage_feeds(message.author, message.channel, 'delete', id = id)
+ async def delete_existing_feed(self, message, id):
+ feed = await self.can_manage_feeds(message.author, message.channel, 'delete', id = id)
if not feed:
return
if bot.get('dryrun'):
else:
log.info('Deleting feed {}'.format(id))
if self.delete_feed(client, id):
- yield from cat.purr(message.channel)
+ await cat.purr(message.channel)
else:
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
- @asyncio.coroutine
- def schedule_feed(self, message, id, **args):
- feed = yield from self.can_manage_feeds(message.author, message.channel, 'schedule', id = id)
+ async def schedule_feed(self, message, id, **args):
+ feed = await self.can_manage_feeds(message.author, message.channel, 'schedule', id = id)
if not feed:
return
else:
log.info('Updating feed {}: {}'.format(id, update))
if self.update_feed(client, id, **update):
- yield from cat.purr(message.channel)
+ await cat.purr(message.channel)
else:
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
- @asyncio.coroutine
- def set_poll_time(self, message, *args):
+ async def set_poll_time(self, message, *args):
seconds = bot.parse_seconds(args[0])
if seconds < 60:
- yield from bot.say(message.channel, 'At least 60!')
+ await bot.say(message.channel, 'At least 60!')
else:
rsstime.value = seconds
- @asyncio.coroutine
- def help_feeds(self, message, command = None):
+ async def help_feeds(self, message, command = None):
if command is None:
lines = [
'Commands to manage news feeds are:',
]
else:
lines = ['*shrugs*']
- yield from bot.say_many(message.channel, lines)
+ await bot.say_many(message.channel, lines)