<commit_before>import os
import json
import pprint
import humanize
import functools
import inspect

from datetime import datetime, timedelta
from holster.emitter import Priority
from disco.api.http import APIException
from disco.bot.command import CommandEvent

from rowboat import REV
from rowboat.util import C, LocalProxy
from rowboat.plugins import BasePlugin as Plugin
from rowboat.plugins import RowboatPlugin
from rowboat.sql import init_db
from rowboat.redis import rdb
from rowboat.models.user import Infraction
from rowboat.models.guild import Guild, GuildBan
from rowboat.models.notification import Notification
from rowboat.plugins.modlog import Actions

ENV = os.getenv('ENV', 'local')

PY_CODE_BLOCK = u'```py\n{}\n```'

INFO_MESSAGE = '''\
:information_source: Rowboat V{} - more information and detailed help can be found here:\
<https://github.com/b1naryth1ef/rowboat/wiki>
'''.format(REV)

class CorePlugin(Plugin):
    def load(self, ctx):
        init_db()

        self.startup = ctx.get('startup', datetime.utcnow())
        self.guilds = ctx.get('guilds', {})

        super(CorePlugin, self).load(ctx)

        for plugin in self.bot.plugins.values():
            if not isinstance(plugin, RowboatPlugin):
                continue

            plugin.register_trigger('command', 'pre', functools.partial(self.on_pre, plugin))
            plugin.register_trigger('listener', 'pre', functools.partial(self.on_pre, plugin))

        self.spawn(self.wait_for_updates)
        self.spawn(self.wait_for_dispatches)

    def wait_for_dispatches(self):
        ps = rdb.pubsub()
        ps.subscribe('notifications')

        for item in ps.listen():
            if item['type'] != 'message':
                continue

            obj = json.loads(item['data'])

            self.bot.client.api.channels_messages_create(
                290924692057882635,
                u'**{}**\n{}'.format(
                    obj['title'],
                    obj['content']))

    def wait_for_updates(self):
        ps = rdb.pubsub()
        ps.subscribe('guild-updates')

        for item in ps.listen():
            if item['type'] != 'message':
                continue

            data = json.loads(item['data'])
            if data['type'] == 'UPDATE' and data['id'] in self.guilds:
                self.send_control_message(u'Reloaded config for Guild {}'.format(self.guilds[data['id']].name))
                self.log.info('Reloading config for guild %s', self.guilds[data['id']].name)
                self.guilds[data['id']].get_config(refresh=True)

    def unload(self, ctx):
        ctx['guilds'] = self.guilds
        ctx['startup'] = self.startup
        super(CorePlugin, self).unload(ctx)

    def on_pre(self, plugin, func, event, args, kwargs):
        """
        This function handles dynamically dispatching and modifying events based
        on a specific guilds configuration. It is called before any handler of
        either commands or listeners.
        """
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            return

        if guild_id not in self.guilds:
            if isinstance(event, CommandEvent):
                if event.command.metadata.get('global_', False):
                    return event
            elif hasattr(func, 'subscriptions'):
                if func.subscriptions[0].metadata.get('global_', False):
                    return event

            return

        event.base_config = self.guilds[guild_id].get_config()

        plugin_name = plugin.name.lower().replace('plugin', '')
        if not getattr(event.base_config.plugins, plugin_name, None):
            return

        if not hasattr(event, 'config'):
            event.config = LocalProxy()

        event.config.set(getattr(event.base_config.plugins, plugin_name))
        return event

    @Plugin.schedule(290, init=False)
    def update_guild_bans(self):
        to_update = [
            guild for guild in Guild.select().where(
                (Guild.last_ban_sync < (datetime.utcnow() - timedelta(days=1))) |
                (Guild.last_ban_sync >> None)
            )
            if guild.guild_id in self.client.state.guilds]

        # Update 10 at a time
        for guild in to_update[:10]:
            guild.sync_bans(self.client.state.guilds.get(guild.guild_id))

    @Plugin.listen('GuildUpdate')
    def on_guild_udpate(self, event):
        self.log.info('Got guild update for guild %s (%s)', event.guild.id, event.guild.channels)

    @Plugin.listen('GuildMembersChunk')
    def on_guild_members_chunk(self, event):
        self.log.info('Got members chunk for guild %s', event.guild_id)

    @Plugin.listen('GuildBanAdd')
    def on_guild_ban_add(self, event):
        GuildBan.ensure(self.client.state.guilds.get(event.guild_id), event.user)

    @Plugin.listen('GuildBanRemove')
    def on_guild_ban_remove(self, event):
        GuildBan.delete().where(
            (GuildBan.user_id == event.user.id) &
            (GuildBan.guild_id == event.guild_id)
        )

    def send_control_message(self, content, *args, **kwargs):
        self.bot.client.api.channels_messages_create(
            290924692057882635,
            u'**{}**\n{}'.format('Production' if ENV == 'prod' else 'Local', content), *args, **kwargs)

    @Plugin.listen('Resumed')
    def on_resumed(self, event):
        Notification.dispatch(
            Notification.Types.RESUME,
            trace=event.trace,
            env=ENV,
        )

    @Plugin.listen('Ready')
    def on_ready(self, event):
        self.log.info('Started session %s', event.session_id)
        Notification.dispatch(
            Notification.Types.CONNECT,
            trace=event.trace,
            env=ENV,
        )

    @Plugin.schedule(1, init=False)
    def on_fucked_channels(self):
        for guild in self.state.guilds.values():
            if not len(guild.channels):
                self.log.warning('Guild %s (%s) has fucked channels', guild.id, guild.name)

    # @Plugin.listen('GuildCreate', conditional=lambda e: e.created is True)
    # def on_guild_join(self, event):
    #     self.send_control_message('Added to guild {}: {}'.format(event.guild.id, event.guild.name))

    @Plugin.listen('GuildDelete', conditional=lambda e: e.deleted is True)
    def on_guild_leave(self, event):
        self.send_control_message('Removed from guild {}'.format(event.guild.id))

    @Plugin.listen('GuildCreate', priority=Priority.BEFORE, conditional=lambda e: not e.created)
    def on_guild_create(self, event):
        try:
            guild = Guild.with_id(event.id)
        except Guild.DoesNotExist:
            return

        if not guild.enabled:
            return

        # Ensure we're updated
        self.log.info('Syncing guild %s', event.guild.id)
        guild.sync(event.guild)

        self.guilds[event.id] = guild

        if guild.get_config().nickname:
            def set_nickname():
                m = event.members.select_one(id=self.state.me.id)
                if m and m.nick != guild.get_config().nickname:
                    try:
                        m.set_nickname(guild.get_config().nickname)
                    except APIException as e:
                        self.log.warning('Failed to set nickname for guild %s (%s)', event.guild, e.content)
            self.spawn_later(5, set_nickname)

    def get_level(self, guild, user):
        config = (guild.id in self.guilds and self.guilds.get(guild.id).get_config())

        user_level = 0
        if config:
            member = guild.get_member(user.id)
            if not member:
                return user_level

            for oid in member.roles:
                if oid in config.levels and config.levels[oid] > user_level:
                    user_level = config.levels[oid]

            # User ID overrides should override all others
            if user.id in config.levels:
                user_level = config.levels[user.id]

        return user_level

    @Plugin.listen('MessageCreate')
    def on_message_create(self, event):
        """
        This monstrosity of a function handles the parsing and dispatching of
        commands.
        """
        # Ignore messages sent by bots
        if event.message.author.bot:
            return

        if rdb.sismember('ignored_channels', event.message.channel_id):
            return

        # If this is message for a guild, grab the guild object
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            guild_id = None

        guild = self.guilds.get(event.guild.id) if guild_id else None
        config = guild and guild.get_config()

        # If the guild has configuration, use that (otherwise use defaults)
        if config:
            if config.commands:
                commands = list(self.bot.get_commands_for_message(
                    config.commands.mention,
                    {},
                    config.commands.prefix,
                    event.message))
        elif guild_id:
            # Otherwise, default to requiring mentions
            commands = list(self.bot.get_commands_for_message(True, {}, '', event.message))
        else:
            if ENV != 'prod':
                if not event.message.content.startswith(ENV + '!'):
                    return
                event.message.content = event.message.content[len(ENV) + 1:]

            # DM's just use the commands (no prefix/mention)
            commands = list(self.bot.get_commands_for_message(False, {}, '', event.message))

        # If we didn't find any matching commands, return
        if not len(commands):
            return

        user_level = self.get_level(event.guild, event.author) if event.guild else 0

        # Grab whether this user is a global admin
        # TODO: cache this
        global_admin = rdb.sismember('global_admins', event.author.id)

        # Iterate over commands and find a match
        for command, match in commands:
            if command.level == -1 and not global_admin:
                continue

            level = command.level

            if guild and not config and command.triggers[0] != 'setup':
                continue
            elif config and config.commands and command.plugin != self:
                overrides = reduce(lambda a, b: a.update(b), list(config.commands.get_command_override(command)))

                if overrides['disabled']:
                    continue

                level = overrides.get('level', level)

            if not global_admin and user_level < level:
                continue

            command.plugin.execute(CommandEvent(command, event.message, match))

            # Dispatch the command used modlog event
            if config:
                event.config = getattr(config.plugins, 'modlog', None)
                if not event.config:
                    return

                plugin = self.bot.plugins.get('ModLogPlugin')
                if plugin:
                    plugin.log_action(Actions.COMMAND_USED, event)

            return

    @Plugin.command('setup')
    def command_setup(self, event):
        """
        Setup a new Guild with Rowboat
        """
        if not event.guild:
            return event.msg.reply(':warning: this command can only be used in servers')

        # Make sure we're not already setup
        if event.guild.id in self.guilds:
            return event.msg.reply(':warning: this server is already setup')

        global_admin = rdb.sismember('global_admins', event.author.id)

        # Make sure this is the owner of the server
        if not global_admin:
            if not event.guild.owner_id == event.author.id:
                return event.msg.reply(':warning: only the server owner can setup rowboat')

        # Make sure we have admin perms
        m = event.guild.members.select_one(id=self.state.me.id)
        if not m.permissions.administrator and not global_admin:
            return event.msg.reply(':warning: bot must have the Administrator permission')

        guild = Guild.setup(event.guild)
        self.guilds[event.guild.id] = guild
        event.msg.reply(':ok_hand: successfully loaded configuration')

    '''
    @Plugin.command('help', '<command>')
    def command_help(self, event, command):
        """
        Provides information on a given command.
        """
        for cmd in self.bot.commands:
            if command.lower() in cmd.triggers:
                break
        else:
            event.msg.reply(u"Couldn't find command for `{}`".format(C(command)))
            return

        event.msg.reply(u'Usage: {} {}\nDescription: {}'.format(
            command,
            cmd.raw_args or '',
            cmd.func.__doc__,
        ))
    '''

    @Plugin.command('nuke', '<user:snowflake> <reason:str...>', level=-1)
    def nuke(self, event, user, reason):
        """
        Force ban a user from all rowboat Guilds
        """
        for gid, guild in self.guilds.items():
            try:
                Infraction.ban(
                    self,
                    event,
                    user,
                    reason,
                    guild=self.state.guilds[gid])
            except:
                self.log.exception('Failed to force ban %s in %s', user, gid)

    @Plugin.command('uptime', level=-1)
    def command_uptime(self, event):
        event.msg.reply('Rowboat was started {}'.format(
            humanize.naturaltime(datetime.utcnow() - self.startup)
        ))

    @Plugin.command('source', '<command>', level=-1)
    def command_source(self, event, command=None):
        for cmd in self.bot.commands:
            if command.lower() in cmd.triggers:
                break
        else:
            event.msg.reply(u"Couldn't find command for `{}`".format(C(command)))
            return

        code = cmd.func.__code__
        lines, firstlineno = inspect.getsourcelines(code)

        event.msg.reply('<https://github.com/b1naryth1ef/rowboat/blob/master/{}#L{}-{}>'.format(
            code.co_filename,
            firstlineno,
            firstlineno + len(lines)
        ))

    @Plugin.command('eval', level=-1)
    def command_eval(self, event):
        ctx = {
            'bot': self.bot,
            'client': self.bot.client,
            'state': self.bot.client.state,
            'event': event,
            'msg': event.msg,
            'guild': event.msg.guild,
            'channel': event.msg.channel,
            'author': event.msg.author
        }

        # Mulitline eval
        src = event.codeblock
        if src.count('\n'):
            lines = filter(bool, src.split('\n'))
            if lines[-1] and 'return' not in lines[-1]:
                lines[-1] = 'return ' + lines[-1]
            lines = '\n'.join('    ' + i for i in lines)
            code = 'def f():\n{}\nx = f()'.format(lines)
            local = {}

            try:
                exec compile(code, '<eval>', 'exec') in ctx, local
            except Exception as e:
                event.msg.reply(PY_CODE_BLOCK.format(type(e).__name__ + ': ' + str(e)))
                return

            result = pprint.pformat(local['x'])
        else:
            try:
                result = str(eval(src, ctx))
            except Exception as e:
                event.msg.reply(PY_CODE_BLOCK.format(type(e).__name__ + ': ' + str(e)))
                return

        if len(result) > 1990:
            event.msg.reply('', attachment=('result.txt', result))
        else:
            event.msg.reply(PY_CODE_BLOCK.format(result))
<commit_msg>Fix disabled<commit_after>import os
import json
import pprint
import humanize
import functools
import inspect

from datetime import datetime, timedelta
from holster.emitter import Priority
from disco.api.http import APIException
from disco.bot.command import CommandEvent

from rowboat import REV
from rowboat.util import C, LocalProxy
from rowboat.plugins import BasePlugin as Plugin
from rowboat.plugins import RowboatPlugin
from rowboat.sql import init_db
from rowboat.redis import rdb
from rowboat.models.user import Infraction
from rowboat.models.guild import Guild, GuildBan
from rowboat.models.notification import Notification
from rowboat.plugins.modlog import Actions

ENV = os.getenv('ENV', 'local')

PY_CODE_BLOCK = u'```py\n{}\n```'

INFO_MESSAGE = '''\
:information_source: Rowboat V{} - more information and detailed help can be found here:\
<https://github.com/b1naryth1ef/rowboat/wiki>
'''.format(REV)

class CorePlugin(Plugin):
    def load(self, ctx):
        init_db()

        self.startup = ctx.get('startup', datetime.utcnow())
        self.guilds = ctx.get('guilds', {})

        super(CorePlugin, self).load(ctx)

        for plugin in self.bot.plugins.values():
            if not isinstance(plugin, RowboatPlugin):
                continue

            plugin.register_trigger('command', 'pre', functools.partial(self.on_pre, plugin))
            plugin.register_trigger('listener', 'pre', functools.partial(self.on_pre, plugin))

        self.spawn(self.wait_for_updates)
        self.spawn(self.wait_for_dispatches)

    def wait_for_dispatches(self):
        ps = rdb.pubsub()
        ps.subscribe('notifications')

        for item in ps.listen():
            if item['type'] != 'message':
                continue

            obj = json.loads(item['data'])

            self.bot.client.api.channels_messages_create(
                290924692057882635,
                u'**{}**\n{}'.format(
                    obj['title'],
                    obj['content']))

    def wait_for_updates(self):
        ps = rdb.pubsub()
        ps.subscribe('guild-updates')

        for item in ps.listen():
            if item['type'] != 'message':
                continue

            data = json.loads(item['data'])
            if data['type'] == 'UPDATE' and data['id'] in self.guilds:
                self.send_control_message(u'Reloaded config for Guild {}'.format(self.guilds[data['id']].name))
                self.log.info('Reloading config for guild %s', self.guilds[data['id']].name)
                self.guilds[data['id']].get_config(refresh=True)

    def unload(self, ctx):
        ctx['guilds'] = self.guilds
        ctx['startup'] = self.startup
        super(CorePlugin, self).unload(ctx)

    def on_pre(self, plugin, func, event, args, kwargs):
        """
        This function handles dynamically dispatching and modifying events based
        on a specific guilds configuration. It is called before any handler of
        either commands or listeners.
        """
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            return

        if guild_id not in self.guilds:
            if isinstance(event, CommandEvent):
                if event.command.metadata.get('global_', False):
                    return event
            elif hasattr(func, 'subscriptions'):
                if func.subscriptions[0].metadata.get('global_', False):
                    return event

            return

        event.base_config = self.guilds[guild_id].get_config()

        plugin_name = plugin.name.lower().replace('plugin', '')
        if not getattr(event.base_config.plugins, plugin_name, None):
            return

        if not hasattr(event, 'config'):
            event.config = LocalProxy()

        event.config.set(getattr(event.base_config.plugins, plugin_name))
        return event

    @Plugin.schedule(290, init=False)
    def update_guild_bans(self):
        to_update = [
            guild for guild in Guild.select().where(
                (Guild.last_ban_sync < (datetime.utcnow() - timedelta(days=1))) |
                (Guild.last_ban_sync >> None)
            )
            if guild.guild_id in self.client.state.guilds]

        # Update 10 at a time
        for guild in to_update[:10]:
            guild.sync_bans(self.client.state.guilds.get(guild.guild_id))

    @Plugin.listen('GuildUpdate')
    def on_guild_udpate(self, event):
        self.log.info('Got guild update for guild %s (%s)', event.guild.id, event.guild.channels)

    @Plugin.listen('GuildMembersChunk')
    def on_guild_members_chunk(self, event):
        self.log.info('Got members chunk for guild %s', event.guild_id)

    @Plugin.listen('GuildBanAdd')
    def on_guild_ban_add(self, event):
        GuildBan.ensure(self.client.state.guilds.get(event.guild_id), event.user)

    @Plugin.listen('GuildBanRemove')
    def on_guild_ban_remove(self, event):
        GuildBan.delete().where(
            (GuildBan.user_id == event.user.id) &
            (GuildBan.guild_id == event.guild_id)
        )

    def send_control_message(self, content, *args, **kwargs):
        self.bot.client.api.channels_messages_create(
            290924692057882635,
            u'**{}**\n{}'.format('Production' if ENV == 'prod' else 'Local', content), *args, **kwargs)

    @Plugin.listen('Resumed')
    def on_resumed(self, event):
        Notification.dispatch(
            Notification.Types.RESUME,
            trace=event.trace,
            env=ENV,
        )

    @Plugin.listen('Ready')
    def on_ready(self, event):
        self.log.info('Started session %s', event.session_id)
        Notification.dispatch(
            Notification.Types.CONNECT,
            trace=event.trace,
            env=ENV,
        )

    @Plugin.schedule(1, init=False)
    def on_fucked_channels(self):
        for guild in self.state.guilds.values():
            if not len(guild.channels):
                self.log.warning('Guild %s (%s) has fucked channels', guild.id, guild.name)

    # @Plugin.listen('GuildCreate', conditional=lambda e: e.created is True)
    # def on_guild_join(self, event):
    #     self.send_control_message('Added to guild {}: {}'.format(event.guild.id, event.guild.name))

    @Plugin.listen('GuildDelete', conditional=lambda e: e.deleted is True)
    def on_guild_leave(self, event):
        self.send_control_message('Removed from guild {}'.format(event.guild.id))

    @Plugin.listen('GuildCreate', priority=Priority.BEFORE, conditional=lambda e: not e.created)
    def on_guild_create(self, event):
        try:
            guild = Guild.with_id(event.id)
        except Guild.DoesNotExist:
            return

        if not guild.enabled:
            return

        # Ensure we're updated
        self.log.info('Syncing guild %s', event.guild.id)
        guild.sync(event.guild)

        self.guilds[event.id] = guild

        if guild.get_config().nickname:
            def set_nickname():
                m = event.members.select_one(id=self.state.me.id)
                if m and m.nick != guild.get_config().nickname:
                    try:
                        m.set_nickname(guild.get_config().nickname)
                    except APIException as e:
                        self.log.warning('Failed to set nickname for guild %s (%s)', event.guild, e.content)
            self.spawn_later(5, set_nickname)

    def get_level(self, guild, user):
        config = (guild.id in self.guilds and self.guilds.get(guild.id).get_config())

        user_level = 0
        if config:
            member = guild.get_member(user.id)
            if not member:
                return user_level

            for oid in member.roles:
                if oid in config.levels and config.levels[oid] > user_level:
                    user_level = config.levels[oid]

            # User ID overrides should override all others
            if user.id in config.levels:
                user_level = config.levels[user.id]

        return user_level

    @Plugin.listen('MessageCreate')
    def on_message_create(self, event):
        """
        This monstrosity of a function handles the parsing and dispatching of
        commands.
        """
        # Ignore messages sent by bots
        if event.message.author.bot:
            return

        if rdb.sismember('ignored_channels', event.message.channel_id):
            return

        # If this is message for a guild, grab the guild object
        if hasattr(event, 'guild') and event.guild:
            guild_id = event.guild.id
        elif hasattr(event, 'guild_id') and event.guild_id:
            guild_id = event.guild_id
        else:
            guild_id = None

        guild = self.guilds.get(event.guild.id) if guild_id else None
        config = guild and guild.get_config()

        # If the guild has configuration, use that (otherwise use defaults)
        if config:
            if config.commands:
                commands = list(self.bot.get_commands_for_message(
                    config.commands.mention,
                    {},
                    config.commands.prefix,
                    event.message))
        elif guild_id:
            # Otherwise, default to requiring mentions
            commands = list(self.bot.get_commands_for_message(True, {}, '', event.message))
        else:
            if ENV != 'prod':
                if not event.message.content.startswith(ENV + '!'):
                    return
                event.message.content = event.message.content[len(ENV) + 1:]

            # DM's just use the commands (no prefix/mention)
            commands = list(self.bot.get_commands_for_message(False, {}, '', event.message))

        # If we didn't find any matching commands, return
        if not len(commands):
            return

        user_level = self.get_level(event.guild, event.author) if event.guild else 0

        # Grab whether this user is a global admin
        # TODO: cache this
        global_admin = rdb.sismember('global_admins', event.author.id)

        # Iterate over commands and find a match
        for command, match in commands:
            if command.level == -1 and not global_admin:
                continue

            level = command.level

            if guild and not config and command.triggers[0] != 'setup':
                continue
            elif config and config.commands and command.plugin != self:
                overrides = reduce(lambda a, b: a.update(b), list(config.commands.get_command_override(command)))

                if overrides.get('disabled'):
                    continue

                level = overrides.get('level', level)

            if not global_admin and user_level < level:
                continue

            command.plugin.execute(CommandEvent(command, event.message, match))

            # Dispatch the command used modlog event
            if config:
                event.config = getattr(config.plugins, 'modlog', None)
                if not event.config:
                    return

                plugin = self.bot.plugins.get('ModLogPlugin')
                if plugin:
                    plugin.log_action(Actions.COMMAND_USED, event)

            return

    @Plugin.command('setup')
    def command_setup(self, event):
        """
        Setup a new Guild with Rowboat
        """
        if not event.guild:
            return event.msg.reply(':warning: this command can only be used in servers')

        # Make sure we're not already setup
        if event.guild.id in self.guilds:
            return event.msg.reply(':warning: this server is already setup')

        global_admin = rdb.sismember('global_admins', event.author.id)

        # Make sure this is the owner of the server
        if not global_admin:
            if not event.guild.owner_id == event.author.id:
                return event.msg.reply(':warning: only the server owner can setup rowboat')

        # Make sure we have admin perms
        m = event.guild.members.select_one(id=self.state.me.id)
        if not m.permissions.administrator and not global_admin:
            return event.msg.reply(':warning: bot must have the Administrator permission')

        guild = Guild.setup(event.guild)
        self.guilds[event.guild.id] = guild
        event.msg.reply(':ok_hand: successfully loaded configuration')

    '''
    @Plugin.command('help', '<command>')
    def command_help(self, event, command):
        """
        Provides information on a given command.
        """
        for cmd in self.bot.commands:
            if command.lower() in cmd.triggers:
                break
        else:
            event.msg.reply(u"Couldn't find command for `{}`".format(C(command)))
            return

        event.msg.reply(u'Usage: {} {}\nDescription: {}'.format(
            command,
            cmd.raw_args or '',
            cmd.func.__doc__,
        ))
    '''

    @Plugin.command('nuke', '<user:snowflake> <reason:str...>', level=-1)
    def nuke(self, event, user, reason):
        """
        Force ban a user from all rowboat Guilds
        """
        for gid, guild in self.guilds.items():
            try:
                Infraction.ban(
                    self,
                    event,
                    user,
                    reason,
                    guild=self.state.guilds[gid])
            except:
                self.log.exception('Failed to force ban %s in %s', user, gid)

    @Plugin.command('uptime', level=-1)
    def command_uptime(self, event):
        event.msg.reply('Rowboat was started {}'.format(
            humanize.naturaltime(datetime.utcnow() - self.startup)
        ))

    @Plugin.command('source', '<command>', level=-1)
    def command_source(self, event, command=None):
        for cmd in self.bot.commands:
            if command.lower() in cmd.triggers:
                break
        else:
            event.msg.reply(u"Couldn't find command for `{}`".format(C(command)))
            return

        code = cmd.func.__code__
        lines, firstlineno = inspect.getsourcelines(code)

        event.msg.reply('<https://github.com/b1naryth1ef/rowboat/blob/master/{}#L{}-{}>'.format(
            code.co_filename,
            firstlineno,
            firstlineno + len(lines)
        ))

    @Plugin.command('eval', level=-1)
    def command_eval(self, event):
        ctx = {
            'bot': self.bot,
            'client': self.bot.client,
            'state': self.bot.client.state,
            'event': event,
            'msg': event.msg,
            'guild': event.msg.guild,
            'channel': event.msg.channel,
            'author': event.msg.author
        }

        # Mulitline eval
        src = event.codeblock
        if src.count('\n'):
            lines = filter(bool, src.split('\n'))
            if lines[-1] and 'return' not in lines[-1]:
                lines[-1] = 'return ' + lines[-1]
            lines = '\n'.join('    ' + i for i in lines)
            code = 'def f():\n{}\nx = f()'.format(lines)
            local = {}

            try:
                exec compile(code, '<eval>', 'exec') in ctx, local
            except Exception as e:
                event.msg.reply(PY_CODE_BLOCK.format(type(e).__name__ + ': ' + str(e)))
                return

            result = pprint.pformat(local['x'])
        else:
            try:
                result = str(eval(src, ctx))
            except Exception as e:
                event.msg.reply(PY_CODE_BLOCK.format(type(e).__name__ + ': ' + str(e)))
                return

        if len(result) > 1990:
            event.msg.reply('', attachment=('result.txt', result))
        else:
            event.msg.reply(PY_CODE_BLOCK.format(result))
<|endoftext|>


<commit_before># Generated by Django 1.9 on 2016-11-29 11:35

from django.db import migrations

from ..db.fields import JSONField

class Migration(migrations.Migration):

    dependencies = [("elasticsearch_django", "0003_auto_20160926_2021")]

    operations = [
        migrations.AlterField(
            model_name="searchquery",
            name="hits",
            field=JSONField(
                help_text="The list of meta info for each of the query matches returned."
            ),
        ),
        migrations.AlterField(
            model_name="searchquery",
            name="query",
            field=JSONField(help_text="The raw ElasticSearch DSL query."),
        ),
    ]
<commit_msg>Update migration to use native JSONField<commit_after># Generated by Django 1.9 on 2016-11-29 11:35

from django.contrib.postgres.fields import JSONField
from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [("elasticsearch_django", "0003_auto_20160926_2021")]

    operations = [
        migrations.AlterField(
            model_name="searchquery",
            name="hits",
            field=JSONField(
                help_text="The list of meta info for each of the query matches returned."
            ),
        ),
        migrations.AlterField(
            model_name="searchquery",
            name="query",
            field=JSONField(help_text="The raw ElasticSearch DSL query."),
        ),
    ]
<|endoftext|>


<commit_before># coding=utf-8
"""Tests for QGIS functionality.

.. note:: This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

"""

# This file was generated from the QGIS Plugin builder plugin
# See https://github.com/g-sherman/Qgis-Plugin-Builder/

__author__ = 'tim@linfiniti.com'
__date__ = '20/01/2011'
__copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
                 'Disaster Reduction')

import os
import unittest
from qgis.core import (
    QgsProviderRegistry,
    QgsCoordinateReferenceSystem,
    QgsRasterLayer)

from svir.test.utilities import get_qgis_app

QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app()

class QGISTest(unittest.TestCase):
    """Test the QGIS Environment"""

    def test_qgis_environment(self):
        """QGIS environment has the expected providers"""

        r = QgsProviderRegistry.instance()
        self.assertIn('gdal', r.providerList())
        self.assertIn('ogr', r.providerList())
        self.assertIn('postgres', r.providerList())

    def test_projection(self):
        """Test that QGIS properly parses a wkt string.
        """
        crs = QgsCoordinateReferenceSystem()
        wkt = (
            'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",'
            'SPHEROID["WGS_1984",6378137.0,298.257223563]],'
            'PRIMEM["Greenwich",0.0],UNIT["Degree",'
            '0.0174532925199433]]')
        crs.createFromWkt(wkt)
        auth_id = crs.authid()
        expected_auth_id = 'EPSG:4326'
        self.assertEqual(auth_id, expected_auth_id)

        # now test for a loaded layer
        path = os.path.join(os.path.dirname(__file__),
                            os.pardir,
                            'data',
                            'raster',
                            'tenbytenraster.asc')
        title = 'TestRaster'
        layer = QgsRasterLayer(path, title)
        auth_id = layer.crs().authid()
        self.assertEqual(auth_id, expected_auth_id)

if __name__ == '__main__':
    unittest.main()
<commit_msg>Minor improvement in an indentation<commit_after># coding=utf-8
"""Tests for QGIS functionality.

.. note:: This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

"""

# This file was generated from the QGIS Plugin builder plugin
# See https://github.com/g-sherman/Qgis-Plugin-Builder/

__author__ = 'tim@linfiniti.com'
__date__ = '20/01/2011'
__copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
                 'Disaster Reduction')

import os
import unittest
from qgis.core import (
    QgsProviderRegistry,
    QgsCoordinateReferenceSystem,
    QgsRasterLayer)

from svir.test.utilities import get_qgis_app

QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app()

class QGISTest(unittest.TestCase):
    """Test the QGIS Environment"""

    def test_qgis_environment(self):
        """QGIS environment has the expected providers"""

        r = QgsProviderRegistry.instance()
        self.assertIn('gdal', r.providerList())
        self.assertIn('ogr', r.providerList())
        self.assertIn('postgres', r.providerList())

    def test_projection(self):
        """Test that QGIS properly parses a wkt string.
        """
        crs = QgsCoordinateReferenceSystem()
        wkt = (
            'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",'
            'SPHEROID["WGS_1984",6378137.0,298.257223563]],'
            'PRIMEM["Greenwich",0.0],UNIT["Degree",'
            '0.0174532925199433]]')
        crs.createFromWkt(wkt)
        auth_id = crs.authid()
        expected_auth_id = 'EPSG:4326'
        self.assertEqual(auth_id, expected_auth_id)

        # now test for a loaded layer
        path = os.path.join(os.path.dirname(__file__), os.pardir,
                            'data', 'raster', 'tenbytenraster.asc')
        title = 'TestRaster'
        layer = QgsRasterLayer(path, title)
        auth_id = layer.crs().authid()
        self.assertEqual(auth_id, expected_auth_id)

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# #############################################################################
#
# Tech-Receptives Solutions Pvt. Ltd.
# Copyright (C) 2004-TODAY Tech-Receptives(<http://www.techreceptives.com>)
# Special Credit and Thanks to Thymbra Latinoamericana S.A.
#
# This program 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.
#
# 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
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# #############################################################################

from openerp import models, fields, api

class MedicalMedicament(models.Model):
    _name = 'medical.medicament'
    _inherit = ['mail.thread']
    _inherits = {'product.product': 'product_id'}

    @api.multi
    def onchange_type(self, _type):
        return self.product_id.onchange_type(_type)

    @api.multi
    def onchange_uom(self, uom_id, uom_po_id):
        return self.product_id.onchange_uom(uom_id, uom_po_id)

    @api.multi
    def name_get(self):
        res = []
        for rec in self:
            name = '%s - %s' % (self.product_id.name, self.drug_form_id.name)
            res.append((rec.id, name))
        return res

    product_id = fields.Many2one(
        comodel_name='product.product', required=True, ondelete="cascade")
    drug_form_id = fields.Many2one(
        comodel_name='medical.drug.form', string='Drug Form', required=True)
    drug_route_id = fields.Many2one(
        comodel_name='medical.drug.route', string='Drug Route')
    active_component = fields.Char()
    indications = fields.Text()
    therapeutic_action = fields.Char()
    pregnancy_category = fields.Selection([
            ('a', 'A'),
            ('b', 'B'),
            ('c', 'C'),
            ('d', 'D'),
            ('x', 'X'),
            ('n', 'N'),
        ], help='** FDA Pregancy Categories ***\n'
                 'CATEGORY A :Adequate and well-controlled human studies have'
                 'failed to demonstrate a risk to the fetus in the first'
                 'trimester of pregnancy (and there is no evidence of risk in '
                 'later trimesters).\n\n'
                 'CATEGORY B : Animal reproduction studies have failed to '
                 'demonstrate a risk to the fetus and there are no adequate '
                 'and well-controlled studies in pregnant women OR Animal '
                 'studies have shown an adverse effect, but adequate and '
                 'well-controlled studies in pregnant women'
                 ' have failed to demonstrate a risk to the fetus in any'
                 ' trimester.\n\n'
                 'CATEGORY C : Animal reproduction studies have shown an '
                 'adverse effect on the fetus and there are no adequate and '
                 'well-controlled  studies in humans, but potential benefits '
                 'may warrant use of the drug in pregnant women despite '
                 'potential risks. \n\n '
                 'CATEGORY D : There is positive evidence of human fetal '
                 'risk based on adverse reaction data from investigational '
                 'or marketing experience or studies in humans, but potential '
                 'benefits may warrant use of the drug in pregnant women '
                 'despite potential risks.\n\n'
                 'CATEGORY X : Studies in animals or humans have demonstrated '
                 'fetal abnormalities and/or there is positive evidence of '
                 'human fetal risk based on adverse reaction data from '
                 'investigational or marketing experience, and the risks '
                 'involved in use of the drug in pregnant'
                 ' women clearly outweigh potential benefits.\n\n'
                 'CATEGORY N : Not yet classified')
    is_pregnant = fields.Boolean(
        string='Pregnancy Warning',
        help='The drug represents risk to pregnancy or lactancy')
    dosage_instruction = fields.Text(
        string='Dosage Instructions')
    pregnancy = fields.Text(
        string='Pregnancy and Lactancy')
    notes = fields.Text()
    overdosage = fields.Text()
    storage = fields.Text()
    adverse_reaction = fields.Text()
    presentation = fields.Text()
    composition = fields.Text()

    @api.model
    @api.returns('self', lambda value: value.id)
    def create(self, vals):
        vals['is_medicament'] = True
        return super(MedicalMedicament, self).create(vals)
<commit_msg>[CHG] flake8<commit_after># -*- coding: utf-8 -*-
# #############################################################################
#
# Tech-Receptives Solutions Pvt. Ltd.
# Copyright (C) 2004-TODAY Tech-Receptives(<http://www.techreceptives.com>)
# Special Credit and Thanks to Thymbra Latinoamericana S.A.
#
# This program 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.
#
# 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
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# #############################################################################

from openerp import models, fields, api

class MedicalMedicament(models.Model):
    _name = 'medical.medicament'
    _inherit = ['mail.thread']
    _inherits = {'product.product': 'product_id'}

    @api.multi
    def onchange_type(self, _type):
        return self.product_id.onchange_type(_type)

    @api.multi
    def onchange_uom(self, uom_id, uom_po_id):
        return self.product_id.onchange_uom(uom_id, uom_po_id)

    @api.multi
    def name_get(self):
        res = []
        for rec in self:
            name = '%s - %s' % (self.product_id.name, self.drug_form_id.name)
            res.append((rec.id, name))
        return res

    product_id = fields.Many2one(
        comodel_name='product.product', required=True, ondelete="cascade")
    drug_form_id = fields.Many2one(
        comodel_name='medical.drug.form', string='Drug Form', required=True)
    drug_route_id = fields.Many2one(
        comodel_name='medical.drug.route', string='Drug Route')
    active_component = fields.Char()
    indications = fields.Text()
    therapeutic_action = fields.Char()
    pregnancy_category = fields.Selection([
        ('a', 'A'),
        ('b', 'B'),
        ('c', 'C'),
        ('d', 'D'),
        ('x', 'X'),
        ('n', 'N'),
    ], help='** FDA Pregancy Categories ***\n'
        'CATEGORY A :Adequate and well-controlled human studies have'
        'failed to demonstrate a risk to the fetus in the first'
        'trimester of pregnancy (and there is no evidence of risk in '
        'later trimesters).\n\n'
        'CATEGORY B : Animal reproduction studies have failed to '
        'demonstrate a risk to the fetus and there are no adequate '
        'and well-controlled studies in pregnant women OR Animal '
        'studies have shown an adverse effect, but adequate and '
        'well-controlled studies in pregnant women'
        ' have failed to demonstrate a risk to the fetus in any'
        ' trimester.\n\n'
        'CATEGORY C : Animal reproduction studies have shown an '
        'adverse effect on the fetus and there are no adequate and '
        'well-controlled  studies in humans, but potential benefits '
        'may warrant use of the drug in pregnant women despite '
        'potential risks. \n\n '
        'CATEGORY D : There is positive evidence of human fetal '
        'risk based on adverse reaction data from investigational '
        'or marketing experience or studies in humans, but potential '
        'benefits may warrant use of the drug in pregnant women '
        'despite potential risks.\n\n'
        'CATEGORY X : Studies in animals or humans have demonstrated '
        'fetal abnormalities and/or there is positive evidence of '
        'human fetal risk based on adverse reaction data from '
        'investigational or marketing experience, and the risks '
        'involved in use of the drug in pregnant'
        ' women clearly outweigh potential benefits.\n\n'
        'CATEGORY N : Not yet classified')
    is_pregnant = fields.Boolean(
        string='Pregnancy Warning',
        help='The drug represents risk to pregnancy or lactancy')
    dosage_instruction = fields.Text(
        string='Dosage Instructions')
    pregnancy = fields.Text(
        string='Pregnancy and Lactancy')
    notes = fields.Text()
    overdosage = fields.Text()
    storage = fields.Text()
    adverse_reaction = fields.Text()
    presentation = fields.Text()
    composition = fields.Text()

    @api.model
    @api.returns('self', lambda value: value.id)
    def create(self, vals):
        vals['is_medicament'] = True
        return super(MedicalMedicament, self).create(vals)
<|endoftext|>


<commit_before>#
# Sublime Text 2 SimpleSync plugin
#
# Help the orphans, street children, disadvantaged people
#   and physically handicapped in Vietnam (http://bit.ly/LPgJ1m)
#
# @copyright (c) 2012 Tan Nhu, tnhu AT me . COM
# @version 0.0.1
# @licence MIT
# @link https://github.com/tnhu/SimpleSync
#
import sublime
import sublime_plugin
import subprocess
import threading

#
# Run a process
# @param cmd process command
#
def runProcess(cmd):
  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

  while (True):
    retcode = p.poll()             #returns None while subprocess is running
    line    = p.stdout.readline()
    yield line

    if (retcode is not None):
      break

# Populate settings
settings = sublime.load_settings("SimpleSync.sublime-settings")
sync     = settings.get("sync")

#
# Get sync item(s) for a file
# @param local_file full path of a local file
# @return sync item(s)
#
def getSyncItem(local_file):
  ret = []

  for item in sync:
    if local_file.startswith(item["local"]):
      ret += [item]

  return ret

#
# ScpCopier does actual copying using threading to avoid UI blocking
#
class ScpCopier(threading.Thread):
  def __init__(self, host, username, local_file, remote_file, port=21):
    self.host        = host
    self.port        = port
    self.username    = username
    self.local_file  = local_file
    self.remote_file = remote_file

    threading.Thread.__init__(self)

  def run(self):
    remote  = self.username + "@" + self.host + ":" + self.remote_file

    print "SimpleSync: ", self.local_file, " -> ", self.remote_file

    for line in runProcess(["scp", "-r", "-P", str(self.port) , self.local_file, remote]):
      print line,

#
# LocalCopier does local copying using threading to avoid UI blocking
#
class LocalCopier(threading.Thread):
  def __init__(self, local_file, remote_file):
    self.local_file  = local_file
    self.remote_file = remote_file
    threading.Thread.__init__(self)

  def run(self):
    print "SimpleSync: ", self.local_file, " -> ", self.remote_file

    for line in runProcess(['cp', self.local_file, self.remote_file]):
      print line,

#
# Subclass sublime_plugin.EventListener
#
class SimpleSync(sublime_plugin.EventListener):
  def on_post_save(self, view):
    local_file = view.file_name()
    syncItems  = getSyncItem(local_file)

    if (len(syncItems) > 0):
      for item in syncItems:
        remote_file = local_file.replace(item["local"], item["remote"])

        if (item["type"] == "ssh"):
          ScpCopier(item["host"], item["username"], local_file, remote_file, port=item["port"]).start()
        elif (item["type"] == "local"):
          LocalCopier(local_file, remote_file).start()<commit_msg>default port 22<commit_after>#
# Sublime Text 2 SimpleSync plugin
#
# Help the orphans, street children, disadvantaged people
#   and physically handicapped in Vietnam (http://bit.ly/LPgJ1m)
#
# @copyright (c) 2012 Tan Nhu, tnhu AT me . COM
# @version 0.0.1
# @licence MIT
# @link https://github.com/tnhu/SimpleSync
#
import sublime
import sublime_plugin
import subprocess
import threading

#
# Run a process
# @param cmd process command
#
def runProcess(cmd):
  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

  while (True):
    retcode = p.poll()             #returns None while subprocess is running
    line    = p.stdout.readline()
    yield line

    if (retcode is not None):
      break

# Populate settings
settings = sublime.load_settings("SimpleSync.sublime-settings")
sync     = settings.get("sync")

#
# Get sync item(s) for a file
# @param local_file full path of a local file
# @return sync item(s)
#
def getSyncItem(local_file):
  ret = []

  for item in sync:
    if local_file.startswith(item["local"]):
      ret += [item]

  return ret

#
# ScpCopier does actual copying using threading to avoid UI blocking
#
class ScpCopier(threading.Thread):
  def __init__(self, host, username, local_file, remote_file, port=22):
    self.host        = host
    self.port        = port
    self.username    = username
    self.local_file  = local_file
    self.remote_file = remote_file

    threading.Thread.__init__(self)

  def run(self):
    remote  = self.username + "@" + self.host + ":" + self.remote_file

    print "SimpleSync: ", self.local_file, " -> ", self.remote_file

    for line in runProcess(["scp", "-r", "-P", str(self.port) , self.local_file, remote]):
      print line,

#
# LocalCopier does local copying using threading to avoid UI blocking
#
class LocalCopier(threading.Thread):
  def __init__(self, local_file, remote_file):
    self.local_file  = local_file
    self.remote_file = remote_file
    threading.Thread.__init__(self)

  def run(self):
    print "SimpleSync: ", self.local_file, " -> ", self.remote_file

    for line in runProcess(['cp', self.local_file, self.remote_file]):
      print line,

#
# Subclass sublime_plugin.EventListener
#
class SimpleSync(sublime_plugin.EventListener):
  def on_post_save(self, view):
    local_file = view.file_name()
    syncItems  = getSyncItem(local_file)

    if (len(syncItems) > 0):
      for item in syncItems:
        remote_file = local_file.replace(item["local"], item["remote"])

        if (item["type"] == "ssh"):
          ScpCopier(item["host"], item["username"], local_file, remote_file, port=item["port"]).start()
        elif (item["type"] == "local"):
          LocalCopier(local_file, remote_file).start()<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Windows color look-up tables and functions."""

from colorise.attributes import Attr
from colorise.color_tools import closest_color
from colorise.win.win32_functions import\
    can_interpret_ansi,\
    can_redefine_colors,\
    get_windows_clut
import colorise.nix.cluts

# Character attributes as defined in wincon.h
# We cannot get these through ctypes since they are #defines
_WIN_ATTRIBUTES = {
        Attr.Reset:     0x0000,
        Attr.Bold:      0x0008,
        Attr.Intense:   0x0008,  # Alias
        Attr.Faint:     0x0000,
        Attr.Italic:    0x0000,
        Attr.Underline: 0x8000,
        Attr.Blink:     0x0000,
        Attr.Reverse:   0x4000,
    }

if can_redefine_colors():
    _WINDOWS_CLUT = get_windows_clut()
else:
    # Windows 16-color (logical) look-up table
    _WINDOWS_CLUT = {
        0:  (0x00, 0x00, 0x00),  # Black
        1:  (0x00, 0x00, 0x80),  # Red
        2:  (0x00, 0x80, 0x00),  # Green
        3:  (0x00, 0x80, 0x80),  # Yellow
        4:  (0x80, 0x00, 0x00),  # Magenta
        5:  (0x80, 0x00, 0x80),  # Blue
        6:  (0x80, 0x80, 0x00),  # Cyan
        7:  (0xff, 0xff, 0xff),  # White
        8:  (0x80, 0x80, 0x80),  # Gray/intensity
        # The remaining colors are sometimes referred to as the 'light' colors
        9:  (0x00, 0x00, 0xff),  # Light blue
        10: (0x00, 0xff, 0x00),  # Light green
        11: (0x00, 0xff, 0xff),  # Light cyan
        12: (0xff, 0x00, 0x00),  # Light red
        13: (0xff, 0x00, 0xff),  # Light purple
        14: (0xff, 0xff, 0x00),  # Light yellow
        15: (0xff, 0xff, 0xff)   # Light white
    }

_FOREGROUND_RED = 0x0004
_FOREGROUND_GREEN = 0x0002
_FOREGROUND_BLUE = 0x0001
_FOREGROUND_INTENSITY = _WIN_ATTRIBUTES[Attr.Bold]

# List of logical colors names on Windows (as defined by colorise)
_WINDOWS_LOGICAL_NAMES = {
    'black':   0,
    'red':     _FOREGROUND_RED,
    'green':   _FOREGROUND_GREEN,
    'yellow':  _FOREGROUND_RED | _FOREGROUND_GREEN,
    'magenta': _FOREGROUND_RED | _FOREGROUND_BLUE,
    'purple':  _FOREGROUND_RED | _FOREGROUND_BLUE,
    'blue':    _FOREGROUND_BLUE,
    'cyan':    _FOREGROUND_GREEN | _FOREGROUND_BLUE,
    'white':   _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE |
               _FOREGROUND_INTENSITY,
}

for name in ['red', 'green', 'blue', 'yellow', 'purple', 'magenta', 'cyan']:
    _WINDOWS_LOGICAL_NAMES['light' + name] =\
        _WINDOWS_LOGICAL_NAMES[name] | _FOREGROUND_INTENSITY

_WINDOWS_LOGICAL_NAMES['gray'] = _WINDOWS_LOGICAL_NAMES['black'] |\
    _FOREGROUND_INTENSITY
_WINDOWS_LOGICAL_NAMES['grey'] = _WINDOWS_LOGICAL_NAMES['black'] |\
    _FOREGROUND_INTENSITY
_WINDOWS_LOGICAL_NAMES['lightgrey'] = _FOREGROUND_RED | _FOREGROUND_GREEN |\
    _FOREGROUND_BLUE
_WINDOWS_LOGICAL_NAMES['lightgray'] = _WINDOWS_LOGICAL_NAMES['lightgrey']

def get_clut(color_count):
    """Return the appropriate color look-up table."""
    return _WINDOWS_CLUT

def to_codes(bg, color, attributes):
    """Convert a set of attributes to Windows character attributes."""
    codes = [color] + [_WIN_ATTRIBUTES[attr] for attr in attributes]

    if bg:
        return [code << 4 for code in codes]

    return codes

def color_from_name(name, color_count, bg, attributes):
    """Return the color value and color count for a given color name."""
    if name not in _WINDOWS_LOGICAL_NAMES:
        raise ValueError("Unknown color name '{0}'".format(name))

    return to_codes(bg, _WINDOWS_LOGICAL_NAMES[name], attributes)

def color_from_index(idx, color_count, bg, attributes):
    """Return the color value and color count for a given color index."""
    if can_interpret_ansi():
        # We can interpret ANSI escape sequences, delegate to nix function
        return colorise.nix.cluts.color_from_index(idx, color_count, bg,
                                                   attributes)

    if idx < 0 or idx > 255:
        raise ValueError('Color index must be in range 0-255 inclusive')

    if idx < 16:
        color = closest_color(
            colorise.nix.cluts._NIX_SYSTEM_COLORS,
            _WINDOWS_CLUT
        )
    elif idx < 88:
        # 88 color index
        color = closest_color(
            colorise.nix.cluts._XTERM_CLUT_88[idx],
            _WINDOWS_CLUT
        )
    elif idx < 256:
        # 256 color index
        color = closest_color(
            colorise.nix.cluts._XTERM_CLUT_256[idx],
            _WINDOWS_CLUT
        )

    return to_codes(bg, color, attributes)

def get_rgb_color(color_count, bg, rgb, attributes):
    """Get the color for an RGB triple or approximate it if necessary."""
    if color_count == 2**24:
        # We have true-color capabilities, delegate to nix function
        # approximate to closest color given current capabilities
        return colorise.nix.cluts.get_rgb_color(color_count, bg, rgb,
                                                attributes)

    # No true-color capabilities, approximate the rgb color
    idx = closest_color(rgb, get_clut(color_count))

    return to_codes(bg, idx, attributes)
<commit_msg>Get windows clut anew if colors can be redefined<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Windows color look-up tables and functions."""

from colorise.attributes import Attr
from colorise.color_tools import closest_color
from colorise.win.win32_functions import\
    can_interpret_ansi,\
    can_redefine_colors,\
    get_windows_clut
import colorise.nix.cluts

# Character attributes as defined in wincon.h
# We cannot get these through ctypes since they are #defines
_WIN_ATTRIBUTES = {
        Attr.Reset:     0x0000,
        Attr.Bold:      0x0008,
        Attr.Intense:   0x0008,  # Alias
        Attr.Faint:     0x0000,
        Attr.Italic:    0x0000,
        Attr.Underline: 0x8000,
        Attr.Blink:     0x0000,
        Attr.Reverse:   0x4000,
    }

# Windows 16-color (logical) look-up table
_WINDOWS_CLUT = {
    0:  (0x00, 0x00, 0x00),  # Black
    1:  (0x00, 0x00, 0x80),  # Red
    2:  (0x00, 0x80, 0x00),  # Green
    3:  (0x00, 0x80, 0x80),  # Yellow
    4:  (0x80, 0x00, 0x00),  # Magenta
    5:  (0x80, 0x00, 0x80),  # Blue
    6:  (0x80, 0x80, 0x00),  # Cyan
    7:  (0xff, 0xff, 0xff),  # White
    8:  (0x80, 0x80, 0x80),  # Gray/intensity
    # The remaining colors are sometimes referred to as the 'light' colors
    9:  (0x00, 0x00, 0xff),  # Light blue
    10: (0x00, 0xff, 0x00),  # Light green
    11: (0x00, 0xff, 0xff),  # Light cyan
    12: (0xff, 0x00, 0x00),  # Light red
    13: (0xff, 0x00, 0xff),  # Light purple
    14: (0xff, 0xff, 0x00),  # Light yellow
    15: (0xff, 0xff, 0xff)   # Light white
}

_FOREGROUND_RED = 0x0004
_FOREGROUND_GREEN = 0x0002
_FOREGROUND_BLUE = 0x0001
_FOREGROUND_INTENSITY = _WIN_ATTRIBUTES[Attr.Bold]

# List of logical colors names on Windows (as defined by colorise)
_WINDOWS_LOGICAL_NAMES = {
    'black':   0,
    'red':     _FOREGROUND_RED,
    'green':   _FOREGROUND_GREEN,
    'yellow':  _FOREGROUND_RED | _FOREGROUND_GREEN,
    'magenta': _FOREGROUND_RED | _FOREGROUND_BLUE,
    'purple':  _FOREGROUND_RED | _FOREGROUND_BLUE,
    'blue':    _FOREGROUND_BLUE,
    'cyan':    _FOREGROUND_GREEN | _FOREGROUND_BLUE,
    'white':   _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE |
               _FOREGROUND_INTENSITY,
}

for name in ['red', 'green', 'blue', 'yellow', 'purple', 'magenta', 'cyan']:
    _WINDOWS_LOGICAL_NAMES['light' + name] =\
        _WINDOWS_LOGICAL_NAMES[name] | _FOREGROUND_INTENSITY

_WINDOWS_LOGICAL_NAMES['gray'] = _WINDOWS_LOGICAL_NAMES['black'] |\
    _FOREGROUND_INTENSITY
_WINDOWS_LOGICAL_NAMES['grey'] = _WINDOWS_LOGICAL_NAMES['black'] |\
    _FOREGROUND_INTENSITY
_WINDOWS_LOGICAL_NAMES['lightgrey'] = _FOREGROUND_RED | _FOREGROUND_GREEN |\
    _FOREGROUND_BLUE
_WINDOWS_LOGICAL_NAMES['lightgray'] = _WINDOWS_LOGICAL_NAMES['lightgrey']

def get_clut(color_count):
    """Return the appropriate color look-up table."""
    if can_redefine_colors():
        return get_windows_clut()

    return _WINDOWS_CLUT

def to_codes(bg, color, attributes):
    """Convert a set of attributes to Windows character attributes."""
    codes = [color] + [_WIN_ATTRIBUTES[attr] for attr in attributes]

    if bg:
        return [code << 4 for code in codes]

    return codes

def color_from_name(name, color_count, bg, attributes):
    """Return the color value and color count for a given color name."""
    if name not in _WINDOWS_LOGICAL_NAMES:
        raise ValueError("Unknown color name '{0}'".format(name))

    return to_codes(bg, _WINDOWS_LOGICAL_NAMES[name], attributes)

def color_from_index(idx, color_count, bg, attributes):
    """Return the color value and color count for a given color index."""
    if can_interpret_ansi():
        # We can interpret ANSI escape sequences, delegate to nix function
        return colorise.nix.cluts.color_from_index(idx, color_count, bg,
                                                   attributes)

    if idx < 0 or idx > 255:
        raise ValueError('Color index must be in range 0-255 inclusive')

    if idx < 16:
        color = closest_color(
            colorise.nix.cluts._NIX_SYSTEM_COLORS,
            _WINDOWS_CLUT
        )
    elif idx < 88:
        # 88 color index
        color = closest_color(
            colorise.nix.cluts._XTERM_CLUT_88[idx],
            _WINDOWS_CLUT
        )
    elif idx < 256:
        # 256 color index
        color = closest_color(
            colorise.nix.cluts._XTERM_CLUT_256[idx],
            _WINDOWS_CLUT
        )

    return to_codes(bg, color, attributes)

def get_rgb_color(color_count, bg, rgb, attributes):
    """Get the color for an RGB triple or approximate it if necessary."""
    if color_count == 2**24:
        # We have true-color capabilities, delegate to nix function
        # approximate to closest color given current capabilities
        return colorise.nix.cluts.get_rgb_color(color_count, bg, rgb,
                                                attributes)

    # No true-color capabilities, approximate the rgb color
    idx = closest_color(rgb, get_clut(color_count))

    return to_codes(bg, idx, attributes)
<|endoftext|>


<commit_before># coding: utf-8
from django.test import TestCase
from datetime import datetime, date
from datetime import timedelta
from regressiontests.views.models import Article, Author, DateArticle

class ObjectDetailTest(TestCase):
    fixtures = ['testdata.json']
    def setUp(self):
        # Correct the date for the current article
        current_article = Article.objects.get(title="Current Article")
        current_article.date_created = datetime.now()
        current_article.save()

    def test_finds_past(self):
        "date_based.object_detail can view a page in the past"
        response = self.client.get('/views/date_based/object_detail/2001/01/01/old_article/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object'].title, "Old Article")

    def test_object_detail_finds_today(self):
        "date_based.object_detail can view a page from today"
        today_url = datetime.now().strftime('%Y/%m/%d')
        response = self.client.get('/views/date_based/object_detail/%s/current_article/' % today_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object'].title, "Current Article")

    def test_object_detail_ignores_future(self):
        "date_based.object_detail can view a page from the future, but only if allowed."
        response = self.client.get('/views/date_based/object_detail/3000/01/01/future_article/')
        self.assertEqual(response.status_code, 404)

    def test_object_detail_allowed_future_if_enabled(self):
        "date_based.object_detail can view a page from the future if explicitly allowed."
        response = self.client.get('/views/date_based/object_detail/3000/01/01/future_article/allow_future/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object'].title, "Future Article")

class MonthArchiveTest(TestCase):
    def test_archive_month_includes_only_month(self):
        "Regression for #3031: Archives around Feburary include only one month"
        author = Author(name="John Smith")
        author.save()

        # 2004 was a leap year, so it should be weird enough to not cheat
        first_second_of_feb = datetime(2004, 2, 1, 0, 0, 1)
        first_second_of_mar = datetime(2004, 3, 1, 0, 0, 1)
        two_seconds = timedelta(0, 2, 0)
        article = Article(title="example", author=author)

        article.date_created = first_second_of_feb
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article.date_created = first_second_of_feb-two_seconds
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        article.date_created = first_second_of_mar-two_seconds
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article.date_created = first_second_of_mar
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        article2 = DateArticle(title="example", author=author)

        article2.date_created = first_second_of_feb.date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article2.date_created = (first_second_of_feb-two_seconds).date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        article2.date_created = (first_second_of_mar-two_seconds).date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article2.date_created = first_second_of_mar.date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        now = datetime.now()
        prev_month = now.date().replace(day=1)
        if prev_month.month == 11:
            prev_month = prev_month.replace(year=prev_month.year-1, month=12)
        else:
            prev_month = prev_month.replace(month=prev_month.month-1)
        article2.date_created = now
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/%s/' % now.strftime('%Y/%m'))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], None)
        self.assertEqual(response.context['previous_month'], prev_month)

class DayArchiveTests(TestCase):

    def test_year_month_day_format(self):
        """
        Make sure day views don't get confused with numeric month formats (#7944)
        """
        author = Author.objects.create(name="John Smith")
        article = Article.objects.create(title="example", author=author, date_created=datetime(2004, 1, 21, 0, 0, 1))
        response = self.client.get('/views/date_based/archive_day/2004/1/21/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object_list'][0], article)<commit_msg>Fixed #12125 -- Fixed a typo in the generic views date_based test that caused it to fail in November.  Thanks brutasse. --This line and those below, will be ignored--<commit_after># coding: utf-8
from django.test import TestCase
from datetime import datetime, date
from datetime import timedelta
from regressiontests.views.models import Article, Author, DateArticle

class ObjectDetailTest(TestCase):
    fixtures = ['testdata.json']
    def setUp(self):
        # Correct the date for the current article
        current_article = Article.objects.get(title="Current Article")
        current_article.date_created = datetime.now()
        current_article.save()

    def test_finds_past(self):
        "date_based.object_detail can view a page in the past"
        response = self.client.get('/views/date_based/object_detail/2001/01/01/old_article/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object'].title, "Old Article")

    def test_object_detail_finds_today(self):
        "date_based.object_detail can view a page from today"
        today_url = datetime.now().strftime('%Y/%m/%d')
        response = self.client.get('/views/date_based/object_detail/%s/current_article/' % today_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object'].title, "Current Article")

    def test_object_detail_ignores_future(self):
        "date_based.object_detail can view a page from the future, but only if allowed."
        response = self.client.get('/views/date_based/object_detail/3000/01/01/future_article/')
        self.assertEqual(response.status_code, 404)

    def test_object_detail_allowed_future_if_enabled(self):
        "date_based.object_detail can view a page from the future if explicitly allowed."
        response = self.client.get('/views/date_based/object_detail/3000/01/01/future_article/allow_future/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object'].title, "Future Article")

class MonthArchiveTest(TestCase):
    def test_archive_month_includes_only_month(self):
        "Regression for #3031: Archives around Feburary include only one month"
        author = Author(name="John Smith")
        author.save()

        # 2004 was a leap year, so it should be weird enough to not cheat
        first_second_of_feb = datetime(2004, 2, 1, 0, 0, 1)
        first_second_of_mar = datetime(2004, 3, 1, 0, 0, 1)
        two_seconds = timedelta(0, 2, 0)
        article = Article(title="example", author=author)

        article.date_created = first_second_of_feb
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article.date_created = first_second_of_feb-two_seconds
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        article.date_created = first_second_of_mar-two_seconds
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article.date_created = first_second_of_mar
        article.save()
        response = self.client.get('/views/date_based/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        article2 = DateArticle(title="example", author=author)

        article2.date_created = first_second_of_feb.date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article2.date_created = (first_second_of_feb-two_seconds).date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        article2.date_created = (first_second_of_mar-two_seconds).date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], date(2004, 3, 1))
        self.assertEqual(response.context['previous_month'], date(2004, 1, 1))

        article2.date_created = first_second_of_mar.date()
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/2004/02/')
        self.assertEqual(response.status_code, 404)

        now = datetime.now()
        prev_month = now.date().replace(day=1)
        if prev_month.month == 1:
            prev_month = prev_month.replace(year=prev_month.year-1, month=12)
        else:
            prev_month = prev_month.replace(month=prev_month.month-1)
        article2.date_created = now
        article2.save()
        response = self.client.get('/views/date_based/datefield/archive_month/%s/' % now.strftime('%Y/%m'))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['next_month'], None)
        self.assertEqual(response.context['previous_month'], prev_month)

class DayArchiveTests(TestCase):

    def test_year_month_day_format(self):
        """
        Make sure day views don't get confused with numeric month formats (#7944)
        """
        author = Author.objects.create(name="John Smith")
        article = Article.objects.create(title="example", author=author, date_created=datetime(2004, 1, 21, 0, 0, 1))
        response = self.client.get('/views/date_based/archive_day/2004/1/21/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.context['object_list'][0], article)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
from dolfin import (
    dx, ds, dot, grad, pi, assemble, lhs, rhs, SpatialCoordinate,
    TrialFunction, TestFunction, KrylovSolver, Function, assemble_system,
    LUSolver
    )

def F(u, v, kappa, rho, cp,
      convection,
      source,
      r,
      neumann_bcs,
      robin_bcs,
      my_dx,
      my_ds
      ):
    '''
    Compute

    .. math::

        F(u) =
            \\int_\\Omega \\kappa r
                \\langle\\nabla(u), \\nabla(v/\\rho, c_p)\\rangle
                \\times 2\\pi \\, \\text{d}x
            + \\int_\\Omega \\langle c, \\nabla(u)\\rangle v
                \\times 2\\pi r\\,\\text{d}x
            - \\int_\\Omega \\frac{1}{\\rho c_p} f v
                \\times 2\\pi r \\,\\text{d}x\\\\
            - \\int_\\Gamma r \\kappa * \\langlen,\\nabla(T)\\rangle v
                \\frac{1}{\\rho c_p} \\times 2\\pi \\,\\text{d}s
            - \\int_\\Gamma  r \\kappa  \\alpha (u - u_0) v
                \\frac{1}{\\rho c_p} \\times 2\\pi \\,\\text{d}s

    or its inverse with Dirichlet conditions. Used for time-stepping

    .. math::

        u' = F(u).
    '''
    rho_cp = rho * cp

    F0 = kappa * r * dot(grad(u), grad(v / rho_cp)) * 2*pi * my_dx

    # F -= dot(b, grad(u)) * v * 2*pi*r * dx_workpiece(0)
    b = convection
    if b:
        F0 += (b[0] * u.dx(0) + b[1] * u.dx(1)) * v * 2*pi*r * my_dx

    # Joule heat
    F0 -= source * v / rho_cp * 2*pi*r * my_dx

    # Neumann boundary conditions
    for k, n_grad_T in neumann_bcs.items():
        F0 -= r * kappa * n_grad_T * v / rho_cp * 2*pi * my_ds(k)

    # Robin boundary conditions
    for k, value in robin_bcs.items():
        alpha, u0 = value
        F0 -= r * kappa * alpha * (u - u0) * v / rho_cp * 2*pi * my_ds(k)

    # # Add SUPG stabilization.
    # rho_cp = rho[wpi](background_temp)*cp[wpi]
    # k = kappa[wpi](background_temp)
    # Rdx = u_t * 2*pi*r*dx(wpi) \
    #     + dot(u_1, grad(trial)) * 2*pi*r*dx(wpi) \
    #     - 1.0/(rho_cp) * div(k*r*grad(trial)) * 2*pi*dx(wpi)
    # #F -= dot(tau*u_1, grad(v)) * Rdx
    # #F -= tau * inner(u_1, grad(v)) * 2*pi*r*dx(wpi)
    # #plot(tau, mesh=V.mesh(), title='u_tau')
    # #interactive()
    # #F -= tau * v * 2*pi*r*dx(wpi)
    # #F -= tau * Rdx
    return F0

class Heat(object):
    def __init__(
            self, Q,
            kappa, rho, cp,
            convection,
            source,
            dirichlet_bcs=None,
            neumann_bcs=None,
            robin_bcs=None,
            my_dx=dx,
            my_ds=ds
            ):
        # TODO stabilization
        # About stabilization for reaction-diffusion-convection:
        # http://www.ewi.tudelft.nl/fileadmin/Faculteit/EWI/Over_de_faculteit/Afdelingen/Applied_Mathematics/Rapporten/doc/06-03.pdf
        # http://www.xfem.rwth-aachen.de/Project/PaperDownload/Fries_ReviewStab.pdf
        #
        # R = u_t \
        #     + dot(u0, grad(trial)) \
        #     - 1.0/(rho(293.0)*cp) * div(kappa*grad(trial))
        # F -= R * dot(tau*u0, grad(v)) * dx
        #
        # Stabilization
        # tau = stab.supg2(
        #         mesh,
        #         u0,
        #         kappa/(rho(293.0)*cp),
        #         Q.ufl_element().degree()
        #         )
        super(Heat, self).__init__()
        self.Q = Q

        dirichlet_bcs = dirichlet_bcs or []
        neumann_bcs = neumann_bcs or {}
        robin_bcs = robin_bcs or {}

        self.convection = convection

        u = TrialFunction(Q)
        v = TestFunction(Q)

        # If there are sharp temperature gradients, numerical oscillations may
        # occur. This happens because the resulting matrix is not an M-matrix,
        # caused by the fact that A1 puts positive elements in places other
        # than the main diagonal. To prevent that, it is suggested by
        # Großmann/Roos to use a vertex-centered discretization for the mass
        # matrix part.
        # Check
        # https://bitbucket.org/fenics-project/ffc/issues/145/uflacs-error-for-vertex-quadrature-scheme
        self.M = assemble(
              u * v * dx,
              form_compiler_parameters={
                  'quadrature_rule': 'vertex',
                  'representation': 'quadrature'
                  }
              )

        mesh = Q.mesh()
        r = SpatialCoordinate(mesh)[0]
        self.F0 = F(
                u, v, kappa, rho, cp,
                convection,
                source,
                r,
                neumann_bcs,
                robin_bcs,
                my_dx,
                my_ds
                )

        self.dirichlet_bcs = dirichlet_bcs

        self.A, self.b = assemble_system(-lhs(self.F0), rhs(self.F0))
        return

    # pylint: disable=unused-argument
    def eval_alpha_M_beta_F(self, alpha, beta, u, t):
        '''
        Evaluate  :code:`alpha * M * u + beta * F(u, t)`.
        '''
        uvec = u.vector()
        # Convert to proper `float`s to avoid accidental conversion to
        # numpy.arrays, cf.
        # <https://bitbucket.org/fenics-project/dolfin/issues/874/genericvector-numpyfloat-numpyarray-not>
        alpha = float(alpha)
        beta = float(beta)
        return alpha * (self.M * uvec) + beta * (self.A * uvec + self.b)

    def solve_alpha_M_beta_F(self, alpha, beta, b, t):
        '''
        Solve  :code:`alpha * M * u + beta * F(u, t) = b`  with Dirichlet
        conditions.
        '''
        matrix = alpha * self.M + beta * self.A

        # See above for float conversion
        right_hand_side = - float(beta) * self.b.copy()
        if b:
            right_hand_side += b

        for bc in self.dirichlet_bcs:
            bc.apply(matrix, right_hand_side)

        # TODO proper preconditioner for convection
        if self.convection:
            # Use HYPRE-Euclid instead of ILU for parallel computation.
            # However, this PC sometimes fails.
            # solver = KrylovSolver('gmres', 'hypre_euclid')
            # Fallback:
            solver = LUSolver()
        else:
            solver = KrylovSolver('gmres', 'hypre_amg')
            solver.parameters['relative_tolerance'] = 1.0e-13
            solver.parameters['absolute_tolerance'] = 0.0
            solver.parameters['maximum_iterations'] = 100
            solver.parameters['monitor_convergence'] = True

        solver.set_operator(matrix)

        u = Function(self.Q)
        solver.solve(u.vector(), right_hand_side)
        return u

    def solve_stationary(self):
        return self.solve_alpha_M_beta_F(alpha=0.0, beta=1.0, b=None, t=0.0)
<commit_msg>docstring fixes for heat<commit_after># -*- coding: utf-8 -*-
#
from dolfin import (
    dx, ds, dot, grad, pi, assemble, lhs, rhs, SpatialCoordinate,
    TrialFunction, TestFunction, KrylovSolver, Function, assemble_system,
    LUSolver
    )

def F(u, v, kappa, rho, cp,
      convection,
      source,
      r,
      neumann_bcs,
      robin_bcs,
      my_dx,
      my_ds
      ):
    '''
    Compute

    .. math::

        F(u) =
            \\int_\\Omega \\kappa r
                \\langle\\nabla u, \\nabla \\frac{v}{\\rho c_p}\\rangle
                \\, 2\\pi \\, \\text{d}x
            + \\int_\\Omega \\langle c, \\nabla u\\rangle v
                \\, 2\\pi r\\,\\text{d}x
            - \\int_\\Omega \\frac{1}{\\rho c_p} f v
                \\, 2\\pi r \\,\\text{d}x\\\\
            - \\int_\\Gamma r \\kappa \\langle n, \\nabla T\\rangle v
                \\frac{1}{\\rho c_p} \\m 2\\pi \\,\\text{d}s
            - \\int_\\Gamma  r \\kappa  \\alpha (u - u_0) v
                \\frac{1}{\\rho c_p} \\, 2\\pi \\,\\text{d}s

    Used for time-stepping

    .. math::

        u' = F(u).
    '''
    rho_cp = rho * cp

    F0 = kappa * r * dot(grad(u), grad(v / rho_cp)) * 2*pi * my_dx

    # F -= dot(b, grad(u)) * v * 2*pi*r * dx_workpiece(0)
    b = convection
    if b:
        F0 += (b[0] * u.dx(0) + b[1] * u.dx(1)) * v * 2*pi*r * my_dx

    # Joule heat
    F0 -= source * v / rho_cp * 2*pi*r * my_dx

    # Neumann boundary conditions
    for k, n_grad_T in neumann_bcs.items():
        F0 -= r * kappa * n_grad_T * v / rho_cp * 2*pi * my_ds(k)

    # Robin boundary conditions
    for k, value in robin_bcs.items():
        alpha, u0 = value
        F0 -= r * kappa * alpha * (u - u0) * v / rho_cp * 2*pi * my_ds(k)

    # # Add SUPG stabilization.
    # rho_cp = rho[wpi](background_temp)*cp[wpi]
    # k = kappa[wpi](background_temp)
    # Rdx = u_t * 2*pi*r*dx(wpi) \
    #     + dot(u_1, grad(trial)) * 2*pi*r*dx(wpi) \
    #     - 1.0/(rho_cp) * div(k*r*grad(trial)) * 2*pi*dx(wpi)
    # #F -= dot(tau*u_1, grad(v)) * Rdx
    # #F -= tau * inner(u_1, grad(v)) * 2*pi*r*dx(wpi)
    # #plot(tau, mesh=V.mesh(), title='u_tau')
    # #interactive()
    # #F -= tau * v * 2*pi*r*dx(wpi)
    # #F -= tau * Rdx
    return F0

class Heat(object):
    def __init__(
            self, Q,
            kappa, rho, cp,
            convection,
            source,
            dirichlet_bcs=None,
            neumann_bcs=None,
            robin_bcs=None,
            my_dx=dx,
            my_ds=ds
            ):
        # TODO stabilization
        # About stabilization for reaction-diffusion-convection:
        # http://www.ewi.tudelft.nl/fileadmin/Faculteit/EWI/Over_de_faculteit/Afdelingen/Applied_Mathematics/Rapporten/doc/06-03.pdf
        # http://www.xfem.rwth-aachen.de/Project/PaperDownload/Fries_ReviewStab.pdf
        #
        # R = u_t \
        #     + dot(u0, grad(trial)) \
        #     - 1.0/(rho(293.0)*cp) * div(kappa*grad(trial))
        # F -= R * dot(tau*u0, grad(v)) * dx
        #
        # Stabilization
        # tau = stab.supg2(
        #         mesh,
        #         u0,
        #         kappa/(rho(293.0)*cp),
        #         Q.ufl_element().degree()
        #         )
        super(Heat, self).__init__()
        self.Q = Q

        dirichlet_bcs = dirichlet_bcs or []
        neumann_bcs = neumann_bcs or {}
        robin_bcs = robin_bcs or {}

        self.convection = convection

        u = TrialFunction(Q)
        v = TestFunction(Q)

        # If there are sharp temperature gradients, numerical oscillations may
        # occur. This happens because the resulting matrix is not an M-matrix,
        # caused by the fact that A1 puts positive elements in places other
        # than the main diagonal. To prevent that, it is suggested by
        # Großmann/Roos to use a vertex-centered discretization for the mass
        # matrix part.
        # Check
        # https://bitbucket.org/fenics-project/ffc/issues/145/uflacs-error-for-vertex-quadrature-scheme
        self.M = assemble(
              u * v * dx,
              form_compiler_parameters={
                  'quadrature_rule': 'vertex',
                  'representation': 'quadrature'
                  }
              )

        mesh = Q.mesh()
        r = SpatialCoordinate(mesh)[0]
        self.F0 = F(
                u, v, kappa, rho, cp,
                convection,
                source,
                r,
                neumann_bcs,
                robin_bcs,
                my_dx,
                my_ds
                )

        self.dirichlet_bcs = dirichlet_bcs

        self.A, self.b = assemble_system(-lhs(self.F0), rhs(self.F0))
        return

    # pylint: disable=unused-argument
    def eval_alpha_M_beta_F(self, alpha, beta, u, t):
        '''Evaluate  :code:`alpha * M * u + beta * F(u, t)`.
        '''
        uvec = u.vector()
        # Convert to proper `float`s to avoid accidental conversion to
        # numpy.arrays, cf.
        # <https://bitbucket.org/fenics-project/dolfin/issues/874/genericvector-numpyfloat-numpyarray-not>
        alpha = float(alpha)
        beta = float(beta)
        return alpha * (self.M * uvec) + beta * (self.A * uvec + self.b)

    def solve_alpha_M_beta_F(self, alpha, beta, b, t):
        '''Solve  :code:`alpha * M * u + beta * F(u, t) = b`  with Dirichlet
        conditions.
        '''
        matrix = alpha * self.M + beta * self.A

        # See above for float conversion
        right_hand_side = - float(beta) * self.b.copy()
        if b:
            right_hand_side += b

        for bc in self.dirichlet_bcs:
            bc.apply(matrix, right_hand_side)

        # TODO proper preconditioner for convection
        if self.convection:
            # Use HYPRE-Euclid instead of ILU for parallel computation.
            # However, this PC sometimes fails.
            # solver = KrylovSolver('gmres', 'hypre_euclid')
            # Fallback:
            solver = LUSolver()
        else:
            solver = KrylovSolver('gmres', 'hypre_amg')
            solver.parameters['relative_tolerance'] = 1.0e-13
            solver.parameters['absolute_tolerance'] = 0.0
            solver.parameters['maximum_iterations'] = 100
            solver.parameters['monitor_convergence'] = True

        solver.set_operator(matrix)

        u = Function(self.Q)
        solver.solve(u.vector(), right_hand_side)
        return u

    def solve_stationary(self):
        '''Solve the stationary problem :code:`F(u, t) = 0`  with Dirichlet
        conditions.
        '''
        return self.solve_alpha_M_beta_F(alpha=0.0, beta=1.0, b=None, t=0.0)
<|endoftext|>


<commit_before>from ggame import App, RectangleAsset, ImageAsset, SoundAsset
from ggame import LineStyle, Color, Sprite, Sound

myapp = App()
myapp.run()
<commit_msg>Updated from Brython Server: 10/13/2015 2:16:02 PM<commit_after>"""
Ryan Kynor tutorial
"""

from ggame import App, RectangleAsset, ImageAsset, SoundAsset
from ggame import LineStyle, Color, Sprite, Sound

myapp = App()
myapp.run()
<|endoftext|>