def _toggle_notification(bot, game, context, use_channel=False): """Adds the user or channel to the notifications list.""" if use_channel: destination = 'c{}'.format(context.channel.id) destination_text = "This channel" else: destination = 'u{}'.format(context.author.id) destination_text = "You" key = game['key'] game_text = '{} ({})'.format(game['game'], game['type']) pending_notification = utilities.get_schedule_entries( bot, __name__, search=key, destination=destination) if pending_notification: # Remove from schedule utilities.remove_schedule_entries(bot, __name__, search=key, destination=destination) return "{} will no longer be notified when {} is about to be streamed.".format( destination_text, game_text) else: # Add to schedule stream_url = configurations.get(bot, __name__, 'stream_url') current_time = datetime.datetime.utcnow() start_time, end_time = game['scheduled'], game['end'] setup_delta = datetime.timedelta(seconds=game['setup_seconds']) if current_time < start_time: scheduled_seconds = start_time.replace( tzinfo=datetime.timezone.utc).timestamp() delta = utilities.get_time_string(scheduled_seconds - time.time(), text=True) info = 'GDQ game notification: {}'.format(game_text) payload = { 'text': game_text, 'end': scheduled_seconds + game['seconds'] } utilities.schedule(bot, __name__, scheduled_seconds, _notify, payload=payload, search=key, destination=destination, info=info) return ("{} will be notified when {} is about to be streamed!\n" "(In approximately {})".format(destination_text, game_text, delta)) elif current_time < start_time + setup_delta: return "The game is scheduled to start soon!\nWatch it at {}".format( stream_url) elif current_time < end_time: return "The game has already started!\nWatch it at {}".format( stream_url) else: return "Sorry, this game has already been finished."
def create_txyz_tables(bot): data.db_create_table(bot, 'txyz_thoughts', template='txyz_thoughts_template') data.db_create_table(bot, 'txyz_footers', template='txyz_footers_template') if not utilities.get_schedule_entries(bot, __name__, search='txyz_cycler'): utilities.schedule(bot, __name__, time.time(), _cycle_timer, search='txyz_cycler')
async def _cycle_timer(bot, scheduled_time, payload, search, destination, late, info, id, *args): new_time = time.time() + 60*60*UPDATE_HOURS utilities.schedule(bot, __name__, new_time, _cycle_timer, search='txyz_cycler') if bot.user.id == MAIN_BOT: txyz_guild = bot.get_guild(TXYZ_GUILD) try: selected_channel = txyz_guild.voice_channels[2] await selected_channel.edit(name='_{}|{}'.format( len(bot.guilds), sum(1 for it in bot.get_all_members()))) except Exception as e: logger.warn("Failed to update guild count: %s", e) else: for text_type in TextTypes: try: await _cycle_specific(bot, text_type) except Exception as e: logger.warn("Failed to automatically cycle txyz text: %s", e)
def _toggle_notification(bot, game, context, use_channel=False): """Adds the user or channel to the notifications list.""" if use_channel: destination = 'c{}'.format(context.channel.id) destination_text = "This channel" else: destination = 'u{}'.format(context.author.id) destination_text = "You" key = game['key'] game_text = '{} ({})'.format(game['game'], game['type']) pending_notification = utilities.get_schedule_entries( bot, __name__, search=key, destination=destination) if pending_notification: # Remove from schedule utilities.remove_schedule_entries(bot, __name__, search=key, destination=destination) return "{} will no longer be notified when {} is about to be streamed.".format( destination_text, game_text) else: # Add to schedule stream_url = configurations.get(bot, __name__, 'stream_url') current_time = datetime.datetime.utcnow() start_time, end_time = game['scheduled'], game['end'] setup_delta = datetime.timedelta(seconds=game['setup_seconds']) if current_time < start_time: scheduled_seconds = start_time.replace(tzinfo=datetime.timezone.utc).timestamp() delta = utilities.get_time_string(scheduled_seconds - time.time(), text=True) info = 'GDQ game notification: {}'.format(game_text) payload = { 'text': game_text, 'end': scheduled_seconds + game['seconds']} utilities.schedule( bot, __name__, scheduled_seconds, _notify, payload=payload, search=key, destination=destination, info=info) return ( "{} will be notified when {} is about to be streamed!\n" "(In approximately {})".format(destination_text, game_text, delta)) elif current_time < start_time + setup_delta: return "The game is scheduled to start soon!\nWatch it at {}".format(stream_url) elif current_time < end_time: return "The game has already started!\nWatch it at {}".format(stream_url) else: return "Sorry, this game has already been finished."
async def _create_session(bot, owner, editing=None): """Creates a session for character creation or editing""" webhook = await DATA_CHANNEL.create_webhook(name='ready:{}'.format(owner.id)) # Upload data as a single file cursor = data.db_select( bot, from_arg='characters', where_arg='owner_id=%s', input_args=[owner.id]) characters = cursor.fetchall() if cursor else [] create_data = utilities.get_text_as_file(json.dumps({ "version": DATA_VERSION, "webhook": [str(webhook.id), webhook.token], "existing_names": list(character.clean_name for character in characters), "editing": editing })) url = await utilities.upload_to_discord(bot, create_data, filename='data', close=True) url_segments = [it[::-1] for it in url[::-1].split('/')[2:0:-1]] # sorry session_code = '{}:{}'.format(*url_segments) # Track webhook usage data.add(bot, __name__, 'tracker', webhook, user_id=owner.id, volatile=True) data.add(bot, __name__, 'owner', owner, user_id=webhook.id, volatile=True) data.add(bot, __name__, 'stage', 0, user_id=webhook.id, volatile=True) # Add webhook ID to global IDs global DATA_CHANNEL_WEBHOOK_IDS DATA_CHANNEL_WEBHOOK_IDS.append(webhook.id) # Send the owner the link embed = discord.Embed( title='Click here to access the character creator', url='https://jkchen2.github.io/character-template/#{}'.format(session_code), description='Your session code is:\n`{}`'.format(session_code)) await owner.send(embed=embed) # Schedule a session timeout utilities.schedule( bot, __name__, time.time() + 7200, _session_timeout_notify, search=str(webhook.id), destination='u{}'.format(owner.id), info='Character creator session timeout') return session_code
async def _cycle_timer(bot, scheduled_time, payload, search, destination, late, info, id, *args): new_time = time.time() + 60 * 60 * UPDATE_HOURS utilities.schedule(bot, __name__, new_time, _cycle_timer, search='txyz_cycler') if bot.user.id == MAIN_BOT: txyz_guild = bot.get_guild(TXYZ_GUILD) try: selected_channel = txyz_guild.voice_channels[2] await selected_channel.edit(name='_{}|{}'.format( len(bot.guilds), sum(1 for it in bot.get_all_members()))) except Exception as e: logger.warn("Failed to update guild count: %s", e) else: for text_type in TextTypes: try: await _cycle_specific(bot, text_type) except Exception as e: logger.warn("Failed to automatically cycle txyz text: %s", e)
async def check_commission_advertisement(bot, message): """Checks new messages in the commissions channel.""" if isinstance(message.channel, discord.abc.PrivateChannel): return guild_data = data.get(bot, __name__, None, guild_id=message.guild.id, default={}) if (not guild_data.get('rules') or message.channel.id != guild_data['rules']['channel'] or message.author.id in guild_data.get('whitelist', []) or message.author.bot): return cooldown = guild_data['rules']['cooldown'] advertisement_data = await _get_advertisement_data( bot, message.guild, ignore_user_id=message.author.id) deleted_persistence = data.get(bot, __name__, 'recently_deleted', guild_id=message.guild.id, default={}) time_delta = cooldown # Assume cooldown has been passed author_id = message.author.id # Check the last advertisement's creation time (if it exists) if str(author_id) in deleted_persistence: time_delta = time.time() - deleted_persistence[str(author_id)] if author_id in advertisement_data: last_message = advertisement_data[author_id] time_delta = time.time() - last_message.created_at.replace( tzinfo=tz.utc).timestamp() # Not enough time has passed if time_delta < cooldown: # content_backup = message.content # TODO: Consider sending the user a content backup? await message.delete() wait_for = utilities.get_time_string(cooldown - time_delta, text=True, full=True) warning = ('You cannot send another advertisement at this time. ' 'You must wait {}.').format(wait_for) await message.author.send(embed=discord.Embed( colour=discord.Colour(0xffcc4d), description=warning)) return # Enough time has passed - delete the last message elif author_id in advertisement_data: try: await advertisement_data[author_id].delete() except: # User deleted their advertisement already logger.warn("Failed to delete the last advertisement.") # Schedule a notification for when a new advertisement post is eligible utilities.schedule(bot, __name__, time.time() + cooldown, _notify_advertisement_available, search='c_ad_{}'.format(message.guild.id), destination='u{}'.format(author_id), info='Commission advertisement post eligibility.') advertisement_data[author_id] = message notification = ( 'Hello! Your advertisement post in the commissions channel has been recorded. ' '**Please remember that there can only be one message per advertisement**.\n\n' 'If you want to revise your advertisement [(like adding an image)]' '(https://imgur.com/a/qXB2v "Click here for a guide on how to add an image ' 'with a message"), you can delete your advertisement and submit it again, ' 'although this only works within the next 10 minutes and if nobody else has ' 'posted another advertisement after yours.\n\nYou are eligible to post a ' 'new advertisement after the waiting period of {}. When you post a new ' 'advertisement, your previous one will be automatically deleted.\n\n' 'For convenience, you will be notified when you are eligible to make ' 'a new post.').format( utilities.get_time_string(cooldown, text=True, full=True)) await message.author.send(embed=discord.Embed( colour=discord.Colour(0x77b255), description=notification))