<commit_before>import discord
from discord.ext import commands

import checks
import config
import database
from web import Web
from data.links import award_link

import json
from os import path
import random
from datetime import datetime, timedelta

class Hunt(commands.Cog):

    phase_1_day = datetime.strptime('2021.05.03 23:00', '%Y.%m.%d %H:%M')
    phase_2_day = datetime.strptime('2021.05.10 14:00', '%Y.%m.%d %H:%M')
    phase_3_day = datetime.strptime('2021.05.17 19:00', '%Y.%m.%d %H:%M')
    phase_4_day = datetime.strptime('2021.05.19 08:00', '%Y.%m.%d %H:%M')
    phase_5_day = datetime.strptime('2021.05.22 08:00', '%Y.%m.%d %H:%M')

    def __init__(self, bot: commands.Bot):
        self.bot = bot
        self.post_init = False
        self.allowed = False
        self.base_chance = 500
        self.base_reward = 100
        self.hunt_cap_ratio = 0.5
        self.lifetime = 1
        self.channels = []
        self.spawn_chance = 0
        self.hunts = {}
        self.reaction = '🐇'
        self.phase_4_hunts = 0
        self.hunt_reactions = []
        self.capture_reactions = []
        self.phase_3_done = False

    def get_phase(self):
        today = datetime.utcnow()
        if today > self.phase_5_day:
            return 5
        if today > self.phase_4_day:
            return 4
        if today > self.phase_3_day:
            return 3
        if today > self.phase_2_day:
            return 2
        if today > self.phase_1_day:
            return 1
        return 0

    def phase_23_chance(self):
        total_time = self.phase_4_day - self.phase_2_day
        remaining_time = self.phase_4_day - datetime.utcnow()
        return int(10000 - (100 * remaining_time.total_seconds() / total_time.total_seconds()) * 100)

    def phase_4_chance(self):
        chance = 10000 - self.phase_4_hunts * 200
        if chance < self.base_chance:
            chance = self.base_chance
        return chance

    def initialize_hunt(self):
        if path.isfile(config.BASE_DIR + 'hunt_settings.json'):
            with open(config.BASE_DIR + 'hunt_settings.json') as json_file:
                data = json.load(json_file)
                try:
                    self.base_chance = data['base_chance']
                    self.allowed = data['allowed']
                    self.channels = data['channels']
                    self.phase_4_hunts = data['phase_4_hunts']
                    self.hunt_reactions = data["hunt_reactions"]
                    self.capture_reactions = data["capture_reactions"]
                    self.phase_3_done = data["phase_3_done"]
                    self.base_reward = data["base_reward"]
                    self.hunt_cap_ratio = data["hunt_cap_ratio"]
                    self.lifetime = data["lifetime"]
                except Exception as e:
                    pass
        self.spawn_chance = self.base_chance
        self.post_init = True

    def save_settings(self):
        settings = {
            "base_chance": self.base_chance,
            "allowed": self.allowed,
            "channels": self.channels,
            "phase_4_hunts": self.phase_4_hunts,
            "hunt_reactions": self.hunt_reactions,
            "capture_reactions": self.capture_reactions,
            "phase_3_done": self.phase_3_done,
            "base_reward": self.base_reward,
            "hunt_cap_ratio": self.hunt_cap_ratio,
            "lifetime": self.lifetime
        }
        with open(config.BASE_DIR + 'hunt_settings.json', 'w') as outfile:
            json.dump(settings, outfile)

    def clean_hunts(self):
        for hunt in tuple(self.hunts):
            if datetime.utcnow() > self.hunts[hunt].end_time:
                self.hunts.pop(hunt)

    async def phase_3_purge(self):
        insert = "UPDATE users SET ducks = 0 WHERE ducks > 0"
        db = await database.Database.get_connection(self.bot.loop)
        async with db.transaction():
            await db.execute(insert)
        await database.Database.close_connection(db)

    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        phase = self.get_phase()
        if not self.post_init:
            return
        if phase < 4:
            return
        if self.allowed is not True:
            return

        # check if the message have a rabbit on it
        self.clean_hunts()
        if reaction.message.id not in self.hunts:
            return
        hunt_data = self.hunts.get(reaction.message.id)

        # check if the player already reacted for this rabbit
        if user.id in hunt_data.players:
            return

        hunting = str(reaction) in self.hunt_reactions
        capturing = phase > 4 and str(reaction) in self.capture_reactions
        # check if the reaction is correct
        if hunting or capturing:
            hunt_data.players.append(user.id)

            hunted = 0
            captured = 0
            today = datetime.utcnow()

            reward = 0

            if hunting:
                self.spawn_chance -= 20
                hunted = 1
                reward = self.base_reward * self.hunt_cap_ratio
                hunt_data.hunted += 1
            if capturing:
                self.spawn_chance += 40
                captured = 1
                reward = self.base_reward * (1 - self.hunt_cap_ratio)
                hunt_data.captured += 1

            if hunt_data.hunted + hunt_data.captured > 1:
                reward = reward/10

            values = {
                'giver': self.bot.user.id,
                # 'giver': 294171600478142466,
                'receiver': user.id,
                # 'receiver': 294171600478142466,
                'amount': round(reward),
                'key': config.TRANSACTION_KEY,
                'type': "diamonds"
            }
            response = await Web.get_response(award_link, values)

            if self.spawn_chance < 100:
                self.spawn_chance = self.base_chance

            insert_hunt = "INSERT INTO hunt (user_id, month, year, hunted, captured) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (user_id, month, year) DO UPDATE SET hunted = hunt.hunted + $4, captured = hunt.captured + $5"
            hunt_insert_data = (
                str(user.id),
                today.month,
                today.year,
                hunted,
                captured
            )

            insert_user = "INSERT INTO users (user_id, message_count, reaction_count, special, ducks) VALUES ($1, 0, 0, 0, 1) ON CONFLICT (user_id) DO UPDATE SET ducks = users.ducks + 1"
            db = await database.Database.get_connection(self.bot.loop)

            async with db.transaction():
                await db.execute(insert_user, str(user.id))
                await db.execute(insert_hunt, *hunt_insert_data)
            await database.Database.close_connection(db)

    @commands.Cog.listener()
    async def on_message(self, message: discord.Message):
        phase = self.get_phase()

        if phase > 2 and not self.phase_3_done:
            await self.phase_3_purge()
            self.phase_3_done = True
            self.save_settings()
        if not self.post_init:
            return
        if self.allowed is not True:
            return
        if message.channel.id not in self.channels:
            return
        number = random.randint(1, 10000)

        if phase < 4:
            self.spawn_chance = self.phase_23_chance()
        if phase == 4:
            self.spawn_chance = self.phase_4_chance()

        if number <= self.spawn_chance:
            hunt_data = HuntData(self.bot.user.id, self.lifetime)
            self.hunts[message.id] = hunt_data
            try:
                await message.add_reaction(self.reaction)
                self.spawn_chance = self.base_chance
            except discord.errors.NotFound as ex:
                self.spawn_chance = 10000
                print("spawning on a removed message, guaranteeing next spawn")

    @commands.group(name='hunt', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _hunt(self, ctx):
        """
        *Admin only* | Set of commands to control the hunt minigame. `?help hunt` for more info.

        Here is a list of all possible subcommands:
        """
        # group of commands for hunt manipulation
        # if used by itself, it'll show an embed with current state of the hunt
        await ctx.message.delete()
        if ctx.invoked_subcommand is None:
            phase = self.get_phase()
            if phase < 4:
                embed = discord.Embed(colour=discord.Colour(0xF8F8FF), title='Phase {}'.format(phase), description="Loading: {}%".format(self.phase_23_chance()/100))
            else:
                embed = discord.Embed(colour=discord.Colour(0xF8F8FF), title='Hunt settings', description="Here you can see an overview of the hunt settings and the current state")

                state = "Stoped"
                if self.allowed:
                    state = "Active"
                embed.add_field(name="State", value=state)
                embed.add_field(name="Base spawn chance", value="{}%".format(self.base_chance / 100))
                chance = self.spawn_chance
                if phase == 4:
                    chance = self.phase_4_chance()
                embed.add_field(name="Spawn chance", value="{}%".format(chance / 100))

                embed.add_field(name="Base reward", value="{} <:diamond:230281835119247361>".format(self.base_reward))
                embed.add_field(name="Hunt modifier", value="{}%".format(self.hunt_cap_ratio * 100))
                embed.add_field(name="Capture modifier", value="{}%".format((1 - self.hunt_cap_ratio) * 100))

                embed.add_field(name="Hunt timeout", value="{} minutes".format(self.lifetime))
                channels = []
                for channel_id in self.channels:
                    channel = self.bot.get_channel(channel_id)
                    channels.append(channel.name)
                embed.add_field(name="Channels", value=", ".join(channels))
                embed.add_field(name="Hunt emoji", value=" ".join(self.hunt_reactions))
                embed.add_field(name="Capture emoji", value=" ".join(self.capture_reactions))

                embed.set_footer(text="Please refer to `?help hunt` in order to change the settings")
            await ctx.send(embed=embed)

    @_hunt.command(name='start', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _start(self, ctx):
        """
        *Admin only* | Starts the hunting minigame
        """
        self.allowed = True
        self.save_settings()

    @_hunt.command(name='stop', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _stop(self, ctx):
        """
        *Admin only* | Stops the hunting minigame
        """
        self.allowed = False
        self.save_settings()

    @_hunt.command(name='spawn', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _spawn(self, ctx):
        """
        *Admin only* | Marks next eligible message for guaranteed spawn
        """
        self.spawn_chance = 10000

    @_hunt.command(name='allow', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _allow(self, ctx):
        """
        *Admin only* | Allows the hunt minigame work in the channel where this command was used
        """
        self.channels.append(ctx.channel.id)
        self.save_settings()

    @_hunt.command(name='deny', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _deny(self, ctx):
        """
        *Admin only* | Denies the hunt minigame to work in the channel where this command was used
        """
        self.channels.remove(ctx.channel.id)
        self.save_settings()

    @_hunt.command(name="add_hunt", case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _add_hunt_reaction(self, ctx, emoji):
        """
        *Admin only* | Adds the emoji into a list of possible reactions to hunt
        """
        self.hunt_reactions.append(emoji)
        self.save_settings()

    @_hunt.command(name="remove_hunt", aliases=['rm_hunt'], case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _remove_hunt_reaction(self, ctx, emoji):
        """
        *Admin only* | Removes the emoji from a list of possible reactions to hunt
        """
        self.hunt_reactions.pop(emoji)
        self.save_settings()

    @_hunt.command(name="add_capture", aliases=['add_cap'], case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _add_capture_reaction(self, ctx, emoji):
        """
        *Admin only* | Adds the emoji into a list of possible reactions to capture
        """
        self.capture_reactions.append(emoji)
        self.save_settings()

    @_hunt.command(name="remove_capture", aliases=['rm_cap'], case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _remove_capture_reaction(self, ctx, emoji):
        """
        *Admin only* | Removes the emoji from a list of possible reactions to capture
        """
        self.capture_reactions.pop(emoji)
        self.save_settings()

    @_hunt.command(name="set_reward", case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _set_diamond_reward(self, ctx, amount):
        """
        *Admin only* | Sets the base diamond reward for each hunt. This is further affected by the hunt/cap ratio and every participant after the first one gets only 1/10 of reward.
        """
        self.base_reward = amount
        self.save_settings()

    @_hunt.command(name="set_timeout", case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _set_lifetime(self, ctx, time):
        """
        *Admin only* | Sets how long is a hunt actively waiting for reactions. Time is in minutes.
        """
        self.lifetime = int(time)
        self.save_settings()

def setup(bot: commands.Bot):
    bot.add_cog(Hunt(bot))

class HuntData:
    def __init__(self, bot_id: int, timeout: int):
        self.hunted = 0
        self.captured = 0
        self.players = [bot_id]
        self.end_time = datetime.utcnow() + timedelta(minutes=timeout)
<commit_msg>hunt fix<commit_after>import discord
from discord.ext import commands

import checks
import config
import database
from web import Web
from data.links import award_link

import json
from os import path
import random
from datetime import datetime, timedelta

class Hunt(commands.Cog):

    phase_1_day = datetime.strptime('2021.05.03 23:00', '%Y.%m.%d %H:%M')
    phase_2_day = datetime.strptime('2021.05.10 14:00', '%Y.%m.%d %H:%M')
    phase_3_day = datetime.strptime('2021.05.17 19:00', '%Y.%m.%d %H:%M')
    phase_4_day = datetime.strptime('2021.05.19 08:00', '%Y.%m.%d %H:%M')
    phase_5_day = datetime.strptime('2021.05.22 08:00', '%Y.%m.%d %H:%M')

    def __init__(self, bot: commands.Bot):
        self.bot = bot
        self.post_init = False
        self.allowed = False
        self.base_chance = 500
        self.base_reward = 100
        self.hunt_cap_ratio = 0.5
        self.lifetime = 1
        self.channels = []
        self.spawn_chance = 0
        self.hunts = {}
        self.reaction = '🐇'
        self.phase_4_hunts = 0
        self.hunt_reactions = []
        self.capture_reactions = []
        self.phase_3_done = False

    def get_phase(self):
        today = datetime.utcnow()
        if today > self.phase_5_day:
            return 5
        if today > self.phase_4_day:
            return 4
        if today > self.phase_3_day:
            return 3
        if today > self.phase_2_day:
            return 2
        if today > self.phase_1_day:
            return 1
        return 0

    def phase_23_chance(self):
        total_time = self.phase_4_day - self.phase_2_day
        remaining_time = self.phase_4_day - datetime.utcnow()
        return int(10000 - (100 * remaining_time.total_seconds() / total_time.total_seconds()) * 100)

    def phase_4_chance(self):
        chance = 10000 - self.phase_4_hunts * 200
        if chance < self.base_chance:
            chance = self.base_chance
        return chance

    def initialize_hunt(self):
        if path.isfile(config.BASE_DIR + 'hunt_settings.json'):
            with open(config.BASE_DIR + 'hunt_settings.json') as json_file:
                data = json.load(json_file)
                try:
                    self.base_chance = data['base_chance']
                    self.allowed = data['allowed']
                    self.channels = data['channels']
                    self.phase_4_hunts = data['phase_4_hunts']
                    self.hunt_reactions = data["hunt_reactions"]
                    self.capture_reactions = data["capture_reactions"]
                    self.phase_3_done = data["phase_3_done"]
                    self.base_reward = data["base_reward"]
                    self.hunt_cap_ratio = data["hunt_cap_ratio"]
                    self.lifetime = data["lifetime"]
                except Exception as e:
                    pass
        self.spawn_chance = self.base_chance
        self.post_init = True

    def save_settings(self):
        settings = {
            "base_chance": self.base_chance,
            "allowed": self.allowed,
            "channels": self.channels,
            "phase_4_hunts": self.phase_4_hunts,
            "hunt_reactions": self.hunt_reactions,
            "capture_reactions": self.capture_reactions,
            "phase_3_done": self.phase_3_done,
            "base_reward": self.base_reward,
            "hunt_cap_ratio": self.hunt_cap_ratio,
            "lifetime": self.lifetime
        }
        with open(config.BASE_DIR + 'hunt_settings.json', 'w') as outfile:
            json.dump(settings, outfile)

    def clean_hunts(self):
        for hunt in tuple(self.hunts):
            if datetime.utcnow() > self.hunts[hunt].end_time:
                self.hunts.pop(hunt)

    async def phase_3_purge(self):
        insert = "UPDATE users SET ducks = 0 WHERE ducks > 0"
        db = await database.Database.get_connection(self.bot.loop)
        async with db.transaction():
            await db.execute(insert)
        await database.Database.close_connection(db)

    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        phase = self.get_phase()
        if not self.post_init:
            return
        if phase < 4:
            return
        if self.allowed is not True:
            return

        # check if the message have a rabbit on it
        self.clean_hunts()
        if reaction.message.id not in self.hunts:
            return
        hunt_data = self.hunts.get(reaction.message.id)

        # check if the player already reacted for this rabbit
        if user.id in hunt_data.players:
            return

        hunting = str(reaction) in self.hunt_reactions
        capturing = phase > 4 and str(reaction) in self.capture_reactions
        # check if the reaction is correct
        if hunting or capturing:
            hunt_data.players.append(user.id)

            hunted = 0
            captured = 0
            today = datetime.utcnow()

            reward = 0

            if hunting:
                self.spawn_chance -= 20
                hunted = 1
                reward = self.base_reward * self.hunt_cap_ratio
                hunt_data.hunted += 1
            if capturing:
                self.spawn_chance += 40
                captured = 1
                reward = self.base_reward * (1 - self.hunt_cap_ratio)
                hunt_data.captured += 1

            if hunt_data.hunted + hunt_data.captured > 1:
                reward = reward/10

            values = {
                'giver': self.bot.user.id,
                # 'giver': 294171600478142466,
                'receiver': user.id,
                # 'receiver': 294171600478142466,
                'amount': round(reward),
                'key': config.TRANSACTION_KEY,
                'type': "diamonds"
            }
            response = await Web.get_response(award_link, values)

            if self.spawn_chance < 100:
                self.spawn_chance = self.base_chance

            insert_hunt = "INSERT INTO hunt (user_id, month, year, hunted, captured) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (user_id, month, year) DO UPDATE SET hunted = hunt.hunted + $4, captured = hunt.captured + $5"
            hunt_insert_data = (
                str(user.id),
                today.month,
                today.year,
                hunted,
                captured
            )

            if phase == 4:
                self.phase_4_hunts += 1
                self.save_settings()

            insert_user = "INSERT INTO users (user_id, message_count, reaction_count, special, ducks) VALUES ($1, 0, 0, 0, 1) ON CONFLICT (user_id) DO UPDATE SET ducks = users.ducks + 1"
            db = await database.Database.get_connection(self.bot.loop)

            async with db.transaction():
                await db.execute(insert_user, str(user.id))
                await db.execute(insert_hunt, *hunt_insert_data)
            await database.Database.close_connection(db)

    @commands.Cog.listener()
    async def on_message(self, message: discord.Message):
        phase = self.get_phase()

        if phase > 2 and not self.phase_3_done:
            await self.phase_3_purge()
            self.phase_3_done = True
            self.save_settings()
        if not self.post_init:
            return
        if self.allowed is not True:
            return
        if message.channel.id not in self.channels:
            return
        number = random.randint(1, 10000)

        if phase < 4:
            self.spawn_chance = self.phase_23_chance()
        if phase == 4:
            self.spawn_chance = self.phase_4_chance()

        if number <= self.spawn_chance:
            hunt_data = HuntData(self.bot.user.id, self.lifetime)
            self.hunts[message.id] = hunt_data
            try:
                await message.add_reaction(self.reaction)
                self.spawn_chance = self.base_chance
            except discord.errors.NotFound as ex:
                self.spawn_chance = 10000
                print("spawning on a removed message, guaranteeing next spawn")

    @commands.group(name='hunt', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _hunt(self, ctx):
        """
        *Admin only* | Set of commands to control the hunt minigame. `?help hunt` for more info.

        Here is a list of all possible subcommands:
        """
        # group of commands for hunt manipulation
        # if used by itself, it'll show an embed with current state of the hunt
        await ctx.message.delete()
        if ctx.invoked_subcommand is None:
            phase = self.get_phase()
            if phase < 4:
                embed = discord.Embed(colour=discord.Colour(0xF8F8FF), title='Phase {}'.format(phase), description="Loading: {}%".format(self.phase_23_chance()/100))
            else:
                embed = discord.Embed(colour=discord.Colour(0xF8F8FF), title='Hunt settings', description="Here you can see an overview of the hunt settings and the current state")

                state = "Stoped"
                if self.allowed:
                    state = "Active"
                embed.add_field(name="State", value=state)
                embed.add_field(name="Base spawn chance", value="{}%".format(self.base_chance / 100))
                chance = self.spawn_chance
                if phase == 4:
                    chance = self.phase_4_chance()
                embed.add_field(name="Spawn chance", value="{}%".format(chance / 100))

                embed.add_field(name="Base reward", value="{} <:diamond:230281835119247361>".format(self.base_reward))
                embed.add_field(name="Hunt modifier", value="{}%".format(self.hunt_cap_ratio * 100))
                embed.add_field(name="Capture modifier", value="{}%".format((1 - self.hunt_cap_ratio) * 100))

                embed.add_field(name="Hunt timeout", value="{} minutes".format(self.lifetime))
                channels = []
                for channel_id in self.channels:
                    channel = self.bot.get_channel(channel_id)
                    channels.append(channel.name)
                embed.add_field(name="Channels", value=", ".join(channels))
                embed.add_field(name="Hunt emoji", value=" ".join(self.hunt_reactions))
                embed.add_field(name="Capture emoji", value=" ".join(self.capture_reactions))

                embed.set_footer(text="Please refer to `?help hunt` in order to change the settings")
            await ctx.send(embed=embed)

    @_hunt.command(name='start', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _start(self, ctx):
        """
        *Admin only* | Starts the hunting minigame
        """
        self.allowed = True
        self.save_settings()

    @_hunt.command(name='stop', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _stop(self, ctx):
        """
        *Admin only* | Stops the hunting minigame
        """
        self.allowed = False
        self.save_settings()

    @_hunt.command(name='spawn', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _spawn(self, ctx):
        """
        *Admin only* | Marks next eligible message for guaranteed spawn
        """
        self.spawn_chance = 10000

    @_hunt.command(name='allow', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _allow(self, ctx):
        """
        *Admin only* | Allows the hunt minigame work in the channel where this command was used
        """
        self.channels.append(ctx.channel.id)
        self.save_settings()

    @_hunt.command(name='deny', case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _deny(self, ctx):
        """
        *Admin only* | Denies the hunt minigame to work in the channel where this command was used
        """
        self.channels.remove(ctx.channel.id)
        self.save_settings()

    @_hunt.command(name="add_hunt", case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _add_hunt_reaction(self, ctx, emoji):
        """
        *Admin only* | Adds the emoji into a list of possible reactions to hunt
        """
        self.hunt_reactions.append(emoji)
        self.save_settings()

    @_hunt.command(name="remove_hunt", aliases=['rm_hunt'], case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _remove_hunt_reaction(self, ctx, emoji):
        """
        *Admin only* | Removes the emoji from a list of possible reactions to hunt
        """
        self.hunt_reactions.pop(emoji)
        self.save_settings()

    @_hunt.command(name="add_capture", aliases=['add_cap'], case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _add_capture_reaction(self, ctx, emoji):
        """
        *Admin only* | Adds the emoji into a list of possible reactions to capture
        """
        self.capture_reactions.append(emoji)
        self.save_settings()

    @_hunt.command(name="remove_capture", aliases=['rm_cap'], case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _remove_capture_reaction(self, ctx, emoji):
        """
        *Admin only* | Removes the emoji from a list of possible reactions to capture
        """
        self.capture_reactions.pop(emoji)
        self.save_settings()

    @_hunt.command(name="set_reward", case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _set_diamond_reward(self, ctx, amount):
        """
        *Admin only* | Sets the base diamond reward for each hunt. This is further affected by the hunt/cap ratio and every participant after the first one gets only 1/10 of reward.
        """
        self.base_reward = amount
        self.save_settings()

    @_hunt.command(name="set_timeout", case_insensitive=True)
    @commands.check(checks.can_manage_bot)
    async def _set_lifetime(self, ctx, time):
        """
        *Admin only* | Sets how long is a hunt actively waiting for reactions. Time is in minutes.
        """
        self.lifetime = int(time)
        self.save_settings()

def setup(bot: commands.Bot):
    bot.add_cog(Hunt(bot))

class HuntData:
    def __init__(self, bot_id: int, timeout: int):
        self.hunted = 0
        self.captured = 0
        self.players = [bot_id]
        self.end_time = datetime.utcnow() + timedelta(minutes=timeout)
<|endoftext|>


<commit_before>from .grammar import expression, flags, operator
from .operators import (
    Add,
    Advantage,
    Disadvantage,
    Divide,
    Drop,
    Keep,
    Multiply,
    Subtract,
)
from .tokens import Dice, Integer
from pyparsing import infixNotation, opAssoc
import re

class Roll:
    """An object that represents the roll and its results."""

    @property
    def result(self):
        return self._result

    def __init__(self, expression: str):
        self.expression = expression

    def evaluate(self, tokens):
        """Evaluate the stack of tokens.

        This is a first pass at the evaluation function. We could improve it with
        generators and other techniques, but it is most important to have
        something that actually works as expected first.
        """
        # TODO: The result here should not be a scalar, but rather a result.
        result = None
        prev_token = None

        #: Iterate over the tokens passed for evaluation. This will continue until
        #: we have no more tokens to evaluate or we return out of the function.
        #:
        #: Our tokens can be grouped together, resulting in subexpressions that
        #: need to be evaluated. [SWQ]
        while tokens:

            #: Get the current token from the end of the list. We end up
            #: unraveling the tokens list right to left.
            cur_token = tokens.pop()
            cur_token_type = type(cur_token)

            #: If our current token is an array, we should recursively evaluate
            #: it. This means that we'll result inner arrays as we encounter them.
            if cur_token_type is type([]):
                return self.evaluate(cur_token)
            elif cur_token_type is Integer:
                result = int(cur_token.evaluate())
                print(f"> {result}")
            elif cur_token_type is Dice:
                result = cur_token.evaluate()
                print(f"> {result} ({result.total})")
                result = result.total
            elif cur_token in [
                "!advantage",
                "!adv",
                "!disadvantage",
                "!dis",
                "!keep",
                "!take",
                "!drop",
                "!shrink",
                "!grow",
            ]:
                next_token = tokens.pop()
                result = self.handle_flags(cur_token, next_token)
                print(f"> {result}")
            elif cur_token in ["+", "-", "*", "/"]:
                next_token = tokens.pop()
                result = self.handle_operator(cur_token, next_token, prev_token)
                print(f"> {result}")
            prev_token = cur_token
        return result

    def handle_flags(self, flag, expr):
        if flag in ("!advantage", "!adv"):
            t = Advantage(expr)
        elif flag in ("!disadvantage", "!dis"):
            t = Disadvantage(expr)
        elif flag in ("!drop"):
            t = Drop(expr)
        elif flag in ("!keep"):
            t = Keep(expr)
        return t.evaluate()

    def handle_operand(self, operand):
        """Evaluates an operand on either the left or right of an operator."""
        operand_type = type(operand)
        if operand_type == type([]):
            result = self.evaluate(operand)
        elif operand_type is Integer:
            result = int(operand.evaluate())
        elif operand_type is Dice:
            result = (operand.evaluate()).total
        return result

    def handle_operator(self, op, left, right):
        left = self.handle_operand(left)
        print(f"> .. {left}")

        print(f"> .. {str(op)}")

        right = self.handle_operand(right)
        print(f"> .. {right}")

        if str(op) == "+":
            t = Add(left, right)
        if str(op) == "-":
            t = Subtract(left, right)
        if str(op) == "*":
            t = Multiply(left, right)
        if str(op) == "/":
            t = Divide(left, right)
        return int(t.evaluate())

    def roll(self):
        parsed = parse_expression_using_infix_notation(self.expression)
        self._result = self.evaluate(parsed.asList())
        return self

def parse_expression_using_infix_notation(expr):
    infix_expression = infixNotation(expression(), [
        (flags(), 1, opAssoc.LEFT,),
        (operator(), 2, opAssoc.LEFT,),
    ])
    return infix_expression.parseString(expr)

def roll(text: str) -> list:
    """Roll dice represented by the text expression."""
    results = []
    expressions = re.split(r"[,;]", text)
    for expr in expressions:
        roll_obj = Roll(expr)
        result = (roll_obj.roll()).result
        results.append(result)
    return results
<commit_msg>Re-arrange imports<commit_after>import re
from pyparsing import infixNotation, opAssoc
from .grammar import expression, flags, operator
from .operators import (
    Add,
    Advantage,
    Disadvantage,
    Divide,
    Drop,
    Keep,
    Multiply,
    Subtract,
)
from .tokens import Dice, Integer

class Roll:
    """An object that represents the roll and its results."""

    @property
    def result(self):
        return self._result

    def __init__(self, expression: str):
        self.expression = expression

    def evaluate(self, tokens):
        """Evaluate the stack of tokens.

        This is a first pass at the evaluation function. We could improve it with
        generators and other techniques, but it is most important to have
        something that actually works as expected first.
        """
        # TODO: The result here should not be a scalar, but rather a result.
        result = None
        prev_token = None

        #: Iterate over the tokens passed for evaluation. This will continue until
        #: we have no more tokens to evaluate or we return out of the function.
        #:
        #: Our tokens can be grouped together, resulting in subexpressions that
        #: need to be evaluated. [SWQ]
        while tokens:

            #: Get the current token from the end of the list. We end up
            #: unraveling the tokens list right to left.
            cur_token = tokens.pop()
            cur_token_type = type(cur_token)

            #: If our current token is an array, we should recursively evaluate
            #: it. This means that we'll result inner arrays as we encounter them.
            if cur_token_type is type([]):
                return self.evaluate(cur_token)
            elif cur_token_type is Integer:
                result = int(cur_token.evaluate())
                print(f"> {result}")
            elif cur_token_type is Dice:
                result = cur_token.evaluate()
                print(f"> {result} ({result.total})")
                result = result.total
            elif cur_token in [
                "!advantage",
                "!adv",
                "!disadvantage",
                "!dis",
                "!keep",
                "!take",
                "!drop",
                "!shrink",
                "!grow",
            ]:
                next_token = tokens.pop()
                result = self.handle_flags(cur_token, next_token)
                print(f"> {result}")
            elif cur_token in ["+", "-", "*", "/"]:
                next_token = tokens.pop()
                result = self.handle_operator(cur_token, next_token, prev_token)
                print(f"> {result}")
            prev_token = cur_token
        return result

    def handle_flags(self, flag, expr):
        if flag in ("!advantage", "!adv"):
            t = Advantage(expr)
        elif flag in ("!disadvantage", "!dis"):
            t = Disadvantage(expr)
        elif flag in ("!drop"):
            t = Drop(expr)
        elif flag in ("!keep"):
            t = Keep(expr)
        return t.evaluate()

    def handle_operand(self, operand):
        """Evaluates an operand on either the left or right of an operator."""
        operand_type = type(operand)
        if operand_type == type([]):
            result = self.evaluate(operand)
        elif operand_type is Integer:
            result = int(operand.evaluate())
        elif operand_type is Dice:
            result = (operand.evaluate()).total
        return result

    def handle_operator(self, op, left, right):
        left = self.handle_operand(left)
        print(f"> .. {left}")

        print(f"> .. {str(op)}")

        right = self.handle_operand(right)
        print(f"> .. {right}")

        if str(op) == "+":
            t = Add(left, right)
        if str(op) == "-":
            t = Subtract(left, right)
        if str(op) == "*":
            t = Multiply(left, right)
        if str(op) == "/":
            t = Divide(left, right)
        return int(t.evaluate())

    def roll(self):
        parsed = parse_expression_using_infix_notation(self.expression)
        self._result = self.evaluate(parsed.asList())
        return self

def parse_expression_using_infix_notation(expr):
    infix_expression = infixNotation(expression(), [
        (flags(), 1, opAssoc.LEFT,),
        (operator(), 2, opAssoc.LEFT,),
    ])
    return infix_expression.parseString(expr)

def roll(text: str) -> list:
    """Roll dice represented by the text expression."""
    results = []
    expressions = re.split(r"[,;]", text)
    for expr in expressions:
        roll_obj = Roll(expr)
        result = (roll_obj.roll()).result
        results.append(result)
    return results
<|endoftext|>


<commit_before>from django.db.backends.postgresql.creation import DatabaseCreation

class RDKitCreation(DatabaseCreation):

    def sql_create_model(self, model, style, known_models=set()):

        final_output, pending_references = \
            super(RDKitCreation, self).sql_create_model(model, style, known_models)
        from django_chem.db.models.fields import MoleculeField

        opts = model._meta
        molecule_fields = [f for f in opts.local_fields
                           if isinstance(f, MoleculeField)]
        qn = self.connection.ops.quote_name
        for f in molecule_fields:
            pass

        return final_output, pending_references

    def sql_indexes_for_field(self, model, f, style):
        "Return specific index creation SQL for the field."

        from django_chem.db.models.fields import ChemField

        output = super(RDKitCreation, self).sql_indexes_for_field(model,
                                                                  f, style)

        if isinstance(f, ChemField) and f.chem_index:
            qn = self.connection.ops.quote_name
            db_table = model._meta.db_table

            output.append(style.SQL_KEYWORD('CREATE INDEX ') +
                          style.SQL_TABLE(qn('%s_%s_gist_idx' %
                                             (db_table, f.column))) +
                          style.SQL_KEYWORD(' ON ') +
                          style.SQL_TABLE(qn(db_table)) +
                          style.SQL_KEYWORD(' USING ') +
                          style.SQL_COLTYPE('GIST') + ' ( ' +
                          style.SQL_FIELD(qn(f.column)) + ' );')

        return output
<commit_msg>removed "empty" override of sql_create_model<commit_after>from django.db.backends.postgresql.creation import DatabaseCreation

class RDKitCreation(DatabaseCreation):

    def sql_indexes_for_field(self, model, f, style):
        "Return specific index creation SQL for the field."

        from django_chem.db.models.fields import ChemField

        output = super(RDKitCreation, self).sql_indexes_for_field(model,
                                                                  f, style)

        if isinstance(f, ChemField) and f.chem_index:
            qn = self.connection.ops.quote_name
            db_table = model._meta.db_table

            output.append(style.SQL_KEYWORD('CREATE INDEX ') +
                          style.SQL_TABLE(qn('%s_%s_gist_idx' %
                                             (db_table, f.column))) +
                          style.SQL_KEYWORD(' ON ') +
                          style.SQL_TABLE(qn(db_table)) +
                          style.SQL_KEYWORD(' USING ') +
                          style.SQL_COLTYPE('GIST') + ' ( ' +
                          style.SQL_FIELD(qn(f.column)) + ' );')

        return output
<|endoftext|>


<commit_before>import discord
from discord.ext import commands

class Info:
	def __init__(self, bot):
		self.bot = bot

	@commands.command(hidden=True, aliases=['info'])
	async def whois(self, ctx, member: discord.Member = None):
		if member == None:
			memberholder = ctx.message.author.id
			member = ctx.guild.get_member(memberholder)
			emb = discord.Embed(colour=0xC500FF)
			emb.set_author(name="Whois for {}".format(member.display_name),
							icon_url=member.avatar_url)
			emb.set_thumbnail(url=member.avatar_url)
			emb.add_field(name="**ID**", value=member.id)
			emb.add_field(name="**Roles**", value=", ".join([r.name for r in member.roles]))
			emb.add_field(name="**Status**", value="**Playing** {}".format(member.game.name if member.game else ""))
			emb.add_field(name="**Color**", value=str(member.color))
			emb.add_field(name="**Joined on**", value=member.joined_at.date())
			emb.add_field(name="**Avatar url**", value="[Here]({})".format(member.avatar_url))
			try:
				await ctx.send(embed=emb)
			except:
				await ctx.send("Too much info...")
		else:
			emb = discord.Embed(colour=0xC500FF)
			emb.set_author(name="Whois for {}".format(member.display_name),
							icon_url=member.avatar_url)
			emb.set_thumbnail(url=member.avatar_url)
			emb.add_field(name="**ID**", value=member.id)
			emb.add_field(name="**Roles**", value=", ".join([r.name for r in member.roles]))
			emb.add_field(name="**Status**", value="**Playing** {}".format(member.game.name if member.game else ""))
			emb.add_field(name="**Color**", value=str(member.color))
			emb.add_field(name="**Joined on**", value=member.joined_at.date())
			emb.add_field(name="**Avatar url**", value="[Here]({})".format(member.avatar_url))
			try:
				await ctx.send(embed=emb)
			except:
				await ctx.send("Too much info...")

def setup(bot):
	bot.add_cog(Info(bot))<commit_msg>Colour edit<commit_after>import discord
from discord.ext import commands

class Info:
	def __init__(self, bot):
		self.bot = bot

	@commands.command(hidden=True, aliases=['info'])
	async def whois(self, ctx, member: discord.Member = None):
		if member == None:
			memberholder = ctx.message.author.id
			member = ctx.guild.get_member(memberholder)
			emb = discord.Embed(colour=self.bot.embed_colour)
			emb.set_author(name="Whois for {}".format(member.display_name),
							icon_url=member.avatar_url)
			emb.set_thumbnail(url=member.avatar_url)
			emb.add_field(name="**ID**", value=member.id)
			emb.add_field(name="**Roles**", value=", ".join([r.name for r in member.roles]))
			emb.add_field(name="**Status**", value="**Playing** {}".format(member.game.name if member.game else ""))
			emb.add_field(name="**Color**", value=str(member.color))
			emb.add_field(name="**Joined on**", value=member.joined_at.date())
			emb.add_field(name="**Avatar url**", value="[Here]({})".format(member.avatar_url))
			try:
				await ctx.send(embed=emb)
			except:
				await ctx.send("Too much info...")
		else:S
			emb = discord.Embed(colour=self.bot.embed_colour)
			emb.set_author(name="Whois for {}".format(member.display_name),
							icon_url=member.avatar_url)
			emb.set_thumbnail(url=member.avatar_url)
			emb.add_field(name="**ID**", value=member.id)
			emb.add_field(name="**Roles**", value=", ".join([r.name for r in member.roles]))
			emb.add_field(name="**Status**", value="**Playing** {}".format(member.game.name if member.game else ""))
			emb.add_field(name="**Color**", value=str(member.color))
			emb.add_field(name="**Joined on**", value=member.joined_at.date())
			emb.add_field(name="**Avatar url**", value="[Here]({})".format(member.avatar_url))
			try:
				await ctx.send(embed=emb)
			except:
				await ctx.send("Too much info...")

def setup(bot):
	bot.add_cog(Info(bot))<|endoftext|>


<commit_before>def body_balance(t, y):

        # todo(put into function the k_elimination as a generic)
        n = len(y)  # 2: implies we have n ODEs
        dydt = np.zeros((n, 1))
        k_elimination = np.log(2) / (5 * 12) / 10

        def intake_amount_child(t, congener, mass_child):
            # todo(create automated peak year to run in loop based on the congener)
            year_begin = pop_start_year
            year_peak = 1977
            days_per_month = 365 / 12

            return_value = []
            if t < average_lact_time_months_:
                intake_curve_track_child.append(0)
                return 0

            elif t >= average_lact_time_months_ and t < (year_peak - year_begin) * 12:
                return_value = upswing_callable_intake(t) * mass_child * days_per_month / timesteps_per_month
                intake_curve_track_child.append(return_value)
                return upswing_callable_intake(t) * mass_child * days_per_month / timesteps_per_month

            elif t >= (year_peak - year_begin) * 12:  # and t < 2 * (year_peak - year_begin) * 12:

                return_value = upswing_callable_intake(t) * mass_child * days_per_month / timesteps_per_month
                intake_curve_track_child.append(return_value)
                return upswing_callable_intake(t) * mass_child * days_per_month / timesteps_per_month
            else:
                intake_curve_track_child.append(0)
                return 0

        def intake_amount(t, congener, mass_mother):
            # todo(create automated peak year to run in loop based on the congener)
            year_begin = pop_start_year
            year_peak = 1977
            days_per_month = 365 / 12

            # return_value = []
            if t < (year_peak - year_begin) * 12:
                return_value = upswing_callable_intake(t) * mass_mother * days_per_month / timesteps_per_month

            elif t >= year_peak * 12 and t < 2 * year_peak * 12:
                return_value = downswing_callable_intake(t) * mass_mother * days_per_month / timesteps_per_month

            else:
                return_value = 0

            intake_curve_track_mother.append(return_value)
            return return_value

        # mother mass, mass balance
        k_lactation = 0.005

        if generations == 1:
            if t < age_mom_in_years * 12:
                dydt[0] = spl_int_bw_lip_mass_deriv(t)
                dydt[1] = intake_amount(t, 'hcb', y[0]) - k_elimination * y[0]  # no lactation
                dydt[2] = 0
                dydt[3] = 0

            elif t >= age_mom_in_years * 12 and t < (age_mom_in_years * 12 + average_lact_time_months_):
                dydt[0] = spl_int_bw_lip_mass_deriv(t)
                dydt[1] = intake_amount(t, 'hcb', y[0]) - k_elimination * y[0] - k_lactation * y[0]
                dydt[2] = intake_amount_child(t, 'hcb', y[3]) - k_elimination * y[3] + k_lactation * y[0]
                dydt[3] = spl_int_bw_lip_mass_deriv(t - 12 * age_mom_in_years)

            elif t >= (age_mom_in_years * 12 + average_lact_time_months_) and t < (age_max_in_years * 12):
                dydt[0] = spl_int_bw_lip_mass_deriv(t)
                dydt[1] = intake_amount(t, 'hcb', y[0]) - k_elimination * y[0]
                dydt[2] = intake_amount_child(t, 'hcb', y[3]) - k_elimination * y[3] + k_lactation * y[0]
                dydt[3] = spl_int_bw_lip_mass_deriv(t - 12 * age_mom_in_years)

            elif t >= (age_max_in_years * 12):
                y[0] = 0

        if generations > 1:
            # todo(create function defining the number of generations, and the outputs for each y)
            print ('not quite ready for multi-generation use')

        # age_of_death_coefficient(t, y)
        return dydt

    # print intake_curve_track_child

    # use ``vode`` with "backward differentiation formula" or 'bdf'
    r = integrate.ode(body_balance).set_integrator('vode', order=5, nsteps=num_steps, max_step=delta_t, min_step=0,
                                                   method='bdf')
    r.set_initial_value([d_M_m_i, d_M_chem_m_i, d_C_chem_m_i, d_C_m_m_i], t_start)

    # create vectors to store trajectories
    t = np.zeros((np.int(num_steps), 1))

    mother_mass = np.zeros((np.int(num_steps), 1))
    mass_chemical_in_mother = np.zeros((np.int(num_steps), 1))
    mass_chemical_in_child = np.zeros((np.int(num_steps), 1))
    child_mass = np.zeros((np.int(num_steps), 1))<commit_msg> removed diff_chem.py<commit_after><|endoftext|>


<commit_before>import discord
import os
from os import walk
from random import randint
from random import choice
from discord.ext import commands
from cogs.utils.observable import Observable

class Jjal(Observable):
    def __init__(self, bot):
        self.bot = bot
        self.bot.listenPublicMsg(self)
        self.IMAGE_PATH = "./data/mutable"

    async def update(self, message):
        await self.checkJjalCategory(message)

    async def checkJjalCategory(self, message):
        if not message.content:
            return
        parsedMsg = message.content.split(' ')
        if self.bot.prefix.startswith(parsedMsg[0]):
            parsedMsg = parsedMsg[1:]
        category = parsedMsg[0].lower()
        if category == "sound":
            return
        if not os.path.isdir("{}/{}".format(self.IMAGE_PATH, category)):
            return

        imageName = " ".join(parsedMsg[1:])
        if not imageName:
            return
        if imageName == "목록":
            await self.printJjalList(message.channel, category)
            return
        if imageName == "랜덤":
            await self.deployRandomImage(message.channel, category)
            return

        for image in os.listdir("{}/{}".format(self.IMAGE_PATH, category)):
            if imageName == image.split('.')[0]:
                await self.deployImage(message.channel, category, image)
                return

    async def deployImage(self, channel, category, image):
        with open("{}/{}/{}".format(self.IMAGE_PATH, category, image), "rb") as f:
            await self.bot.send_file(channel, f)

    async def deployRandomImage(self, channel, category):
        imageList = os.listdir("{}/{}".format(self.IMAGE_PATH, category))
        image = choice(imageList)
        with open("{}/{}/{}".format(self.IMAGE_PATH, category, image), "rb") as f:
            await self.bot.send_file(channel, f)

    async def printJjalList(self, channel, category):
        imageList = os.listdir("{}/{}".format(self.IMAGE_PATH, category))
        imageList = ["🔹" + image.split(".")[0] for image in imageList]
        await self.bot.send_message(channel, "```{}```".format(" ".join(imageList)))

def setup(bot):
    cog = Jjal(bot)
    bot.add_cog(cog)
<commit_msg>feat: Making "짤" folder can be accessed without prefix<commit_after>import discord
import os
from os import walk
from random import randint
from random import choice
from discord.ext import commands
from cogs.utils.observable import Observable

class Jjal(Observable):
    def __init__(self, bot):
        self.bot = bot
        self.bot.listenPublicMsg(self)
        self.IMAGE_PATH = "./data/mutable"

    async def update(self, message):
        await self.checkJjalCategory(message)

    async def checkJjalCategory(self, message):
        if not message.content:
            return
        parsedMsg = message.content.split(' ')
        if self.bot.prefix.startswith(parsedMsg[0]):
            parsedMsg = parsedMsg[1:]
        category = parsedMsg[0].lower()
        if category == "sound":
            return
        if not os.path.isdir("{}/{}".format(self.IMAGE_PATH, category)):
            category = "짤"
            imageName = " ".join(parsedMsg[0:])
        else:
            imageName = " ".join(parsedMsg[1:])
        if not imageName:
            return
        if imageName == "목록":
            await self.printJjalList(message.channel, category)
            return
        if imageName == "랜덤":
            await self.deployRandomImage(message.channel, category)
            return

        for image in os.listdir("{}/{}".format(self.IMAGE_PATH, category)):
            if imageName == image.split('.')[0]:
                await self.deployImage(message.channel, category, image)
                return

    async def deployImage(self, channel, category, image):
        with open("{}/{}/{}".format(self.IMAGE_PATH, category, image), "rb") as f:
            await self.bot.send_file(channel, f)

    async def deployRandomImage(self, channel, category):
        imageList = os.listdir("{}/{}".format(self.IMAGE_PATH, category))
        image = choice(imageList)
        with open("{}/{}/{}".format(self.IMAGE_PATH, category, image), "rb") as f:
            await self.bot.send_file(channel, f)

    async def printJjalList(self, channel, category):
        imageList = os.listdir("{}/{}".format(self.IMAGE_PATH, category))
        imageList = ["🔹" + image.split(".")[0] for image in imageList]
        await self.bot.send_message(channel, "```{}```".format(" ".join(imageList)))

def setup(bot):
    cog = Jjal(bot)
    bot.add_cog(cog)
<|endoftext|>


<commit_before>#!/bin/evn python
import discord
import json
from utils import aiohttp_wrap as aw
from discord.ext import commands

class News:
    def __init__(self, bot):
        self.bot = bot
        self.redis_client = bot.redis_client
        self.aio_session = bot.aio_session
        self.uri = 'https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey={}'
        with open('data/apikeys.json') as f:
            self.api_key = json.load(f)['news']

    def json_to_embed(json_dict):
        em = discord.Embed()
        em.title = json_dict['title']
        em.description = json_dict['description']
        em.url = json_dict['url']
        em.set_image(url=json_dict['urlToImage'])

        return em

    @commands.command(name='news')
    async def get_news(self, ctx):
        """ Get the top 5 articles from Google News (http://newsapi.org """

        """
        Here's my dream:
           1. Check whether cached response exists
           2. Return that information or make the API call
           3. Map each field of the json response to an embed field
                - Make the footer of the embed the page currently displayed
           - The bot sends the first article in this format from a list of pre-fabricated embeds
            - I can get the message object which was sent by assigning the ctx.send to a variable
                - Add 1 - 5 emoji reactions along with first/last buttons
                - When the user clicks on one (on_reaction_add / on_reaction_remove) go to that page with:
                    - discord.Message.edit
        """

        em_list = []

        if await self.redis_client.exists('news'):
            raw_json_string = await self.redis_client.get('news')
            raw_json_dict = json.loads(raw_json_string)
            article_list = raw_json_dict['articles']

            for article in article_list:
                em_list.append(News.json_to_embed(article))

        else:
            api_response = await aw.aio_get_json(self.aio_session, self.uri.format(self.api_key))
            article_list = api_response['articles']
            await self.redis_client.set('news', json.dumps(api_response), ex=300)

            for article in article_list:
                em_list.append(News.json_to_embed(article))

        bot_message = await ctx.send(embed=em_list[0])
        for embed in em_list:
            asyncio.sleep(5)
            bot_message.edit(embed=embed)

def setup(bot):
    bot.add_cog(News(bot))
<commit_msg>forgot import<commit_after>#!/bin/evn python
import discord
import json
import asyncio
from utils import aiohttp_wrap as aw
from discord.ext import commands

class News:
    def __init__(self, bot):
        self.bot = bot
        self.redis_client = bot.redis_client
        self.aio_session = bot.aio_session
        self.uri = 'https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey={}'
        with open('data/apikeys.json') as f:
            self.api_key = json.load(f)['news']

    def json_to_embed(json_dict):
        em = discord.Embed()
        em.title = json_dict['title']
        em.description = json_dict['description']
        em.url = json_dict['url']
        em.set_image(url=json_dict['urlToImage'])

        return em

    @commands.command(name='news')
    async def get_news(self, ctx):
        """ Get the top 5 articles from Google News (http://newsapi.org """

        """
        Here's my dream:
           1. Check whether cached response exists
           2. Return that information or make the API call
           3. Map each field of the json response to an embed field
                - Make the footer of the embed the page currently displayed
           - The bot sends the first article in this format from a list of pre-fabricated embeds
            - I can get the message object which was sent by assigning the ctx.send to a variable
                - Add 1 - 5 emoji reactions along with first/last buttons
                - When the user clicks on one (on_reaction_add / on_reaction_remove) go to that page with:
                    - discord.Message.edit
        """

        em_list = []

        if await self.redis_client.exists('news'):
            raw_json_string = await self.redis_client.get('news')
            raw_json_dict = json.loads(raw_json_string)
            article_list = raw_json_dict['articles']

            for article in article_list:
                em_list.append(News.json_to_embed(article))

        else:
            api_response = await aw.aio_get_json(self.aio_session, self.uri.format(self.api_key))
            article_list = api_response['articles']
            await self.redis_client.set('news', json.dumps(api_response), ex=300)

            for article in article_list:
                em_list.append(News.json_to_embed(article))

        bot_message = await ctx.send(embed=em_list[0])
        for embed in em_list:
            asyncio.sleep(5)
            bot_message.edit(embed=embed)

def setup(bot):
    bot.add_cog(News(bot))
<|endoftext|>


<commit_before>from discord.ext import commands
from .utils import checks
import asyncio
import traceback

class REPL:
    def __init__(self, bot):
        self.bot = bot

    def cleanup_code(self, content):
        """Automatically removes code blocks from the code."""
        # remove ```py\n```
        if content.startswith('```') and content.endswith('```'):
            return '\n'.join(content.split('\n')[1:-1])

        # remove `foo`
        return content.strip('` \n')

    def get_syntax_error(self, e):
        return '```py\n{0.text}{1:>{0.offset}}\n{2}: {0}```'.format(e, '^', type(e).__name__)

    @commands.command(pass_context=True, hidden=True)
    @checks.is_owner()
    async def repl(self, ctx):
        msg = ctx.message

        repl_locals = {}
        repl_globals = {
            'ctx': ctx,
            'bot': self.bot,
            'message': msg
        }

        await self.bot.say('Enter code to execute or evaluate. `exit()` or `quit` to exit\n'
                           'Code must be `code` or in code blocks.\n'
                           'After 10 minutes of no replying I will auto-exit.\n'
                           'I will auto remove \`\`\`py blocks for you.')
        while True:
            response = await self.bot.wait_for_message(author=msg.author, channel=msg.channel,
                                                       timeout=600.0, check=lambda m: m.content.startswith('`'))
            if response is None:
                await self.bot.say('Auto exiting.')
                return

            cleaned = self.cleanup_code(response.content)

            if cleaned in ('quit', 'exit', 'exit()'):
                await self.bot.say('Exiting.')
                return

            use_eval = False

            if cleaned.count('\n') == 0:
                # single statement, potentially 'eval'
                try:
                    code = compile(cleaned, '<repl session>', 'eval')
                except SyntaxError:
                    pass
                else:
                    use_eval = True

            if not use_eval:
                try:
                    code = compile(cleaned, '<repl session>', 'exec')
                except SyntaxError as e:
                    await self.bot.say(self.get_syntax_error(e))
                    continue

            executor = exec if not use_eval else eval
            repl_globals['message'] = response

            try:
                result = executor(code, repl_globals, repl_locals)
                if asyncio.iscoroutine(result):
                    result = await result
            except Exception as e:
                await self.bot.say('```py\n{}\n```'.format(traceback.format_exc()))
            else:
                if result is not None:
                    await self.bot.say('```py\n{}\n```'.format(result))

def setup(bot):
    bot.add_cog(REPL(bot))
<commit_msg>Cleanup repl code and remove auto-cancelling.<commit_after>from discord.ext import commands
from .utils import checks
import asyncio
import traceback

class REPL:
    def __init__(self, bot):
        self.bot = bot

    def cleanup_code(self, content):
        """Automatically removes code blocks from the code."""
        # remove ```py\n```
        if content.startswith('```') and content.endswith('```'):
            return '\n'.join(content.split('\n')[1:-1])

        # remove `foo`
        return content.strip('` \n')

    def get_syntax_error(self, e):
        return '```py\n{0.text}{1:>{0.offset}}\n{2}: {0}```'.format(e, '^', type(e).__name__)

    @commands.command(pass_context=True, hidden=True)
    @checks.is_owner()
    async def repl(self, ctx):
        msg = ctx.message

        repl_locals = {}
        repl_globals = {
            'ctx': ctx,
            'bot': self.bot,
            'message': msg
        }

        await self.bot.say('Enter code to execute or evaluate. `exit()` or `quit` to exit.')
        while True:
            response = await self.bot.wait_for_message(author=msg.author, channel=msg.channel,
                                                       check=lambda m: m.content.startswith('`'))

            cleaned = self.cleanup_code(response.content)

            if cleaned in ('quit', 'exit', 'exit()'):
                await self.bot.say('Exiting.')
                return

            executor = exec
            if cleaned.count('\n') == 0:
                # single statement, potentially 'eval'
                try:
                    code = compile(cleaned, '<repl session>', 'eval')
                except SyntaxError:
                    pass
                else:
                    executor = eval

            if executor is exec:
                try:
                    code = compile(cleaned, '<repl session>', 'exec')
                except SyntaxError as e:
                    await self.bot.say(self.get_syntax_error(e))
                    continue

            repl_globals['message'] = response

            try:
                result = executor(code, repl_globals, repl_locals)
                if asyncio.iscoroutine(result):
                    result = await result
            except Exception as e:
                await self.bot.say('```py\n{}\n```'.format(traceback.format_exc()))
            else:
                if result is not None:
                    await self.bot.say('```py\n{}\n```'.format(result))

def setup(bot):
    bot.add_cog(REPL(bot))
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""
Trying to implement the following example
http://mdtraj.org/latest/examples/pca.html
"""

import mdtraj as md
import sys
from glob import glob
import numpy as np
import os
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from itertools import combinations
import argparse

parser = argparse.ArgumentParser(usage="""{} Trajectories*.nc Topology.prmtop""".
                                 format(sys.argv[0]),
                                 epilog="""Load up a list of AMBER NetCDF
                                 trajectories and their corresponding topology
                                 with MDtraj.Calculate a two-component PCA
                                 based on the pairwise distance between alpha
                                 carbons of the protein bakcbone. Plot a hexbin
                                 projection of the trajectories onto the PC space""")

parser.add_argument("Trajectories", help="""An indefinite amount of AMBER
                    trajectories""", nargs="+")

parser.add_argument("Topology", help="""The topology .prmtop file that matches
                    the trajectories""")

parser.add_argument("-s", "--save", help="Save the plots as .png images",
                    action="store_true")

parser.add_argument("-st", "--stride", help="""Stride for the loading of the
                    trajectory. Must be a divisor of the chunk.
                    Default value is 1.""", default=1)

parser.add_argument("-ch", "--chunk", help="""Number of frames that will be
                    used by md.iterload to load up the trajectories. Must be
                    a multiplier of the stride.
                    Default is 50 frames.""", default=1)

args = parser.parse_args()

def load_Trajs(names, topology, stride=1, chunk = 50):
    list_chunks = []
    for file in names:
        for frag in md.iterload(file, chunk = chunk, top = topology,
                                stride=stride):
            list_chunks.append(frag)
    return(list_chunks)

def pca_pwise_distance(list_chunks):
    pca = PCA(n_components=2)
    topology = list_chunks[0].topology
    ca_backbone = topology.select("backbone and name CA")
    pair_distances = []

    no_of_pwise_distances = ca_backbone.shape[0]*(ca_backbone.shape[0] -1 )/ 2
    print("""The number of pairwise distances to be calculated is: %s"""
          % int(no_of_pwise_distances))

    for chunk in list_chunks:
        pairs = topology.select_pairs(ca_backbone, ca_backbone)
        X = md.compute_distances(chunk, pairs)
        pair_distances.append(X)
    distance_array = np.concatenate(pair_distances)
    print(distance_array.shape)
    Y = pca.fit_transform(distance_array)
    return Y

def hex_plot(pca_array):
    PC1 = pca_array[:,0]
    PC2 = pca_array[:,1]
    plt.figure()
    plt.xlabel('PC1 (nm)')
    plt.ylabel('PC2 (nm)')
    plt.hexbin(x=PC1, y=PC2, bins='log', mincnt=1)
    if args.save:
        plt.savefig("PCA.png", dpi=600)
    else:
        plt.show()

def main():
    print('\n', args, '\n')
    if args:
        list_chunks = load_Trajs(sorted(args.Trajectories), args.Topology,
                                 stride=int(args.stride), chunk=int(args.chunk))
        pca_array = pca_pwise_distance(list_chunks)
        hex_plot(pca_array)

if __name__ == "__main__":
    main()
<commit_msg>Correct units for PC's is Å, not nm<commit_after>#!/usr/bin/env python
"""
Trying to implement the following example
http://mdtraj.org/latest/examples/pca.html
"""

import mdtraj as md
import sys
from glob import glob
import numpy as np
import os
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from itertools import combinations
import argparse

parser = argparse.ArgumentParser(usage="""{} Trajectories*.nc Topology.prmtop""".
                                 format(sys.argv[0]),
                                 epilog="""Load up a list of AMBER NetCDF
                                 trajectories and their corresponding topology
                                 with MDtraj.Calculate a two-component PCA
                                 based on the pairwise distance between alpha
                                 carbons of the protein bakcbone. Plot a hexbin
                                 projection of the trajectories onto the PC space""")

parser.add_argument("Trajectories", help="""An indefinite amount of AMBER
                    trajectories""", nargs="+")

parser.add_argument("Topology", help="""The topology .prmtop file that matches
                    the trajectories""")

parser.add_argument("-s", "--save", help="Save the plots as .png images",
                    action="store_true")

parser.add_argument("-st", "--stride", help="""Stride for the loading of the
                    trajectory. Must be a divisor of the chunk.
                    Default value is 1.""", default=1)

parser.add_argument("-ch", "--chunk", help="""Number of frames that will be
                    used by md.iterload to load up the trajectories. Must be
                    a multiplier of the stride.
                    Default is 50 frames.""", default=1)

args = parser.parse_args()

def load_Trajs(names, topology, stride=1, chunk = 50):
    list_chunks = []
    for file in names:
        for frag in md.iterload(file, chunk = chunk, top = topology,
                                stride=stride):
            list_chunks.append(frag)
    return(list_chunks)

def pca_pwise_distance(list_chunks):
    pca = PCA(n_components=2)
    topology = list_chunks[0].topology
    ca_backbone = topology.select("backbone and name CA")
    pair_distances = []

    no_of_pwise_distances = ca_backbone.shape[0]*(ca_backbone.shape[0] -1 )/ 2
    print("""The number of pairwise distances to be calculated is: %s"""
          % int(no_of_pwise_distances))

    for chunk in list_chunks:
        pairs = topology.select_pairs(ca_backbone, ca_backbone)
        X = md.compute_distances(chunk, pairs)
        pair_distances.append(X)
    distance_array = np.concatenate(pair_distances)
    print(distance_array.shape)
    Y = pca.fit_transform(distance_array)
    return Y

def hex_plot(pca_array):
    PC1 = pca_array[:,0]
    PC2 = pca_array[:,1]
    plt.figure()
    plt.xlabel('PC1 (Å)')
    plt.ylabel('PC2 (Å)')
    plt.hexbin(x=PC1, y=PC2, bins='log', mincnt=1)
    if args.save:
        plt.savefig("PCA.png", dpi=600)
    else:
        plt.show()

def main():
    print('\n', args, '\n')
    if args:
        list_chunks = load_Trajs(sorted(args.Trajectories), args.Topology,
                                 stride=int(args.stride), chunk=int(args.chunk))
        pca_array = pca_pwise_distance(list_chunks)
        hex_plot(pca_array)

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Samson Yeung, Phil Sung
#
# This file is part of Zeya.
#
# Zeya is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Zeya is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Zeya. If not, see <http://www.gnu.org/licenses/>.

# Directory backend.
#
# Files in the specified directory are read for artist/title/album tag which is
# then saved in a database (zeya.db) stored in that directory.

import os
import tagpy
import pickle

from backends import LibraryBackend
from backends import extract_metadata
from common import tokenize_filename
from m3u import M3uPlaylist
from pls import PlsPlaylist

KEY = 'key'

DB = 'db'
KEY_FILENAME = 'key_filename'
MTIMES = 'mtimes'

class DirectoryBackend(LibraryBackend):
    """
    Object that controls access to music in a given directory.
    """
    def __init__(self, media_path, save_db=True):
        """
        Initializes a DirectoryBackend that reads from the specified directory.

        save_db can be set to False to prevent the db from being written back
        to disk. This is probably only useful for debugging purposes.
        """
        self._media_path = os.path.expanduser(media_path)
        self._save_db = save_db
        # Sequence of dicts containing song metadata (key, artist, title, album)
        self.db = []
        # Playlists
        self._playlists = []
        # Dict mapping keys to source filenames and vice versa
        self.key_filename = {}
        self.filename_key = {}
        # Dict mapping filenames to mtimes
        self.mtimes = {}

        self.setup_db()

    def get_db_filename(self):
        return os.path.join(self._media_path, 'zeya.db')

    def setup_db(self):
        # Load the previous database from file, and convert it to a
        # representation where it can serve as a metadata cache (keyed by
        # filename) when we load the file collection.
        previous_db = self.load_previous_db()
        self.fill_db(previous_db)
        if self._save_db:
            self.save_db()

    def load_previous_db(self):
        """
        Read the existing database on disk and return a dict mapping each
        filename to the (mtime, metadata) associated with the filename.
        """
        filename_to_metadata_map = {}
        try:
            # Load the old data structures from file.
            info = pickle.load(open(self.get_db_filename(), 'r'))
            key_to_metadata_map = {}
            prev_mtimes = info[MTIMES]
            # Construct a map from keys to metadata.
            for db_entry in info[DB]:
                key_to_metadata_map[db_entry[KEY]] = db_entry
            # Construct a map from filename to (mtime, metadata) associated
            # with that file.
            for (key, filename) in info[KEY_FILENAME].iteritems():
                filename_to_metadata_map[filename] = \
                    (prev_mtimes[filename], key_to_metadata_map[key])
        except IOError:
            # Couldn't read the file. Just return an empty data structure.
            pass
        return filename_to_metadata_map

    def save_db(self):
        self.info = {DB: self.db,
                     MTIMES: self.mtimes,
                     KEY_FILENAME: self.key_filename}
        try:
            pickle.dump(self.info, open(self.get_db_filename(), 'wb+'))
        except IOError, e:
            print "Warning: the metadata cache could not be written to disk:"
            print "  " + str(e)
            print "(Zeya will continue, but the directory will need to be",
            print "re-scanned the next time Zeya is run.)"

    def write_metadata(self, filename, previous_db):
        """
        Obtains and writes the metadata for the specified FILENAME to the
        database. The metadata may be found by looking in the cache
        (PREVIOUS_DB), and failing that, by pulling the metadata from the file
        itself.

        Returns the key associated with the filename.
        """
        if filename in self.filename_key:
            # First, if the filename is already in our database, we don't have
            # to do anything. We can encounter the same filename twice if a
            # playlist contains a reference to a file we've already scanned.
            key = self.filename_key[filename]
        else:
            # The filename is not in the database. We have to obtain a metadata
            # entry, either by reading it out of our cache, or by calling out
            # to tagpy.
            #
            # previous_db acts as a cache of mtime and metadata, keyed by
            # filename.
            rec_mtime, old_metadata = previous_db.get(filename, (None, None))
            file_mtime = os.stat(filename).st_mtime

            if rec_mtime is not None and rec_mtime >= file_mtime:
                # Use cached data. However, we potentially renumber the keys
                # every time the program runs, so the old KEY is no good. We'll
                # fix up the KEY field below.
                metadata = old_metadata
            else:
                # In this branch, we actually need to read the file and
                # extract its metadata.
                metadata = extract_metadata(filename)

            # Assign a key for this song. These are just integers assigned
            # sequentially.
            key = len(self.key_filename)
            metadata[KEY] = key

            self.db.append(metadata)
            self.key_filename[key] = filename
            self.filename_key[filename] = key
            self.mtimes[filename] = file_mtime

        return key

    def fill_db(self, previous_db):
        """
        Populate the database, given the output of load_previous_db.
        """
        # By default, os.walk will happily accept a non-existent directory and
        # return an empty sequence. Detect the case of a non-existent path and
        # bail out early.
        if not os.path.exists(self._media_path):
            raise IOError("Error: directory %r doesn't exist." % (self._media_path,))
        print "Scanning for music in %r..." % (os.path.abspath(self._media_path),)
        # Iterate over all the files.
        for path, dirs, files in os.walk(self._media_path, followlinks=True):
            # Sort dirs so that subdirectories will subsequently be visited
            # alphabetically (see os.walk).
            dirs.sort(key=tokenize_filename)
            for filename in sorted(files, key=tokenize_filename):
                filename = os.path.abspath(os.path.join(path, filename))

                if filename.lower().endswith('.m3u') or filename.lower().endswith('.pls'):
                    # Encountered a playlist file.
                    if filename.lower().endswith('.m3u'):
                        playlist = M3uPlaylist(filename, open(filename))
                    elif filename.lower().endswith('.pls'):
                        playlist = PlsPlaylist(filename, open(filename))
                    items = []
                    for song_filename in playlist.get_filenames():
                        try:
                            song_key = self.write_metadata(
                                song_filename, previous_db)
                        except (OSError, ValueError):
                            continue
                        items.append(song_key)
                    self._playlists.append(
                        {'name' : os.path.basename(filename), 'items': items})
                else:
                    # Encountered what is possibly a regular music file.
                    try:
                        self.write_metadata(filename, previous_db)
                    except (OSError, ValueError):
                        continue

    def get_library_contents(self):
        return self.db

    def get_playlists(self):
        return self._playlists

    def get_filename_from_key(self, key):
        return self.key_filename[int(key)]
<commit_msg>directory.py: let each playlist supply its own title.<commit_after># -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Samson Yeung, Phil Sung
#
# This file is part of Zeya.
#
# Zeya is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Zeya is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Zeya. If not, see <http://www.gnu.org/licenses/>.

# Directory backend.
#
# Files in the specified directory are read for artist/title/album tag which is
# then saved in a database (zeya.db) stored in that directory.

import os
import tagpy
import pickle

from backends import LibraryBackend
from backends import extract_metadata
from common import tokenize_filename
from m3u import M3uPlaylist
from pls import PlsPlaylist

KEY = 'key'

DB = 'db'
KEY_FILENAME = 'key_filename'
MTIMES = 'mtimes'

class DirectoryBackend(LibraryBackend):
    """
    Object that controls access to music in a given directory.
    """
    def __init__(self, media_path, save_db=True):
        """
        Initializes a DirectoryBackend that reads from the specified directory.

        save_db can be set to False to prevent the db from being written back
        to disk. This is probably only useful for debugging purposes.
        """
        self._media_path = os.path.expanduser(media_path)
        self._save_db = save_db
        # Sequence of dicts containing song metadata (key, artist, title, album)
        self.db = []
        # Playlists
        self._playlists = []
        # Dict mapping keys to source filenames and vice versa
        self.key_filename = {}
        self.filename_key = {}
        # Dict mapping filenames to mtimes
        self.mtimes = {}

        self.setup_db()

    def get_db_filename(self):
        return os.path.join(self._media_path, 'zeya.db')

    def setup_db(self):
        # Load the previous database from file, and convert it to a
        # representation where it can serve as a metadata cache (keyed by
        # filename) when we load the file collection.
        previous_db = self.load_previous_db()
        self.fill_db(previous_db)
        if self._save_db:
            self.save_db()

    def load_previous_db(self):
        """
        Read the existing database on disk and return a dict mapping each
        filename to the (mtime, metadata) associated with the filename.
        """
        filename_to_metadata_map = {}
        try:
            # Load the old data structures from file.
            info = pickle.load(open(self.get_db_filename(), 'r'))
            key_to_metadata_map = {}
            prev_mtimes = info[MTIMES]
            # Construct a map from keys to metadata.
            for db_entry in info[DB]:
                key_to_metadata_map[db_entry[KEY]] = db_entry
            # Construct a map from filename to (mtime, metadata) associated
            # with that file.
            for (key, filename) in info[KEY_FILENAME].iteritems():
                filename_to_metadata_map[filename] = \
                    (prev_mtimes[filename], key_to_metadata_map[key])
        except IOError:
            # Couldn't read the file. Just return an empty data structure.
            pass
        return filename_to_metadata_map

    def save_db(self):
        self.info = {DB: self.db,
                     MTIMES: self.mtimes,
                     KEY_FILENAME: self.key_filename}
        try:
            pickle.dump(self.info, open(self.get_db_filename(), 'wb+'))
        except IOError, e:
            print "Warning: the metadata cache could not be written to disk:"
            print "  " + str(e)
            print "(Zeya will continue, but the directory will need to be",
            print "re-scanned the next time Zeya is run.)"

    def write_metadata(self, filename, previous_db):
        """
        Obtains and writes the metadata for the specified FILENAME to the
        database. The metadata may be found by looking in the cache
        (PREVIOUS_DB), and failing that, by pulling the metadata from the file
        itself.

        Returns the key associated with the filename.
        """
        if filename in self.filename_key:
            # First, if the filename is already in our database, we don't have
            # to do anything. We can encounter the same filename twice if a
            # playlist contains a reference to a file we've already scanned.
            key = self.filename_key[filename]
        else:
            # The filename is not in the database. We have to obtain a metadata
            # entry, either by reading it out of our cache, or by calling out
            # to tagpy.
            #
            # previous_db acts as a cache of mtime and metadata, keyed by
            # filename.
            rec_mtime, old_metadata = previous_db.get(filename, (None, None))
            file_mtime = os.stat(filename).st_mtime

            if rec_mtime is not None and rec_mtime >= file_mtime:
                # Use cached data. However, we potentially renumber the keys
                # every time the program runs, so the old KEY is no good. We'll
                # fix up the KEY field below.
                metadata = old_metadata
            else:
                # In this branch, we actually need to read the file and
                # extract its metadata.
                metadata = extract_metadata(filename)

            # Assign a key for this song. These are just integers assigned
            # sequentially.
            key = len(self.key_filename)
            metadata[KEY] = key

            self.db.append(metadata)
            self.key_filename[key] = filename
            self.filename_key[filename] = key
            self.mtimes[filename] = file_mtime

        return key

    def fill_db(self, previous_db):
        """
        Populate the database, given the output of load_previous_db.
        """
        # By default, os.walk will happily accept a non-existent directory and
        # return an empty sequence. Detect the case of a non-existent path and
        # bail out early.
        if not os.path.exists(self._media_path):
            raise IOError("Error: directory %r doesn't exist." % (self._media_path,))
        print "Scanning for music in %r..." % (os.path.abspath(self._media_path),)
        # Iterate over all the files.
        for path, dirs, files in os.walk(self._media_path, followlinks=True):
            # Sort dirs so that subdirectories will subsequently be visited
            # alphabetically (see os.walk).
            dirs.sort(key=tokenize_filename)
            for filename in sorted(files, key=tokenize_filename):
                filename = os.path.abspath(os.path.join(path, filename))

                if filename.lower().endswith('.m3u') or filename.lower().endswith('.pls'):
                    # Encountered a playlist file.
                    if filename.lower().endswith('.m3u'):
                        playlist = M3uPlaylist(filename, open(filename))
                    elif filename.lower().endswith('.pls'):
                        playlist = PlsPlaylist(filename, open(filename))
                    items = []
                    for song_filename in playlist.get_filenames():
                        try:
                            song_key = self.write_metadata(
                                song_filename, previous_db)
                        except (OSError, ValueError):
                            continue
                        items.append(song_key)
                    self._playlists.append(
                        {'name' : playlist.get_title(), 'items': items})
                else:
                    # Encountered what is possibly a regular music file.
                    try:
                        self.write_metadata(filename, previous_db)
                    except (OSError, ValueError):
                        continue

    def get_library_contents(self):
        return self.db

    def get_playlists(self):
        return self._playlists

    def get_filename_from_key(self, key):
        return self.key_filename[int(key)]
<|endoftext|>


<commit_before>#!/usr/bin/env python
###################################################################
#
# Copyright (c) 2011 Canonical Ltd.
# Copyright (c) 2013 Miing.org <samuel.miing@gmail.com>
#
# This software is licensed under the GNU Affero General Public
# License version 3 (AGPLv3), as published by the Free Software
# Foundation, and may be copied, distributed, and modified under
# those terms.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# file LICENSE for more details.
#
###################################################################

import paths
paths.setup_paths()

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj.settings')

    from django_configglue.management import execute_from_command_line

    execute_from_command_line(sys.argv)
<commit_msg>Fix 'not import from sys'<commit_after>#!/usr/bin/env python
###################################################################
#
# Copyright (c) 2011 Canonical Ltd.
# Copyright (c) 2013 Miing.org <samuel.miing@gmail.com>
#
# This software is licensed under the GNU Affero General Public
# License version 3 (AGPLv3), as published by the Free Software
# Foundation, and may be copied, distributed, and modified under
# those terms.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# file LICENSE for more details.
#
###################################################################

import os
import sys

import paths
paths.setup_paths()

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj.settings')

    from django_configglue.management import execute_from_command_line

    execute_from_command_line(sys.argv)
<|endoftext|>


<commit_before>import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello world"

if __name__ == "__main__":
    port = int(os.environ.get("PORT", 5000))
    app.run(host='0.0.0.0', port=port)
<commit_msg>Testing isaac's scipt<commit_after>from flask import Flask, request, redirect
import twilio.twiml
from twilio.rest import TwilioRestClient

app = Flask(__name__)

def send_message();
    client.messages.create(
        to=userNumber,
        from_=OUR_NUMBER,
        body=response,
        media_url=media_response,
    )

#from Twilio acct
ACCOUNT_SID = "ACe892e28b309a94844845c5f621ca451a"
AUTH_TOKEN = "[99426e30a3c5c2e25d5ba56f9087b7c3]"
OUR_NUMBER = "+18442306122"

#needs to be a string
userNumber= request.values.get( 'From', None )

@app.route("/", methods=['GET', 'POST'])

client = TwilioRestClient( ACCOUNT_SID, AUTH_TOKEN )

while true:
    clientMessages = client.messages.list( to=OUR_NUMBER )
    for m in clientMessages:
        if m.status == "receiving":
            #do the things
            userNumber=m.From
            response= m.status
            send_message()
        if m.status == "undelivered" or m.status == "failed":
            #TBD

response = "4321"
media_response = ""

send_message()

if __name__ == "__main__":
    port = int( os.environ.get( "PORT",5000 ) )
    app.run(host="0.0.0.0", port=port)
<|endoftext|>


<commit_before>from django.conf.urls import patterns, include, url
from django.views.generic.edit import CreateView
from django.contrib.auth.forms import UserCreationForm

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    url(r'^$', 'dlib.views.landing', name='landing'),
    url(r'^user$', 'dlib.views.user', name='user'),
    url(r'^book$', 'dlib.views.book', name='book'),
    url(r'^booklist$', 'dlib.views.booklist', name='booklist'),

    # url(r'^dlib/', include('dlib.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    url('^register/', CreateView.as_view(
            template_name='register.html',
            form_class=UserCreationForm,
            success_url='/'
    )),
    url('^accounts/', include('django.contrib.auth.urls')),

    # Uncomment the next line to enable the admin:
     url(r'^admin/', include(admin.site.urls)),
)
<commit_msg>Book single page reorder.<commit_after>from django.conf.urls import patterns, include, url
from django.views.generic.edit import CreateView
from django.contrib.auth.forms import UserCreationForm

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    url(r'^$', 'dlib.views.landing', name='landing'),
    url(r'^user$', 'dlib.views.user', name='user'),
    url(r'^book/(\d+)$', 'dlib.views.book', name='book'),
    url(r'^booklist$', 'dlib.views.booklist', name='booklist'),

    # url(r'^dlib/', include('dlib.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    url('^register/', CreateView.as_view(
            template_name='register.html',
            form_class=UserCreationForm,
            success_url='/'
    )),
    url('^accounts/', include('django.contrib.auth.urls')),

    # Uncomment the next line to enable the admin:
     url(r'^admin/', include(admin.site.urls)),
)
<|endoftext|>


<commit_before>"""
Script for setting up and using [all]reduce with a binary-tree engine interconnect.

usage: `python bintree_script.py`

"""

from IPython.parallel import Client, Reference

# connect client and create views
rc = Client()
rc.block=True
ids = rc.ids

root_id = ids[0]
root = rc[root_id]

view = rc[:]

# run bintree.py script defining bintree functions, etc.
execfile('bintree.py')

# generate binary tree of parents
btree = bintree(ids)

print "setting up binary tree interconnect:"
print_bintree(btree)

view.run('bintree.py')
view.scatter('id', ids, flatten=True)
view['root_id'] = root_id

# create the Communicator objects on the engines
view.execute('com = BinaryTreeCommunicator(id, root = id==root_id )')
pub_url = root.apply_sync(lambda : com.pub_url)

# gather the connection information into a dict
ar = view.apply_async(lambda : com.info)
peers = ar.get_dict()
# this is a dict, keyed by engine ID, of the connection info for the EngineCommunicators

# connect the engines to each other:
def connect(com, peers, tree, pub_url, root_id):
    """this function will be called on the engines"""
    com.connect(peers, tree, pub_url, root_id)

view.apply_sync(connect, Reference('com'), peers, btree, pub_url, root_id)

# functions that can be used for reductions
# max and min builtins can be used as well
def add(a,b):
    """cumulative sum reduction"""
    return a+b

def mul(a,b):
    """cumulative product reduction"""
    return a*b

view['add'] = add
view['mul'] = mul

# scatter some data
data = range(1000)
view.scatter('data', data)

# perform cumulative sum via allreduce
view.execute("data_sum = com.allreduce(add, data, flat=False)")
print "allreduce sum of data on all engines:", view['data_sum']

# perform cumulative sum *without* final broadcast
# when not broadcasting with allreduce, the final result resides on the root node:
view.execute("ids_sum = com.reduce(add, id, flat=True)")
print "reduce sum of engine ids (not broadcast):", root['ids_sum']
print "partial result on each engine:", view['ids_sum']
<commit_msg>make bintree_script example executable<commit_after>#!/usr/bin/env python
"""
Script for setting up and using [all]reduce with a binary-tree engine interconnect.

usage: `python bintree_script.py`

"""

from IPython.parallel import Client, Reference

# connect client and create views
rc = Client()
rc.block=True
ids = rc.ids

root_id = ids[0]
root = rc[root_id]

view = rc[:]

# run bintree.py script defining bintree functions, etc.
execfile('bintree.py')

# generate binary tree of parents
btree = bintree(ids)

print "setting up binary tree interconnect:"
print_bintree(btree)

view.run('bintree.py')
view.scatter('id', ids, flatten=True)
view['root_id'] = root_id

# create the Communicator objects on the engines
view.execute('com = BinaryTreeCommunicator(id, root = id==root_id )')
pub_url = root.apply_sync(lambda : com.pub_url)

# gather the connection information into a dict
ar = view.apply_async(lambda : com.info)
peers = ar.get_dict()
# this is a dict, keyed by engine ID, of the connection info for the EngineCommunicators

# connect the engines to each other:
def connect(com, peers, tree, pub_url, root_id):
    """this function will be called on the engines"""
    com.connect(peers, tree, pub_url, root_id)

view.apply_sync(connect, Reference('com'), peers, btree, pub_url, root_id)

# functions that can be used for reductions
# max and min builtins can be used as well
def add(a,b):
    """cumulative sum reduction"""
    return a+b

def mul(a,b):
    """cumulative product reduction"""
    return a*b

view['add'] = add
view['mul'] = mul

# scatter some data
data = range(1000)
view.scatter('data', data)

# perform cumulative sum via allreduce
view.execute("data_sum = com.allreduce(add, data, flat=False)")
print "allreduce sum of data on all engines:", view['data_sum']

# perform cumulative sum *without* final broadcast
# when not broadcasting with allreduce, the final result resides on the root node:
view.execute("ids_sum = com.reduce(add, id, flat=True)")
print "reduce sum of engine ids (not broadcast):", root['ids_sum']
print "partial result on each engine:", view['ids_sum']
<|endoftext|>