Example #1
0
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."
Example #2
0
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')
Example #3
0
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)
Example #4
0
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."
Example #5
0
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
Example #6
0
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)
Example #7
0
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))
Example #8
0
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')