async def set_interval(message, client): if message.author not in get_patrons('Donor'): await message.channel.send(embed=discord.Embed( description= 'You need to be a Patron (donating 2$ or more) to access this command! Type `$donate` to find out more.' )) return args = message.content.split(' ') args.pop(0) # remove the command item if len(args) < 3: await message.channel.send(embed=discord.Embed( title='interval', description= '**Usage** ```$interval [channel mention or user mention] <time to or time at> <interval> <message>```\n\n**Example** ```$interval #general 9:30 1d Good morning!``` ```$interval 0s 10s This will be really irritating```' )) return scope = message.channel.id pref = '#' if args[0].startswith('<'): # if a scope is provided if args[0][2:-1][0] == '!': tag = int(args[0][3:-1]) else: try: tag = int(args[0][2:-1]) except ValueError: await message.channel.send(embed=discord.Embed( description= 'Please ensure your tag links directly to a user or channel, not a role.' )) if args[0][1] == '@': # if the scope is a user pref = '@' scope = message.guild.get_member(tag) else: pref = '#' scope = message.guild.get_channel(tag) if scope == None: await message.channel.send(embed=discord.Embed( description='Couldn\'t find a location by your tag present.')) return else: scope = scope.id args.pop(0) msg_time = format_time(args[0], message.guild.id) if msg_time == None: await message.channel.send(embed=discord.Embed( description= 'Make sure the time you have provided is in the format of [num][s/m/h/d][num][s/m/h/d] etc. or `day`/`month`/`year`-`hour`:`minute`:`second`.\n\n*This feature was reworked on the 21/01/2018. Please check the help menu*' )) return args.pop(0) msg_interval = format_time(args[0], message.guild.id) if msg_interval == None: await message.channel.send(embed=discord.Embed( description= 'Make sure the interval you have provided is in the format of [num][s/m/h/d][num][s/m/h/d] etc. with no spaces, eg. 10s for 10 seconds or 10s12m15h1d for 10 seconds, 12 minutes, 15 hours and 1 day.' )) return elif msg_interval < 8: await message.channel.send(embed=discord.Embed( description= 'Please make sure your interval timer is longer than 8 seconds.')) return msg_interval -= time.time() msg_interval = round(msg_interval) args.pop(0) msg_text = ' '.join(args) if len(msg_text) > 150 and message.author not in get_patrons('Patrons'): await message.channel.send(embed=discord.Embed( description= 'Interval message too long! (max 150, you used {}). Use `$donate` to increase your character limit to 400 ($5 tier)' .format(len(msg_text)))) return if pref == '#': if not message.author.guild_permissions.administrator: if scope not in restrictions.keys(): restrictions[scope] = [] for role in message.author.roles: if role.id in restrictions[scope]: break else: await message.channel.send(embed=discord.Embed( description= 'You must be either admin or have a role capable of sending reminders to that channel. Please talk to your server admin, and tell her/him to use the `$restrict` command to specify allowed roles.' )) return intervals.append([msg_time, msg_interval, scope, msg_text]) await message.channel.send(embed=discord.Embed( description= 'New interval registered for <{}{}> in {} seconds . You can\'t edit the reminder now, so you are free to delete the message.' .format(pref, scope, round(msg_time - time.time())))) print('Registered a new interval for {}'.format(message.guild.name))
async def set_reminder(message, client): args = message.content.split(' ') args.pop(0) # remove the command item if len(args) < 2: await message.channel.send(embed=discord.Embed( title='remind', description= '**Usage** ```$remind [channel mention or user mention] <time to or time at> <message>```\n\n**Example** ```$remind #general 10s Hello world``` ```$remind 10:30 It\'s now 10:30```' )) return scope = message.channel.id pref = '#' if args[0].startswith('<'): # if a scope is provided if args[0][2:-1][0] == '!': tag = int(args[0][3:-1]) else: try: tag = int(args[0][2:-1]) except ValueError: await message.channel.send(embed=discord.Embed( description= 'Please ensure your tag links directly to a user or channel, not a role.' )) return if args[0][1] == '@': # if the scope is a user pref = '@' scope = message.guild.get_member(tag) else: pref = '#' scope = message.guild.get_channel(tag) if scope == None: await message.channel.send(embed=discord.Embed( description='Couldn\'t find a location by your tag present.')) return else: scope = scope.id args.pop(0) msg_time = format_time(args[0], message.guild.id) if msg_time == None: await message.channel.send(embed=discord.Embed( description= 'Make sure the time you have provided is in the format of [num][s/m/h/d][num][s/m/h/d] etc. or `day`/`month`/`year`-`hour`:`minute`:`second`.\n\n*This feature was reworked on the 21/01/2018. Please check the help menu*' )) return args.pop(0) msg_text = ' '.join(args) if count_reminders(scope) > 5 and message.author not in get_patrons( 'Patrons'): await message.channel.send(embed=discord.Embed( description= 'Too many reminders in specified channel! Use `$del` to delete some of them, or use `$donate` to increase your maximum ($5 tier)' )) return if len(msg_text) > 150 and message.author not in get_patrons('Patrons'): await message.channel.send(embed=discord.Embed( description= 'Reminder message too long! (max 150, you used {}). Use `$donate` to increase your character limit to 400 ($5 tier)' .format(len(msg_text)))) return if pref == '#': if not message.author.guild_permissions.administrator: if scope not in restrictions.keys(): restrictions[scope] = [] for role in message.author.roles: if role.id in restrictions[scope]: break else: await message.channel.send(embed=discord.Embed( description= 'You must be either admin or have a role capable of sending reminders to that channel. Please talk to your server admin, and tell her/him to use the `$restrict` command to specify allowed roles.' )) return calendar.append([msg_time, scope, msg_text]) await message.channel.send(embed=discord.Embed( description= 'New reminder registered for <{}{}> in {} seconds . You can\'t edit the reminder now, so you are free to delete the message.' .format(pref, scope, round(msg_time - time.time())))) print('Registered a new reminder for {}'.format(message.guild.name))
async def check_reminders(): await client.wait_until_ready() while not client.is_closed(): for reminder in calendar: if len(reminder[2]) > 400: calendar.remove(reminder) if int(reminder[0]) <= time.time(): users = client.get_all_members() channels = client.get_all_channels() msg_points = chain(users, channels) recipient = discord.utils.get(msg_points, id=reminder[1]) try: await recipient.send(reminder[2]) print('Administered reminder to ' + recipient.name) except: print( 'Couldn\'t find required channel. Skipping a reminder') calendar.remove(reminder) for inv in intervals: if int(inv[0]) <= time.time(): channels = client.get_all_channels() recipient = discord.utils.get(channels, id=inv[2]) try: server_members = recipient.guild.members patrons = get_patrons('Donor') for m in server_members: if m in patrons: if inv[3].startswith('-del_on_send'): try: await recipient.purge( check=lambda m: m.content == inv[3][ 12:].strip() and time.time( ) - m.created_at.timestamp() < 1209600 and m.author == client.user) except Exception as e: print(e) await recipient.send(inv[3][12:]) else: await recipient.send(inv[3]) print('Administered interval to ' + recipient.name) break else: await recipient.send( 'There appears to be no patrons on your server, so the interval has been removed.' ) intervals.remove(inv) print(inv) inv[0] = int(inv[0]) + int( inv[1]) ## change the time for the next interval except: print( 'Couldn\'t find required channel. Skipping an interval' ) intervals.remove(inv) with open('DATA/calendar.json', 'w') as f: json.dump(calendar, f) ## uses a CSV writer to write the data to file. with open('DATA/intervals.json', 'w') as f: json.dump(intervals, f) ## uses a CSV writer to write the data to file. await asyncio.sleep(1.5)
async def tag(message, client): not_done = True if isinstance(message.channel, discord.DMChannel): return if message.guild.id not in tags.keys(): tags[message.guild.id] = {} splits = message.content.split(' ') if len(splits) == 1: if len(tags[message.guild.id]) == 0: await message.channel.send(embed=discord.Embed( title='No Tags!', description= '*Use `$tag add <name>: <message>`, `$tag remove` and `$tag help` to manage your tags*' )) else: await message.channel.send(embed=discord.Embed( title='Tags', description='\n'.join(tags[message.guild.id].keys()))) not_done = False elif len(splits) > 2: content = ' '.join(splits[2:]) if splits[1] in ['add', 'new']: if len(tags[message.guild.id] ) > 5 and message.author not in get_patrons('Patrons'): await message.channel.send( 'Sorry, but for normal users tags are capped at 6. Please remove some or consider donating with `$donate` ($5 tier).' ) return elif len(content) > 80 and message.author not in get_patrons( 'Patrons'): await message.channel.send( 'Tags are capped at 80 characters. Keep it concise!') return content = content.split(':') if len(content) == 1: await message.channel.send( 'Please add a colon to split the name of the tag from the body.' ) else: if content[0].startswith(('add', 'new', 'remove', 'del')): await message.channel.send( 'Please don\'t use keywords `add, new, remove, del` in the names of your tags.' ) return tags[message.guild.id][content[0]] = ' '.join( content[1:]).strip() await message.channel.send('Added tag {}'.format(content[0])) not_done = False elif splits[1] in ['remove', 'del']: name = ' '.join(splits[2:]) if name not in tags[message.guild.id].keys(): await message.channel.send( 'Couldn\'t find the tag by the name you specified.') return del tags[message.guild.id][name] await message.channel.send('Deleted tag {}'.format(name)) not_done = False if len(splits) > 1 and not_done: name = ' '.join(splits[1:]).strip() if name not in tags[message.guild.id].keys(): await message.channel.send( 'Use `$tag add <name>: <message>` to add new tags. Use `$tag remove <name>` to delete a tag. Use `$tag <name>` to view a tag. Use `$tag` to list all tags' ) return await message.channel.send(tags[message.guild.id][name]) with open('DATA/tags.json', 'w') as f: json.dump(tags, f)
async def check_reminders(): await client.wait_until_ready() times['start'] = time.time() while not client.is_closed(): times['last_loop'] = time.time() times['loops'] += 1 while len(reminders) and reminders[0].time <= time.time(): print('Looping for reminder(s)...') reminder = reminders.pop(0) if reminder.interval is not None and reminder.interval < 8: continue users = client.get_all_members() channels = client.get_all_channels() msg_points = chain(users, channels) recipient = discord.utils.get(msg_points, id=reminder.channel) if recipient == None: print('{}: Failed to locate channel'.format(datetime.datetime.utcnow().strftime('%H:%M:%S'))) continue try: if reminder.interval == None: await recipient.send(reminder.message) print('{}: Administered reminder to {}'.format(datetime.datetime.utcnow().strftime('%H:%M:%S'), recipient.name)) else: server_members = recipient.guild.members patrons = get_patrons('Donor') if any([m in patrons for m in server_members]): if reminder.message.startswith('-del_on_send'): try: await recipient.purge(check=lambda m: m.content == reminder.message[len('-del_on_send'):].strip() and time.time() - m.created_at.timestamp() < 1209600 and m.author == client.user) except Exception as e: print(e) await recipient.send(reminder.message[len('-del_on_send'):]) elif reminder.message.startswith('-del_after_'): chars = '' for char in reminder.message[len('-del_after_'):]: if char in '0123456789': chars += char else: break wait_time = int(chars) message = await recipient.send(reminder.message[len('-del_after_{}'.format(chars)):]) process_deletes[message.id] = {'time' : time.time() + wait_time, 'channel' : message.channel.id} elif reminder.message.startswith('getfrom['): id_started = False chars = '' for char in reminder.message[8:].strip(): if char in '0123456789': id_started = True chars += char elif id_started: break channel_id = int(chars) get_from = [s for s in recipient.guild.channels if s.id == channel_id] if not get_from: print('getfrom call failed') continue a = [] async for item in get_from[0].history(limit=50): a.append(item) quote = random.choice(a) await recipient.send(quote.content) else: await recipient.send(reminder.message) print('{}: Administered interval to {} (Reset for {} seconds)'.format(datetime.datetime.utcnow().strftime('%H:%M:%S'), recipient.name, reminder.interval)) else: await recipient.send('There appears to be no patrons on your server, so the interval has been removed.') continue while reminder.time <= time.time(): reminder.time += reminder.interval ## change the time for the next interval reminders.append(reminder) # Requeue the interval with modified time reminders.sort(key=lambda x: x.time) except Exception as e: print(e) cursor.execute('DELETE FROM reminders') cursor.execute('VACUUM') for d in map(lambda x: x.__dict__, reminders): command = '''INSERT INTO reminders (interval, time, channel, message) VALUES (?, ?, ?, ?)''' cursor.execute(command, (d['interval'], d['time'], d['channel'], d['message'])) connection.commit() try: for message, info in process_deletes.copy().items(): if info['time'] <= time.time(): del process_deletes[message] message = await client.get_channel(info['channel']).get_message(message) if message is None or message.pinned: pass else: print('{}: Attempting to auto-delete a message...'.format(datetime.datetime.utcnow().strftime('%H:%M:%S'))) try: await message.delete() except Exception as e: print(e) except Exception as e: print('Error in deletion loop: {}'.format(e)) with open('DATA/process_deletes.mp', 'wb') as f: msgpack.dump(process_deletes, f) await asyncio.sleep(2.5)