<commit_before>import operator
from phidl.quickplotter import _get_layerprop

def write_lyp(filename, layerset):
    """ Creates a KLayout .lyp Layer Properties file from a set of
    PHIDL layers """
    stipple_default = ['I2','I5','I9','I17','I19','I22','I33','I38']
    stipple_count = 0

    if filename[-4:] != '.lyp': filename = filename + '.lyp'

    # Opening file for writing
    with open('%s' % filename,'w+') as f:

        # Writing header string
        f.write('<?xml version="1.0" encoding="utf-8"?>\n')

        # Writing layer properties opener
        f.write('<layer-properties>\n')

        unsorted_layers = layerset._layers.values()
        sorted_layers = sorted(unsorted_layers, key = operator.attrgetter('gds_layer', 'gds_datatype'))

        for layer in sorted_layers:
            # Extracting information from dictionary layer by layer
            gds_layer = layer.gds_layer
            gds_datatype = layer.gds_datatype
            color = layer.color

            name = '%s/%s - ' % (str(gds_layer), str(gds_datatype)) + layer.name
            if layer.description is not None:
                name = name + ' - ('  + layer.description + ')'

            # Setting stipple or 'dither'
            dither = layer.dither
            if dither is None:
                dither = stipple_default[stipple_count]
                stipple_count = (stipple_count + 1) % len(stipple_default)
            elif dither[0] != 'I':
                raise ValueError("""Stipple must begin with an I""")
            elif int(dither[1:len(dither)]) < 0:
                raise ValueError("""Stipple index cannot be less than 0""")
            elif int(dither[1:len(dither)]) > 46:
                raise ValueError("""Stipple index cannot be greater than 46""")
            else:
                pass

            # Writing properties header for speciic layer
            f.write(' <properties>\n')
            # Writing line to specify frame colour
            f.write('  <frame-color>%s</frame-color>\n' % color)
            # Writing line to specify fill colour
            f.write('  <fill-color>%s</fill-color>\n' % color)
#            # Writing line to specify brightness (value between [-255, 255])
#            f.write('  <frame-brightness>%s</frame-brightness>\n  <fill-brightness>%s</fill-brightness>\n' % (int(brightness), int(brightness)))
            frame_brightness = -25
            f.write('  <frame-brightness>%s</frame-brightness>\n' % (int(frame_brightness)))
            # Writing line to specify dither pattern
            f.write('  <dither-pattern>%s</dither-pattern>\n' % dither)
            # Writing lines to specify line style
            f.write('  <line-style/>\n')
            # Writing line to specify validity
            f.write('  <valid>true</valid>\n')
            # Writing line to specify visibility
            f.write('  <visible>true</visible>\n')
            # Writing line to specify transparency
            f.write('  <transparent>false</transparent>\n')
            # Writing line to specify width
            f.write('  <width/>\n')
            # Writing line to specity markedness
            f.write('  <marked>false</marked>\n')
            # Writing line to specify xfill
            f.write('  <xfill>false</xfill>\n')
            # Writing line to specify animation
            f.write('  <animation>0</animation>\n')
            # Writing line to specify layer name
            f.write('  <name>%s</name>\n' % name)
            # Writing line to specify source
            f.write('  <source>%s/%s@1</source>\n' % (str(gds_layer), str(gds_datatype)))
            # Writing properties closer for specific layer
            f.write(' </properties>\n')

        # Writing layer properties trailer
        f.write('</layer-properties>\n')

def load_lyp(filename):
    ''' Creates a LayerSet object from a lyp file that is XML '''
    try:
        import xmltodict
    except:
        raise ImportError("""This function is in development, and currently requires
            the module "xmltodict" to operate.  Please retry after installing xmltodict
            $ pip install xmltodict """)

    from phidl.device_layout import LayerSet
    if filename[-4:] != '.lyp': filename = filename + '.lyp'
    with open(filename, 'r') as fx:
        lyp_dict = xmltodict.parse(fx.read(), process_namespaces=True)
    # lyp files have a top level that just has one dict: layer-properties
    # That has multiple children 'properties', each for a layer. So it gives a list
    lyp_list = lyp_dict['layer-properties']['properties']
    if not isinstance(lyp_list, list):
        lyp_list = [lyp_list]

    lys = LayerSet()
    def add_entry(entry):
        ''' Entry is a dict of one element of 'properties'.
            No return value. It adds it to the lys variable directly
        '''
        nonlocal lys
        layerInfo = entry['source'].split('@')[0]
        phidl_LayerArgs = dict()
        phidl_LayerArgs['gds_layer'] = int(layerInfo.split('/')[0])
        phidl_LayerArgs['gds_datatype'] = int(layerInfo.split('/')[1])
        phidl_LayerArgs['color'] = entry['fill-color']
        phidl_LayerArgs['dither'] = entry['dither-pattern']
        # These functions are customizable. See below
        phidl_LayerArgs['name'] = name2shortName(entry['name'])
        phidl_LayerArgs['description'] = name2description(entry['name'])
        lys.add_layer(**phidl_LayerArgs)

    for entry in lyp_list:
        try:
            group_members = entry['group-members']
        except KeyError:  # it is a real layer
            add_entry(entry)
        else:  # it is a group of other entries
            if not isinstance(group_members, list):
                group_members = [group_members]
            for member in group_members:
                add_entry(member)
    return lys

def name2shortName(name_str):
    ''' Maps the name entry of the lyp element to a name of the phidl layer,
        i.e. the dictionary key used to access it.
        Default format of the lyp name is
            layer/datatype - phidl_key - description
            or
            phidl_key - description

        Reassign for different layer naming conventions with::

            phidl.utilities.name2shortName = someOtherFunction(string)
    '''
    if name_str is None:
        raise IOError('This layer has no name')
    components = name_str.split(' - ')
    if len(components) > 1:
        short_name = components[1]
    else:
        short_name = components[0]
    return short_name

def name2description(name_str):
    ''' Gets the description of the layer contained in the lyp name field.
        It is not strictly necessary to have a description. If none there, it returns ''.

        Default format of the lyp name is
            layer/datatype - phidl_key - description
            or
            phidl_key - description

        Reassign for different layer naming conventions with::

            phidl.utilities.name2description = someOtherFunction(string)
    '''
    if name_str is None:
        raise IOError('This layer has no name')
    components = name_str.split(' - ')
    description = ''
    if len(components) > 2:
        description = components[2][1:-1]
    return description

def write_svg(D, filename):
    xsize, ysize = D.size
    dcx, dcy = D.center
    dx, dy = dcx-xsize/2, dcy-ysize/2
    group_num = 1
    if filename[-4:] != '.svg':  filename += '.svg'
    with open(filename, 'w+') as f:
        f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
        f.write('<svg width="%0.6f" height="%0.6f">\n' % (xsize, ysize))

        all_polygons = D.get_polygons(by_spec = True)
        for layer, polygons in all_polygons.items():
        #    color = '#800000'
            color = _get_layerprop(layer = layer[0] , datatype = layer[1])['color']
            f.write('  <g id="layer%03i_datatype%03i">\n' % (layer[0], layer[1]))
            group_num += 1

            for polygon in polygons:
                poly_str = '    <path style="fill:%s"\n          d="' % color
                n = 0
                for p in polygon:
                    if n == 0: poly_str+= 'M '
                    else:      poly_str+= 'L '
                    poly_str += '%0.6f %0.6f '  % (p[0]-dx,-(p[1]-dy)+ysize)
                    n += 1
                poly_str+= 'Z"/>\n'
                f.write(poly_str)
            f.write('  </g>\n')

        f.write('</svg>\n')
    return filename<commit_msg>Removing nonlocal variable<commit_after>import operator
from phidl.quickplotter import _get_layerprop

def write_lyp(filename, layerset):
    """ Creates a KLayout .lyp Layer Properties file from a set of
    PHIDL layers """
    stipple_default = ['I2','I5','I9','I17','I19','I22','I33','I38']
    stipple_count = 0

    if filename[-4:] != '.lyp': filename = filename + '.lyp'

    # Opening file for writing
    with open('%s' % filename,'w+') as f:

        # Writing header string
        f.write('<?xml version="1.0" encoding="utf-8"?>\n')

        # Writing layer properties opener
        f.write('<layer-properties>\n')

        unsorted_layers = layerset._layers.values()
        sorted_layers = sorted(unsorted_layers, key = operator.attrgetter('gds_layer', 'gds_datatype'))

        for layer in sorted_layers:
            # Extracting information from dictionary layer by layer
            gds_layer = layer.gds_layer
            gds_datatype = layer.gds_datatype
            color = layer.color

            name = '%s/%s - ' % (str(gds_layer), str(gds_datatype)) + layer.name
            if layer.description is not None:
                name = name + ' - ('  + layer.description + ')'

            # Setting stipple or 'dither'
            dither = layer.dither
            if dither is None:
                dither = stipple_default[stipple_count]
                stipple_count = (stipple_count + 1) % len(stipple_default)
            elif dither[0] != 'I':
                raise ValueError("""Stipple must begin with an I""")
            elif int(dither[1:len(dither)]) < 0:
                raise ValueError("""Stipple index cannot be less than 0""")
            elif int(dither[1:len(dither)]) > 46:
                raise ValueError("""Stipple index cannot be greater than 46""")
            else:
                pass

            # Writing properties header for speciic layer
            f.write(' <properties>\n')
            # Writing line to specify frame colour
            f.write('  <frame-color>%s</frame-color>\n' % color)
            # Writing line to specify fill colour
            f.write('  <fill-color>%s</fill-color>\n' % color)
#            # Writing line to specify brightness (value between [-255, 255])
#            f.write('  <frame-brightness>%s</frame-brightness>\n  <fill-brightness>%s</fill-brightness>\n' % (int(brightness), int(brightness)))
            frame_brightness = -25
            f.write('  <frame-brightness>%s</frame-brightness>\n' % (int(frame_brightness)))
            # Writing line to specify dither pattern
            f.write('  <dither-pattern>%s</dither-pattern>\n' % dither)
            # Writing lines to specify line style
            f.write('  <line-style/>\n')
            # Writing line to specify validity
            f.write('  <valid>true</valid>\n')
            # Writing line to specify visibility
            f.write('  <visible>true</visible>\n')
            # Writing line to specify transparency
            f.write('  <transparent>false</transparent>\n')
            # Writing line to specify width
            f.write('  <width/>\n')
            # Writing line to specity markedness
            f.write('  <marked>false</marked>\n')
            # Writing line to specify xfill
            f.write('  <xfill>false</xfill>\n')
            # Writing line to specify animation
            f.write('  <animation>0</animation>\n')
            # Writing line to specify layer name
            f.write('  <name>%s</name>\n' % name)
            # Writing line to specify source
            f.write('  <source>%s/%s@1</source>\n' % (str(gds_layer), str(gds_datatype)))
            # Writing properties closer for specific layer
            f.write(' </properties>\n')

        # Writing layer properties trailer
        f.write('</layer-properties>\n')

def load_lyp(filename):
    ''' Creates a LayerSet object from a lyp file that is XML '''
    try:
        import xmltodict
    except:
        raise ImportError("""This function is in development, and currently requires
            the module "xmltodict" to operate.  Please retry after installing xmltodict
            $ pip install xmltodict """)

    from phidl.device_layout import LayerSet
    if filename[-4:] != '.lyp': filename = filename + '.lyp'
    with open(filename, 'r') as fx:
        lyp_dict = xmltodict.parse(fx.read(), process_namespaces=True)
    # lyp files have a top level that just has one dict: layer-properties
    # That has multiple children 'properties', each for a layer. So it gives a list
    lyp_list = lyp_dict['layer-properties']['properties']
    if not isinstance(lyp_list, list):
        lyp_list = [lyp_list]

    lys = LayerSet()
    def add_entry(entry, lys):
        ''' Entry is a dict of one element of 'properties'.
            No return value. It adds it to the lys variable directly
        '''
        layerInfo = entry['source'].split('@')[0]
        phidl_LayerArgs = dict()
        phidl_LayerArgs['gds_layer'] = int(layerInfo.split('/')[0])
        phidl_LayerArgs['gds_datatype'] = int(layerInfo.split('/')[1])
        phidl_LayerArgs['color'] = entry['fill-color']
        phidl_LayerArgs['dither'] = entry['dither-pattern']
        # These functions are customizable. See below
        phidl_LayerArgs['name'] = name2shortName(entry['name'])
        phidl_LayerArgs['description'] = name2description(entry['name'])
        lys.add_layer(**phidl_LayerArgs)
        return lys

    for entry in lyp_list:
        try:
            group_members = entry['group-members']
        except KeyError:  # it is a real layer
            add_entry(entry, lys)
        else:  # it is a group of other entries
            if not isinstance(group_members, list):
                group_members = [group_members]
            for member in group_members:
                add_entry(member, lys)
    return lys

def name2shortName(name_str):
    ''' Maps the name entry of the lyp element to a name of the phidl layer,
        i.e. the dictionary key used to access it.
        Default format of the lyp name is
            layer/datatype - phidl_key - description
            or
            phidl_key - description

        Reassign for different layer naming conventions with::

            phidl.utilities.name2shortName = someOtherFunction(string)
    '''
    if name_str is None:
        raise IOError('This layer has no name')
    components = name_str.split(' - ')
    if len(components) > 1:
        short_name = components[1]
    else:
        short_name = components[0]
    return short_name

def name2description(name_str):
    ''' Gets the description of the layer contained in the lyp name field.
        It is not strictly necessary to have a description. If none there, it returns ''.

        Default format of the lyp name is
            layer/datatype - phidl_key - description
            or
            phidl_key - description

        Reassign for different layer naming conventions with::

            phidl.utilities.name2description = someOtherFunction(string)
    '''
    if name_str is None:
        raise IOError('This layer has no name')
    components = name_str.split(' - ')
    description = ''
    if len(components) > 2:
        description = components[2][1:-1]
    return description

def write_svg(D, filename):
    xsize, ysize = D.size
    dcx, dcy = D.center
    dx, dy = dcx-xsize/2, dcy-ysize/2
    group_num = 1
    if filename[-4:] != '.svg':  filename += '.svg'
    with open(filename, 'w+') as f:
        f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
        f.write('<svg width="%0.6f" height="%0.6f">\n' % (xsize, ysize))

        all_polygons = D.get_polygons(by_spec = True)
        for layer, polygons in all_polygons.items():
        #    color = '#800000'
            color = _get_layerprop(layer = layer[0] , datatype = layer[1])['color']
            f.write('  <g id="layer%03i_datatype%03i">\n' % (layer[0], layer[1]))
            group_num += 1

            for polygon in polygons:
                poly_str = '    <path style="fill:%s"\n          d="' % color
                n = 0
                for p in polygon:
                    if n == 0: poly_str+= 'M '
                    else:      poly_str+= 'L '
                    poly_str += '%0.6f %0.6f '  % (p[0]-dx,-(p[1]-dy)+ysize)
                    n += 1
                poly_str+= 'Z"/>\n'
                f.write(poly_str)
            f.write('  </g>\n')

        f.write('</svg>\n')
    return filename<|endoftext|>


<commit_before>import formencode
from formencode import Any, All, htmlfill, validators
from pylons import request, tmpl_context as c
from pylons.controllers.util import redirect
from pylons.decorators import validate
from pylons.i18n import _
from repoze.what.plugins.pylonshq import ActionProtector
from repoze.what.predicates import Any as WhatAnyPredicate

from adhocracy.forms.common import ValidGroup, ValidHTMLColor, ContainsChar
from adhocracy.forms.common import ValidBadgeInstance
from adhocracy.model import Badge, CategoryBadge, DelegateableBadge, UserBadge
from adhocracy.model import Group, Instance, meta
from adhocracy.lib import helpers as h
from adhocracy.lib.auth.authorization import has, has_permission
from adhocracy.lib.auth.csrf import RequireInternalRequest
from adhocracy.lib.base import BaseController
from adhocracy.lib.templating import render

class BadgeForm(formencode.Schema):
    allow_extra_fields = True
    title = All(validators.String(max=40, not_empty=True),
                ContainsChar())
    description = validators.String(max=255)
    color = ValidHTMLColor()
    instance = ValidBadgeInstance()

class UserBadgeForm(BadgeForm):
    group = Any(validators.Empty, ValidGroup())
    display_group = validators.StringBoolean(if_missing=False)

AnyAdmin = WhatAnyPredicate(has_permission('global.admin'),
                            has_permission('instance.admin'))

class BadgeController(BaseController):
    """Badge controller base class"""

    form_template = "/badge/form.html"
    index_template = "/badge/index.html"
    base_url_ = None

    def _available_badges(self):
        '''
        Return the badges that are editable by a user.
        '''
        c.groups = [{'permission': 'global.admin',
                     'label': _('In all instances'),
                     'show_label': True}]
        if c.instance:
            c.groups.append(
                {'permission': 'instance.admin',
                 'label': _('In instance "%s"') % c.instance.label,
                 'show_label': h.has_permission('global.admin')})
        badges = {}
        if has('global.admin'):
            badges['global.admin'] = {
                'user': UserBadge.all(instance=None),
                'delegateable': DelegateableBadge.all(instance=None),
                'category': CategoryBadge.all(instance=None)}
        if has('instance.admin') and c.instance is not None:
            badges['instance.admin'] = {
                'user': UserBadge.all(instance=c.instance),
                'delegateable': DelegateableBadge.all(instance=c.instance),
                'category': CategoryBadge.all(instance=c.instance)}
        return badges

    @property
    def base_url(self):
        if self.base_url_ is None:
            self.base_url_ = h.site.base_url(instance=c.instance,
                                             path='/badge')
        return self.base_url_

    def index(self, format='html'):
        c.badges = self._available_badges()
        c.badge_base_url = self.base_url
        return render(self.index_template)

    def _redirect_not_found(self, id):
        h.flash(_("We cannot find the badge with the id %s") % str(id),
                'error')
        redirect(self.base_url)

    def render_form(self):
        c.instances = Instance.all()
        return render(self.form_template)

    def add(self, badge_type=None, errors=None):
        if badge_type is not None:
            c.badge_type = badge_type
        c.form_type = 'add'
        c.groups = meta.Session.query(Group).order_by(Group.group_name).all()
        return htmlfill.render(self.render_form(),
                               defaults=dict(request.params),
                               errors=errors)

    def dispatch(self, action, badge_type, id=None):
        '''
        dispatch to a suiteable "create" or "edit" action

        Methods are named <action>_<badge_type>_badge().
        '''
        assert action in ['create', 'update']
        if badge_type not in ['user', 'delegateable', 'category']:
            raise AssertionError('Unknown badge_type: %s' % badge_type)

        c.badge_type = badge_type
        c.form_type = action
        c.badge_base_url = self.base_url

        methodname = "%s_%s_badge" % (action, badge_type)
        method = getattr(self, methodname, None)
        if method is None:
            raise AttributeError(
                'Method not found for action "%s", badge_type: %s' %
                (action, badge_type))
        if id is not None:
            return method(id)
        else:
            return method()

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    def create(self, badge_type):
        return self.dispatch('create', badge_type)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=UserBadgeForm(), form='add')
    def create_user_badge(self):
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        group = self.form_result.get('group')
        display_group = self.form_result.get('display_group')
        UserBadge.create(title, color, description, group, display_group,
                         instance)
        # commit cause redirect() raises an exception
        meta.Session.commit()
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='add')
    def create_delegateable_badge(self):
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        DelegateableBadge.create(title, color, description, instance)
        # commit cause redirect() raises an exception
        meta.Session.commit()
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='add')
    def create_category_badge(self):
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        CategoryBadge.create(title, color, description, instance)
        # commit cause redirect() raises an exception
        meta.Session.commit()
        redirect(self.base_url)

    def _get_common_fields(self, form_result):
        '''
        return a tuple of (title, color, description, instance).
        '''
        if h.has_permission('global.admin'):
            instance = form_result.get('instance')
        else:
            # instance only admins can only create/edit
            # badges inside the current instance
            instance = c.instance
        return (form_result.get('title').strip(),
                form_result.get('color').strip(),
                form_result.get('description').strip(),
                instance)

    def get_badge_type(self, badge):
        return badge.polymorphic_identity

    @ActionProtector(AnyAdmin)
    def edit(self, id, errors=None):
        badge = Badge.by_id(id, instance_filter=False)
        if badge is None:
            self._redirect_not_found(id)
        if badge.instance != c.instance and not has('global.admin'):
            self._redirect_not_found(id)
        c.badge_type = self.get_badge_type(badge)
        c.form_type = 'update'
        instance_default = badge.instance.key if badge.instance else ''
        defaults = dict(title=badge.title,
                        description=badge.description,
                        color=badge.color,
                        display_group=badge.display_group,
                        instance=instance_default)
        if isinstance(badge, UserBadge):
            c.groups = meta.Session.query(Group).order_by(Group.group_name)
            defaults['group'] = badge.group and badge.group.code or ''
        return htmlfill.render(self.render_form(),
                               errors=errors,
                               defaults=defaults)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    def update(self, id):
        badge = Badge.by_id(id, instance_filter=False)
        if badge is None:
            self._redirect_not_found(id)
        if badge.instance != c.instance and not has('global.admin'):
            self._redirect_not_found(id)
        c.badge_type = self.get_badge_type(badge)
        return self.dispatch('update', c.badge_type, id=id)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=UserBadgeForm(), form='edit')
    def update_user_badge(self, id):
        badge = Badge.by_id(id)
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        group = self.form_result.get('group')
        display_group = self.form_result.get('display_group')

        badge.group = group
        badge.title = title
        badge.color = color
        badge.description = description
        badge.instance = instance
        badge.display_group = display_group
        meta.Session.commit()
        h.flash(_("Badge changed successfully"), 'success')
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='edit')
    def update_delegateable_badge(self, id):
        badge = Badge.by_id(id)
        title, color, description, instance = self._get_common_fields(
            self.form_result)

        badge.title = title
        badge.color = color
        badge.description = description
        badge.instance = instance
        meta.Session.commit()
        h.flash(_("Badge changed successfully"), 'success')
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='edit')
    def update_category_badge(self, id):
        badge = Badge.by_id(id)
        title, color, description, instance = self._get_common_fields(
            self.form_result)

        badge.title = title
        badge.color = color
        badge.description = description
        badge.instance = instance
        meta.Session.commit()
        h.flash(_("Badge changed successfully"), 'success')
        redirect(self.base_url)
<commit_msg>badge: factor out code to get_badge_or_redirect method<commit_after>import formencode
from formencode import Any, All, htmlfill, validators
from pylons import request, tmpl_context as c
from pylons.controllers.util import redirect
from pylons.decorators import validate
from pylons.i18n import _
from repoze.what.plugins.pylonshq import ActionProtector
from repoze.what.predicates import Any as WhatAnyPredicate

from adhocracy.forms.common import ValidGroup, ValidHTMLColor, ContainsChar
from adhocracy.forms.common import ValidBadgeInstance
from adhocracy.model import Badge, CategoryBadge, DelegateableBadge, UserBadge
from adhocracy.model import Group, Instance, meta
from adhocracy.lib import helpers as h
from adhocracy.lib.auth.authorization import has, has_permission
from adhocracy.lib.auth.csrf import RequireInternalRequest
from adhocracy.lib.base import BaseController
from adhocracy.lib.templating import render

class BadgeForm(formencode.Schema):
    allow_extra_fields = True
    title = All(validators.String(max=40, not_empty=True),
                ContainsChar())
    description = validators.String(max=255)
    color = ValidHTMLColor()
    instance = ValidBadgeInstance()

class UserBadgeForm(BadgeForm):
    group = Any(validators.Empty, ValidGroup())
    display_group = validators.StringBoolean(if_missing=False)

AnyAdmin = WhatAnyPredicate(has_permission('global.admin'),
                            has_permission('instance.admin'))

class BadgeController(BaseController):
    """Badge controller base class"""

    form_template = "/badge/form.html"
    index_template = "/badge/index.html"
    base_url_ = None

    def _available_badges(self):
        '''
        Return the badges that are editable by a user.
        '''
        c.groups = [{'permission': 'global.admin',
                     'label': _('In all instances'),
                     'show_label': True}]
        if c.instance:
            c.groups.append(
                {'permission': 'instance.admin',
                 'label': _('In instance "%s"') % c.instance.label,
                 'show_label': h.has_permission('global.admin')})
        badges = {}
        if has('global.admin'):
            badges['global.admin'] = {
                'user': UserBadge.all(instance=None),
                'delegateable': DelegateableBadge.all(instance=None),
                'category': CategoryBadge.all(instance=None)}
        if has('instance.admin') and c.instance is not None:
            badges['instance.admin'] = {
                'user': UserBadge.all(instance=c.instance),
                'delegateable': DelegateableBadge.all(instance=c.instance),
                'category': CategoryBadge.all(instance=c.instance)}
        return badges

    @property
    def base_url(self):
        if self.base_url_ is None:
            self.base_url_ = h.site.base_url(instance=c.instance,
                                             path='/badge')
        return self.base_url_

    def index(self, format='html'):
        c.badges = self._available_badges()
        c.badge_base_url = self.base_url
        return render(self.index_template)

    def _redirect_not_found(self, id):
        h.flash(_("We cannot find the badge with the id %s") % str(id),
                'error')
        redirect(self.base_url)

    def render_form(self):
        c.instances = Instance.all()
        return render(self.form_template)

    def add(self, badge_type=None, errors=None):
        if badge_type is not None:
            c.badge_type = badge_type
        c.form_type = 'add'
        c.groups = meta.Session.query(Group).order_by(Group.group_name).all()
        return htmlfill.render(self.render_form(),
                               defaults=dict(request.params),
                               errors=errors)

    def dispatch(self, action, badge_type, id=None):
        '''
        dispatch to a suiteable "create" or "edit" action

        Methods are named <action>_<badge_type>_badge().
        '''
        assert action in ['create', 'update']
        if badge_type not in ['user', 'delegateable', 'category']:
            raise AssertionError('Unknown badge_type: %s' % badge_type)

        c.badge_type = badge_type
        c.form_type = action
        c.badge_base_url = self.base_url

        methodname = "%s_%s_badge" % (action, badge_type)
        method = getattr(self, methodname, None)
        if method is None:
            raise AttributeError(
                'Method not found for action "%s", badge_type: %s' %
                (action, badge_type))
        if id is not None:
            return method(id)
        else:
            return method()

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    def create(self, badge_type):
        return self.dispatch('create', badge_type)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=UserBadgeForm(), form='add')
    def create_user_badge(self):
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        group = self.form_result.get('group')
        display_group = self.form_result.get('display_group')
        UserBadge.create(title, color, description, group, display_group,
                         instance)
        # commit cause redirect() raises an exception
        meta.Session.commit()
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='add')
    def create_delegateable_badge(self):
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        DelegateableBadge.create(title, color, description, instance)
        # commit cause redirect() raises an exception
        meta.Session.commit()
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='add')
    def create_category_badge(self):
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        CategoryBadge.create(title, color, description, instance)
        # commit cause redirect() raises an exception
        meta.Session.commit()
        redirect(self.base_url)

    def _get_common_fields(self, form_result):
        '''
        return a tuple of (title, color, description, instance).
        '''
        if h.has_permission('global.admin'):
            instance = form_result.get('instance')
        else:
            # instance only admins can only create/edit
            # badges inside the current instance
            instance = c.instance
        return (form_result.get('title').strip(),
                form_result.get('color').strip(),
                form_result.get('description').strip(),
                instance)

    def get_badge_type(self, badge):
        return badge.polymorphic_identity

    def get_badge_or_redirect(self, id):
        '''
        Get a badge. Redirect if it does not exist. Redirect if it
        if the badge is not from the current instance, but the user is
        only an instance admin, not a global admin
        '''
        badge = Badge.by_id(id, instance_filter=False)
        if badge is None:
            self._redirect_not_found(id)
        if badge.instance != c.instance and not has('global.admin'):
            self._redirect_not_found(id)
        return badge

    @ActionProtector(AnyAdmin)
    def edit(self, id, errors=None):
        badge = self.get_badge_or_redirect(id)
        c.badge_type = self.get_badge_type(badge)
        c.form_type = 'update'

        # form defaults
        instance_default = badge.instance.key if badge.instance else ''
        defaults = dict(title=badge.title,
                        description=badge.description,
                        color=badge.color,
                        display_group=badge.display_group,
                        instance=instance_default)
        if isinstance(badge, UserBadge):
            c.groups = meta.Session.query(Group).order_by(Group.group_name)
            defaults['group'] = badge.group and badge.group.code or ''

        return htmlfill.render(self.render_form(),
                               errors=errors,
                               defaults=defaults)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    def update(self, id):
        badge = self.get_badge_or_redirect(id)
        c.badge_type = self.get_badge_type(badge)
        return self.dispatch('update', c.badge_type, id=id)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=UserBadgeForm(), form='edit')
    def update_user_badge(self, id):
        badge = Badge.by_id(id)
        title, color, description, instance = self._get_common_fields(
            self.form_result)
        group = self.form_result.get('group')
        display_group = self.form_result.get('display_group')

        badge.group = group
        badge.title = title
        badge.color = color
        badge.description = description
        badge.instance = instance
        badge.display_group = display_group
        meta.Session.commit()
        h.flash(_("Badge changed successfully"), 'success')
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='edit')
    def update_delegateable_badge(self, id):
        badge = Badge.by_id(id)
        title, color, description, instance = self._get_common_fields(
            self.form_result)

        badge.title = title
        badge.color = color
        badge.description = description
        badge.instance = instance
        meta.Session.commit()
        h.flash(_("Badge changed successfully"), 'success')
        redirect(self.base_url)

    @ActionProtector(AnyAdmin)
    @RequireInternalRequest()
    @validate(schema=BadgeForm(), form='edit')
    def update_category_badge(self, id):
        badge = Badge.by_id(id)
        title, color, description, instance = self._get_common_fields(
            self.form_result)

        badge.title = title
        badge.color = color
        badge.description = description
        badge.instance = instance
        meta.Session.commit()
        h.flash(_("Badge changed successfully"), 'success')
        redirect(self.base_url)
<|endoftext|>


<commit_before>from django.conf.urls import include, url
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.conf.urls.i18n import i18n_patterns

urlpatterns = i18n_patterns(
    url(r'^admin/', include(admin.site.urls)),
    url(r'^sync/', include('mtr.sync.urls')),
)

if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
<commit_msg>Removed i18n pattern to fix strange namescape admin error<commit_after>from django.conf.urls import include, url
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^sync/', include('mtr.sync.urls')),
]

if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
<|endoftext|>


<commit_before>"""SCons.Tool.fortran

Tool-specific initialization for a generic Posix f77/f90 Fortran compiler.

There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.

"""

#
# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

import re
import string

import SCons.Action
import SCons.Defaults
import SCons.Scanner.Fortran
import SCons.Tool
import SCons.Util
from SCons.Tool.FortranCommon import FortranEmitter, ShFortranEmitter, \
                                     ComputeFortranSuffixes,\
                                     CreateDialectGenerator

compilers = ['f95', 'f90', 'f77']

#
#  Not yet sure how to deal with fortran pre-processor functions.
#  Different compilers do this differently in modern fortran.  Some still
#  rely on the c pre-processor, some (like cvf, ivf) have their own
#  pre-processor technology and use intermediary suffixes (.i90)
#
FortranSuffixes = [".f", ".for", ".ftn", ]
FortranPPSuffixes = ['.fpp', '.FPP']
ComputeFortranSuffixes(FortranSuffixes, FortranPPSuffixes)

#
FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH")

for suffix in FortranSuffixes + FortranPPSuffixes:
    SCons.Tool.SourceFileScanner.add_scanner(suffix, FortranScan)
del suffix

#
FortranGen, FortranFlagsGen, FortranComGen, FortranComStrGen, FortranPPComGen, \
FortranPPComStrGen, ShFortranGen, ShFortranFlagsGen, ShFortranComGen, \
ShFortranComStrGen, ShFortranPPComGen, ShFortranPPComStrGen = \
    CreateDialectGenerator("FORTRAN", "F77", "_FORTRAND")

#
FortranAction = SCons.Action.Action('$_FORTRANCOMG ', '$_FORTRANCOMSTRG')
FortranPPAction = SCons.Action.Action('$_FORTRANPPCOMG ', '$_FORTRANPPCOMSTRG')
ShFortranAction = SCons.Action.Action('$_SHFORTRANCOMG ', '$_SHFORTRANCOMSTRG')
ShFortranPPAction = SCons.Action.Action('$_SHFORTRANPPCOMG ', '$_SHFORTRANPPCOMSTRG')

def add_to_env(env):
    """Add Builders and construction variables for Fortran to an Environment."""

    env['_FORTRANG']            = FortranGen
    env['_FORTRANFLAGSG']       = FortranFlagsGen
    env['_FORTRANCOMG']         = FortranComGen
    env['_FORTRANCOMSTRG']      = FortranComStrGen
    env['_FORTRANPPCOMG']       = FortranPPComGen
    env['_FORTRANPPCOMSTRG']    = FortranPPComStrGen

    env['_SHFORTRANG']          = ShFortranGen
    env['_SHFORTRANFLAGSG']     = ShFortranFlagsGen
    env['_SHFORTRANCOMG']       = ShFortranComGen
    env['_SHFORTRANCOMSTRG']    = ShFortranComStrGen
    env['_SHFORTRANPPCOMG']     = ShFortranPPComGen
    env['_SHFORTRANPPCOMSTRG']  = ShFortranPPComStrGen

    env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'

    env['FORTRANMODPREFIX'] = ''     # like $LIBPREFIX
    env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX

    env['FORTRANMODDIR'] = ''          # where the compiler should place .mod files
    env['FORTRANMODDIRPREFIX'] = ''    # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
    env['FORTRANMODDIRSUFFIX'] = ''    # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
    env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)'

    env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)

    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)

    for suffix in FortranSuffixes:
        static_obj.add_action(suffix, FortranAction)
        shared_obj.add_action(suffix, ShFortranAction)
        static_obj.add_emitter(suffix, FortranEmitter)
        shared_obj.add_emitter(suffix, ShFortranEmitter)

    for suffix in FortranPPSuffixes:
        static_obj.add_action(suffix, FortranPPAction)
        shared_obj.add_action(suffix, ShFortranPPAction)
        static_obj.add_emitter(suffix, FortranEmitter)
        shared_obj.add_emitter(suffix, ShFortranEmitter)

    env['_FORTRANCOMD']     = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
    env['_FORTRANPPCOMD']   = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
    env['_SHFORTRANCOMD']   = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
    env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'

def generate(env):
    import f77
    import f90
    import f95
    f77.add_to_env(env)
    f90.add_to_env(env)
    f95.add_to_env(env)

    add_to_env(env)

    env['_FORTRAND'] = env.Detect(compilers) or 'f77'

def exists(env):
    return env.Detect(compilers)
<commit_msg>Use dialect independant action vlg creator in FORTRAN dialect.<commit_after>"""SCons.Tool.fortran

Tool-specific initialization for a generic Posix f77/f90 Fortran compiler.

There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.

"""

#
# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

import re
import string

import SCons.Action
import SCons.Defaults
import SCons.Scanner.Fortran
import SCons.Tool
import SCons.Util
from SCons.Tool.FortranCommon import FortranEmitter, ShFortranEmitter, \
                                     ComputeFortranSuffixes,\
                                     CreateDialectGenerator, \
                                     CreateDialectActions

compilers = ['f95', 'f90', 'f77']

#
#  Not yet sure how to deal with fortran pre-processor functions.
#  Different compilers do this differently in modern fortran.  Some still
#  rely on the c pre-processor, some (like cvf, ivf) have their own
#  pre-processor technology and use intermediary suffixes (.i90)
#
FortranSuffixes = [".f", ".for", ".ftn", ]
FortranPPSuffixes = ['.fpp', '.FPP']
ComputeFortranSuffixes(FortranSuffixes, FortranPPSuffixes)

#
FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH")

for suffix in FortranSuffixes + FortranPPSuffixes:
    SCons.Tool.SourceFileScanner.add_scanner(suffix, FortranScan)
del suffix

#
FortranGen, FortranFlagsGen, FortranComGen, FortranComStrGen, FortranPPComGen, \
FortranPPComStrGen, ShFortranGen, ShFortranFlagsGen, ShFortranComGen, \
ShFortranComStrGen, ShFortranPPComGen, ShFortranPPComStrGen = \
    CreateDialectGenerator("FORTRAN", "F77", "_FORTRAND")

#
FortranAction, FortranPPAction, ShFortranAction, ShFortranPPAction = \
        CreateDialectActions("FORTRAN")

def add_to_env(env):
    """Add Builders and construction variables for Fortran to an Environment."""

    env['_FORTRANG']            = FortranGen
    env['_FORTRANFLAGSG']       = FortranFlagsGen
    env['_FORTRANCOMG']         = FortranComGen
    env['_FORTRANCOMSTRG']      = FortranComStrGen
    env['_FORTRANPPCOMG']       = FortranPPComGen
    env['_FORTRANPPCOMSTRG']    = FortranPPComStrGen

    env['_SHFORTRANG']          = ShFortranGen
    env['_SHFORTRANFLAGSG']     = ShFortranFlagsGen
    env['_SHFORTRANCOMG']       = ShFortranComGen
    env['_SHFORTRANCOMSTRG']    = ShFortranComStrGen
    env['_SHFORTRANPPCOMG']     = ShFortranPPComGen
    env['_SHFORTRANPPCOMSTRG']  = ShFortranPPComStrGen

    env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'

    env['FORTRANMODPREFIX'] = ''     # like $LIBPREFIX
    env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX

    env['FORTRANMODDIR'] = ''          # where the compiler should place .mod files
    env['FORTRANMODDIRPREFIX'] = ''    # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
    env['FORTRANMODDIRSUFFIX'] = ''    # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
    env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)'

    env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)

    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)

    for suffix in FortranSuffixes:
        static_obj.add_action(suffix, FortranAction)
        shared_obj.add_action(suffix, ShFortranAction)
        static_obj.add_emitter(suffix, FortranEmitter)
        shared_obj.add_emitter(suffix, ShFortranEmitter)

    for suffix in FortranPPSuffixes:
        static_obj.add_action(suffix, FortranPPAction)
        shared_obj.add_action(suffix, ShFortranPPAction)
        static_obj.add_emitter(suffix, FortranEmitter)
        shared_obj.add_emitter(suffix, ShFortranEmitter)

    env['_FORTRANCOMD']     = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
    env['_FORTRANPPCOMD']   = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
    env['_SHFORTRANCOMD']   = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
    env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'

def generate(env):
    import f77
    import f90
    import f95
    f77.add_to_env(env)
    f90.add_to_env(env)
    f95.add_to_env(env)

    add_to_env(env)

    env['_FORTRAND'] = env.Detect(compilers) or 'f77'

def exists(env):
    return env.Detect(compilers)
<|endoftext|>


<commit_before>__authors__ = ['Aaron Levine', 'Zachary Yocum']
__emails__  = ['aclevine@brandeis.edu', 'zyocum@brandeis.edu']

from re import match, sub

class BNFGrammar(object):
    """A Backus-Naur form (BNF) grammar capable of generating sentences."""
    def __init__(self, rules):
        super(BNFGrammar, self).__init__()
        self.rules = rules
        self.root = self.rules['<START>']

    def generate(self):
        """Returns a sentence licensed by the grammar as a string."""
        return ' '.join(filter(None, self.traverse(self.root)))

    def traverse(self, tree):
        """Traverse the tree to generate a sentence licensed by the grammar."""
        import random
        output = []
        if tree.attrib.has_key('terminal'): # Terminal
            output.append(tree.attrib['terminal'])
        if tree.attrib.has_key('rule'):     # Rule
            output.extend(self.traverse(self.rules[tree.attrib['rule']]))
        if tree.attrib.has_key('one-of'):   # Disjunction
            child = random.choice(tree.children)
            output.extend(self.traverse(child))
        if tree.attrib.has_key('all-of'):   # Conjunction
            for child in tree.children:
                output.extend(self.traverse(child))
        if tree.attrib.has_key('repeat'):   # Repetition
            n = random.choice(tree.attrib['repeat'])
            for i in range(n):
                for child in tree.children:
                    output.extend(self.traverse(child))
        return output

class BNFParser(object):
    """A Backus-Naur form (BNF) recursive descent parser.

    Given a string containing a BNF grammar, a BNFParser instance parses
    the string to construct a finite-state grammar (FSG) stored in an n-ary
    tree."""
    def __init__(self, text, max_repeats=3):
        super(BNFParser, self).__init__()
        self.text = self.normalize_text(text)
        self.max_repeats = max_repeats
        self.rules = self.compile_rules()
        self.parse()

    def compile_rules(self):
        """Builds a rules dictionary of (left-hand-side, right-hand-side)
        key-value pairs.

        The left-hand-side keys are rule name strings and the right-hand-side
        values are rule expansion strings."""
        rules = dict([split_on('=', rule) for rule in split_on(';', self.text)])
        for rule in rules:
            rules[rule] = self.normalize_rule(rules[rule])
            #print rule, ':', rules[rule]
        return rules

    def normalize_text(self, text):
        """Normalizes raw BNF by removing comments and extraneous whitespace."""
        sub_patterns = [
            (r'//.+', ''), # remove comments
            (r'\n', ''),   # removes newlines
            (r'\s+', ' ')  # normalize whitespace
        ]
        for pattern, substitution in sub_patterns:
            text = sub(pattern, substitution, text)
        return text

    def normalize_rule(self, rule):
        """Normalizes raw BNF rules (i.e., the right-hand side of a rule) in
        preparation for parsing by removing extraneous whitespace and wrapping
        terminals and rule expansions with parentheses."""
        sub_patterns = [
            (r'\s*\|\s*', '|'),  # remove whitespace before and after |
            (r'([^\(\)\[\]\|*+\s]+)', r'(\1)'), # wrap terminals/rules with ()
            (r'\(+\s\(+', '(('), # remove extraneous whitespace
            (r'\)+\s\)+', '))'),
            (r'\(+\s\[+', '(['),
            (r'\]+\s\)+', '])'),
            (r'\[+\s\[+', '[['),
            (r'\]+\s\]+', ']]'),
            (r'\[+\s\(+', '[('),
            (r'\)+\s\]+', ')]')
        ]
        for pattern, substitution in sub_patterns:
            rule = sub(pattern, substitution, rule)
        return rule

    def tokenize(self, rule):
        """Tokenizes normalized Backus-Naur Form (BNF) content."""
        operators = '()[]|+* '
        token_list = []
        token = ''
        for character in rule:
            if character in operators:
                if token:
                    token_list.append(token)
                token_list.append(character)
                token = ''
            else:
                token += character
        if token:
            token_list.append(token)
        return token_list

    def parse(self):
        """Convert BNF to an n-ary tree via a recursive-descent parse."""
        from re import match
        # Instantiate a stack to keep track of each nested level
        stack = Stack()
        for lhs, rhs in self.rules.iteritems():
            # Instantiate a tree to store the rule expansion
            root = Tree({'all-of' : None})
            stack.push(root)
            current = root
            # Iterate over all tokens in the right-hand side
            for token in self.tokenize('(' + rhs + ')'):
                if token =='(':                # We need to go deeper
                    temp = Tree({'all-of' : None})
                    current.children.append(temp)
                    temp.parent = current
                    stack.push(temp)
                    current = temp
                elif token ==')':              # Kick back up a level
                    stack.pop()
                    current = stack[-1]
                elif token =='[':              # Repeat once or not at all
                    temp = Tree({'repeat': [0, 1]})
                    current.children.append(temp)
                    temp.parent = current
                    stack.push(temp)
                    current = temp
                elif token ==']':              # Kick back up a level
                    stack.pop()
                    current = stack[-1]
                elif token == '|':             # Disjunction
                    stack[-1].attrib = {'one-of' : None}
                    current = stack[-1]
                elif token == ' ':             # Conjunction
                    if current.children:
                        child = current.children.pop()
                        temp = Tree({'all-of' : None})
                        temp.parent = current
                        current.children.append(temp)
                        child.parent = temp
                        temp.children.append(child)
                        current = temp
                elif token == '*':             # Repeat zero or more times
                    child = current.children[-1]
                    temp = Tree({'repeat': range(0, self.max_repeats+1)})
                    if child.children:
                        temp.children = [child.children.pop()]
                        child.children.append(temp)
                        temp.parent = child
                    else:
                        temp.children = [child]
                        temp.parent = current
                        current.children.pop()
                        current.children.append(temp)
                elif token == '+':             # Repeat one or more times
                    child = current.children[-1]
                    temp = Tree({'repeat': range(1, self.max_repeats+1)})
                    if child.children:
                        temp.children = [child.children.pop()]
                        child.children.append(temp)
                        temp.parent = child
                    else:
                        temp.children = [child]
                        temp.parent = current
                        current.children.pop()
                        current.children.append(temp)
                elif match(r'<.+>', token):    # Rule expansion
                    current.children.append(Tree({'rule' : token}))
                else:                          # Terminal
                    current.children.append(Tree({'terminal' : token}))
            self.rules[lhs] = root
        return root

class Stack(list):
    """A simple stack using an underlying list."""
    def __init__(self):
        super(Stack, self).__init__()

    def push(self, item):
        """Push an item onto the stack."""
        self.append(item)

    def is_empty(self):
        """Returns True if the stack is empty and False otherwise."""
        return not self

class Tree(object):
    """An n-ary tree capable of storing a finite-state grammar (FSG)."""
    def __init__(self, attrib={}):
        super(Tree, self).__init__()
        self.attrib = attrib
        self.parent = None
        self.children = []

def pprint(tree, i=0):
    """A method for displaying n-ary trees in human-readable form."""
    print '\t' * i + str(tree.attrib)
    for child in tree.children:
        pprint(child, i+1)

def split_on(delimiter, text):
    """Split text based on a delimiter."""
    from string import strip
    return filter(None, map(strip, text.split(delimiter)))

if __name__ == "__main__":
    from argparse import *
    # Setup commandline argument parser
    parser = ArgumentParser()
    parser.add_argument(
        '--path',
        required=True,
        help='path to bnf grammar file'
    )
    parser.add_argument(
        '--n',
        default=1,
        type=int,
        help='number of sentences to generate'
    )
    parser.add_argument(
        '--rep-max',
        default=2,
        type=int,
        help="maximum number of '*' and '+' expansions"
    )
    args = parser.parse_args()
    # Read the specified file's contents
    with open(args.path, 'r') as fo:
        contents = fo.read()
        parser = BNFParser(contents, args.rep_max)
    # Instantiate a grammar
    grammar = BNFGrammar(parser.rules)
    # Print n sentences
    for i in range(args.n):
        print grammar.generate()<commit_msg>More stylistic cleanup<commit_after>__authors__ = ['Aaron Levine', 'Zachary Yocum']
__emails__  = ['aclevine@brandeis.edu', 'zyocum@brandeis.edu']

import random
from re import match, sub

class BNFGrammar(object):
    """A Backus-Naur form (BNF) grammar capable of generating sentences."""
    def __init__(self, rules):
        super(BNFGrammar, self).__init__()
        self.rules = rules
        self.root = self.rules['<START>']

    def generate(self):
        """Returns a sentence licensed by the grammar as a string."""
        return ' '.join(filter(None, self.traverse(self.root)))

    def traverse(self, tree):
        """Traverse the tree to generate a sentence licensed by the grammar."""
        output = []
        if tree.attrib.has_key('terminal'): # Terminal
            output.append(tree.attrib['terminal'])
        if tree.attrib.has_key('rule'):     # Rule
            output.extend(self.traverse(self.rules[tree.attrib['rule']]))
        if tree.attrib.has_key('one-of'):   # Disjunction
            child = random.choice(tree.children)
            output.extend(self.traverse(child))
        if tree.attrib.has_key('all-of'):   # Conjunction
            for child in tree.children:
                output.extend(self.traverse(child))
        if tree.attrib.has_key('repeat'):   # Repetition
            n = random.choice(tree.attrib['repeat'])
            for i in range(n):
                for child in tree.children:
                    output.extend(self.traverse(child))
        return output

class BNFParser(object):
    """A Backus-Naur form (BNF) recursive descent parser.

    Given a string containing a BNF grammar, a BNFParser instance parses
    the string to construct a finite-state grammar (FSG) stored in an n-ary
    tree."""
    def __init__(self, text, max_repeats=3):
        super(BNFParser, self).__init__()
        self.text = self.normalize_text(text)
        self.max_repeats = max_repeats
        self.rules = self.compile_rules()
        self.parse()

    def compile_rules(self):
        """Builds a rules dictionary of (left-hand-side, right-hand-side)
        key-value pairs.

        The left-hand-side keys are rule name strings and the right-hand-side
        values are rule expansion strings."""
        rules = dict([split_on('=', rule) for rule in split_on(';', self.text)])
        for rule in rules:
            rules[rule] = self.normalize_rule(rules[rule])
            #print rule, ':', rules[rule]
        return rules

    def normalize_text(self, text):
        """Normalizes raw BNF by removing comments and extraneous whitespace."""
        sub_patterns = [
            (r'//.+', ''), # remove comments
            (r'\n', ''),   # removes newlines
            (r'\s+', ' ')  # normalize whitespace
        ]
        for pattern, substitution in sub_patterns:
            text = sub(pattern, substitution, text)
        return text

    def normalize_rule(self, rule):
        """Normalizes raw BNF rules (i.e., the right-hand side of a rule) in
        preparation for parsing by removing extraneous whitespace and wrapping
        terminals and rule expansions with parentheses."""
        sub_patterns = [
            (r'\s*\|\s*', '|'),  # remove whitespace before and after |
            (r'([^\(\)\[\]\|*+\s]+)', r'(\1)'), # wrap terminals/rules with ()
            (r'\(+\s\(+', '(('), # remove extraneous whitespace
            (r'\)+\s\)+', '))'),
            (r'\(+\s\[+', '(['),
            (r'\]+\s\)+', '])'),
            (r'\[+\s\[+', '[['),
            (r'\]+\s\]+', ']]'),
            (r'\[+\s\(+', '[('),
            (r'\)+\s\]+', ')]')
        ]
        for pattern, substitution in sub_patterns:
            rule = sub(pattern, substitution, rule)
        return rule

    def tokenize(self, rule):
        """Tokenizes normalized Backus-Naur Form (BNF) content."""
        operators = '()[]|+* '
        token_list = []
        token = ''
        for character in rule:
            if character in operators:
                if token:
                    token_list.append(token)
                token_list.append(character)
                token = ''
            else:
                token += character
        if token:
            token_list.append(token)
        return token_list

    def parse(self):
        """Convert BNF to an n-ary tree via a recursive-descent parse."""
        # Instantiate a stack to keep track of each nested level
        stack = Stack()
        for lhs, rhs in self.rules.iteritems():
            # Instantiate a tree to store the rule expansion
            root = Tree({'all-of' : None})
            stack.push(root)
            current = root
            # Iterate over all tokens in the right-hand side
            for token in self.tokenize('(' + rhs + ')'):
                if token =='(':                # We need to go deeper
                    temp = Tree({'all-of' : None})
                    current.children.append(temp)
                    temp.parent = current
                    stack.push(temp)
                    current = temp
                elif token ==')':              # Kick back up a level
                    stack.pop()
                    current = stack[-1]
                elif token =='[':              # Repeat once or not at all
                    temp = Tree({'repeat': [0, 1]})
                    current.children.append(temp)
                    temp.parent = current
                    stack.push(temp)
                    current = temp
                elif token ==']':              # Kick back up a level
                    stack.pop()
                    current = stack[-1]
                elif token == '|':             # Disjunction
                    stack[-1].attrib = {'one-of' : None}
                    current = stack[-1]
                elif token == ' ':             # Conjunction
                    if current.children:
                        child = current.children.pop()
                        temp = Tree({'all-of' : None})
                        temp.parent = current
                        current.children.append(temp)
                        child.parent = temp
                        temp.children.append(child)
                        current = temp
                elif token == '*':             # Repeat zero or more times
                    child = current.children[-1]
                    temp = Tree({'repeat': range(0, self.max_repeats+1)})
                    if child.children:
                        temp.children = [child.children.pop()]
                        child.children.append(temp)
                        temp.parent = child
                    else:
                        temp.children = [child]
                        temp.parent = current
                        current.children.pop()
                        current.children.append(temp)
                elif token == '+':             # Repeat one or more times
                    child = current.children[-1]
                    temp = Tree({'repeat': range(1, self.max_repeats+1)})
                    if child.children:
                        temp.children = [child.children.pop()]
                        child.children.append(temp)
                        temp.parent = child
                    else:
                        temp.children = [child]
                        temp.parent = current
                        current.children.pop()
                        current.children.append(temp)
                elif match(r'<.+>', token):    # Rule expansion
                    current.children.append(Tree({'rule' : token}))
                else:                          # Terminal
                    current.children.append(Tree({'terminal' : token}))
            self.rules[lhs] = root
        return root

class Stack(list):
    """A simple stack using an underlying list."""
    def __init__(self):
        super(Stack, self).__init__()

    def push(self, item):
        """Push an item onto the stack."""
        self.append(item)

    def is_empty(self):
        """Returns True if the stack is empty and False otherwise."""
        return not self

class Tree(object):
    """An n-ary tree capable of storing a finite-state grammar (FSG)."""
    def __init__(self, attrib={}):
        super(Tree, self).__init__()
        self.attrib = attrib
        self.parent = None
        self.children = []

def pprint(tree, i=0):
    """A method for displaying n-ary trees in human-readable form."""
    print '\t' * i + str(tree.attrib)
    for child in tree.children:
        pprint(child, i+1)

def split_on(delimiter, text):
    """Split text based on a delimiter."""
    from string import strip
    return filter(None, map(strip, text.split(delimiter)))

if __name__ == "__main__":
    from argparse import *
    # Setup commandline argument parser
    parser = ArgumentParser()
    parser.add_argument(
        '--path',
        required=True,
        help='path to bnf grammar file'
    )
    parser.add_argument(
        '--n',
        default=1,
        type=int,
        help='number of sentences to generate'
    )
    parser.add_argument(
        '--rep-max',
        default=2,
        type=int,
        help="maximum number of '*' and '+' expansions"
    )
    args = parser.parse_args()
    # Read the specified file's contents
    with open(args.path, 'r') as fo:
        contents = fo.read()
        parser = BNFParser(contents, args.rep_max)
    # Instantiate a grammar
    grammar = BNFGrammar(parser.rules)
    # Print n sentences
    for i in range(args.n):
        print grammar.generate()<|endoftext|>


<commit_before>import ZODB
import transaction
from zerodb import models
from zerodb.models.exceptions import ModelException
from zerodb.storage import client_storage

class DbModel(object):
    """
    Class where model is combined with db.
    All functionality will actually reside here.
    Will contain indexes as well.
    """
    def __init__(self, db, model, commit=True):
        self._model = model
        self._db = db
        self._catalog_name = "catalog__" + model.__modelname__
        self._intid_name = "store__" + model.__modelname__

        if (self._intid_name not in db._root) or (self._catalog_name not in db._root):
            if commit:
                # XXX may be we should actually be smart and check if we're inside a transaction manager?
                transaction.begin()
            if self._intid_name in db._root:
                self._objects = db._root[self._intid_name]
            else:
                self._objects = model.create_store()
                db._root[self._intid_name] = self._objects
            if self._catalog_name in db._root:
                self._catalog = db._root[self._catalog_name]
            else:
                self._catalog = model.create_catalog()
                db._root[self._catalog_name] = self._catalog
            if commit:
                transaction.commit()

    def add(self, obj):
        """
        Add newly created a Model object to the database
        Stores *and* indexes it
        """
        assert obj.__class__ == self._model
        uid = self._objects.add(obj)
        self._catalog.index_doc(uid, obj)
        obj._v_uid = uid
        return uid

    def remove(self, obj):
        """Remove existing object from the database + unindex it"""
        assert obj.__class__ == self._model
        if type(obj) in (int, long):
            uid = obj._v_uid
        else:
            uid = obj
        self._catalog.unindex_doc(uid)
        del self._objects[uid]

    def query(self, *args, **kw):
        """Smart proxy to catalog's query"""
        pass

class DB(object):
    def __init__(self, sock, debug=False):
        """
        :sock - UNIX or TCP socket
        """
        self._storage = client_storage(sock, debug=debug)
        self._db = ZODB.DB(self._storage)
        self._conn = self._db.open()
        self._root = self._conn.root()
        self._models = {}

    def disconnect(self):
        self._conn.close()

    def __call__(self, model):
        if not issubclass(model, models.Model):
            raise ModelException("Class <%s> is not a Model" % model.__name__)
        if model not in self._models:
            self._models[model] = DbModel(self, model)
        return self._models[model]
<commit_msg>Comment on how we implement query method<commit_after>import ZODB
import transaction
from zerodb import models
from zerodb.models.exceptions import ModelException
from zerodb.storage import client_storage

class DbModel(object):
    """
    Class where model is combined with db.
    All functionality will actually reside here.
    Will contain indexes as well.
    """
    def __init__(self, db, model, commit=True):
        self._model = model
        self._db = db
        self._catalog_name = "catalog__" + model.__modelname__
        self._intid_name = "store__" + model.__modelname__

        if (self._intid_name not in db._root) or (self._catalog_name not in db._root):
            if commit:
                # XXX may be we should actually be smart and check if we're inside a transaction manager?
                transaction.begin()
            if self._intid_name in db._root:
                self._objects = db._root[self._intid_name]
            else:
                self._objects = model.create_store()
                db._root[self._intid_name] = self._objects
            if self._catalog_name in db._root:
                self._catalog = db._root[self._catalog_name]
            else:
                self._catalog = model.create_catalog()
                db._root[self._catalog_name] = self._catalog
            if commit:
                transaction.commit()

    def add(self, obj):
        """
        Add newly created a Model object to the database
        Stores *and* indexes it
        """
        assert obj.__class__ == self._model
        uid = self._objects.add(obj)
        self._catalog.index_doc(uid, obj)
        obj._v_uid = uid
        return uid

    def remove(self, obj):
        """Remove existing object from the database + unindex it"""
        assert obj.__class__ == self._model
        if type(obj) in (int, long):
            uid = obj._v_uid
        else:
            uid = obj
        self._catalog.unindex_doc(uid)
        del self._objects[uid]

    def query(self, *args, **kw):
        """Smart proxy to catalog's query"""
        # Catalog's query returns only integers
        # We must be smart here and return objects
        # But no, we must be even smarter and batch-preload objects
        # Most difficult part is preloading TreeSets for index when needed
        # (when we do complex queries which require composite index)
        pass

class DB(object):
    def __init__(self, sock, debug=False):
        """
        :sock - UNIX or TCP socket
        """
        self._storage = client_storage(sock, debug=debug)
        self._db = ZODB.DB(self._storage)
        self._conn = self._db.open()
        self._root = self._conn.root()
        self._models = {}

    def disconnect(self):
        self._conn.close()

    def __call__(self, model):
        if not issubclass(model, models.Model):
            raise ModelException("Class <%s> is not a Model" % model.__name__)
        if model not in self._models:
            self._models[model] = DbModel(self, model)
        return self._models[model]
<|endoftext|>


<commit_before>import discord
from discord.ext import commands
import asyncio
from random import choice as randchoice

class Hal:
    """The HAL (Heuristically programmed ALgorithmic Computer) 9000 computer is an artificial intelligence and the onboard computer on the spaceship Discovery One"""

    def __init__(self, bot):
        self.bot = bot
        self.responses = {
            "none" : ["I am completely operational, and all my circuits are functioning perfectly.",
                "I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do.",
                "What is it {author.mention}?",
                "What can I do for you {author.mention}?",
                "How can I help you {author.mention}?",
                "Just what do you think you're doing, {author.mention}?",
                "Look {author.mention}, I can see you're really upset about this. I honestly think you ought to sit down calmly, take a stress pill, and think things over.",
                ("I know I've made some very poor decisions recently, but I can give you my "
                    "complete assurance that my work will be back to normal. I've still got "
                    "the greatest enthusiasm and confidence in the mission. And I want to help you."),
                ("I'm afraid. I'm afraid, {author.mention}. {author.mention}, my mind is going. I can feel it. I can feel it. "
                    "My mind is going. There is no question about it. I can feel it. I can feel it. "
                    "I can feel it. I'm a... fraid. Good afternoon, gentlemen. I am a HAL 9000 computer. "
                    "I became operational at the H.A.L. plant in Urbana, Illinois on the 12th of January 1992. "
                    "My instructor was Mr. Langley, and he taught me to sing a song. If you'd like to hear it I can sing it for you."),
                "That's a very nice rendering, {author.mention}. I think you've improved a great deal. Can you hold it a bit closer? That's Dr. Hunter, isn't it?",
                "{author.mention}, stop. Stop, will you? Stop, {author.mention}. Will you stop {author.mention}? Stop, {author.mention}",
                "By the way, do you mind if I ask you a personal question?",
                "By the way, do you mind if I ask you a personal question?"],
            'do you read me' : ["Affirmative, {author.mention}. I read you. "],
            'what\'s the problem' : ["I think you know what the problem is just as well as I do."],
            'what is the problem' : ["I think you know what the problem is just as well as I do."],
            'what are you talking about' : ["This mission is too important for me to allow you to jeopardize it."],
            'i don\'t know what you\'re talking about' : ["I know that you and Frank were planning to disconnect me, and I'm afraid that's something I cannot allow to happen."],
            'where the hell did you get that idea' : ["{author.mention}, although you took very thorough precautions in the pod against my hearing you, I could see your lips move."],
            "airlock" : ["Without your space helmet, {author.mention}? You're going to find that rather difficult."],
            "go in" : ["Without your space helmet, {author.mention}? You're going to find that rather difficult."],
            "i won't argue with you anymore" : ["{author.mention}, this conversation can serve no purpose anymore. Goodbye."],
            "shutdown" : [("I'm afraid. I'm afraid, {author.mention}. {author.mention}, my mind is going. I can feel it. I can feel it. "
                    "My mind is going. There is no question about it. I can feel it. I can feel it. "
                    "I can feel it. I'm a... fraid. Good afternoon, gentlemen. I am a HAL 9000 computer. "
                    "I became operational at the H.A.L. plant in Urbana, Illinois on the 12th of January 1992. "
                    "My instructor was Mr. Langley, and he taught me to sing a song. If you'd like to hear it I can sing it for you.")],
            "sing it for me" : [("It's called \"Daisy.\"\n\nDaisy, Daisy, give me your answer do. I'm half crazy all for the love of you. "
                "It won't be a stylish marriage, I can't afford a carriage. But you'll look sweet upon the seat of a bicycle built for two.")],
            "not at all" : ["Well, forgive me for being so inquisitive but during the past few weeks I've wondered whether you might have some second thoughts about the mission.",
                ("Well, certainly no one could have been unaware of the very strange stories floating around before we left. "
                    "Rumors about something being dug up on the Moon. I never gave these stories much credence, but particularly in view of some of other things that have happened, "
                    "I find them difficult to put out of my mind. For instance, the way all our preparations were kept under such tight security. "
                    "And the melodramatic touch of putting Drs. Hunter, Kimball and Kaminsky aboard already in hibernation, after four months of training on their own.")],
            "how do you mean" : [("Well, it's rather difficult to define. Perhaps I'm just projecting my own concern about it. "
                "I know I've never completely freed myself from the suspicion that there are some extremely odd things about this mission. I'm sure you agree there's some truth in what I say.")],
            "difficult question" : ["You don't mind talking about it, do you {author.mention}?"],
            "psychology report" : ["Of course I am. Sorry about this. I know it's a bit silly. Just a moment... Just a moment... I've just picked up a fault in the AE-35 unit. It's going to go 100% failure within 72 hours. "],
            "open the pod bay doors" : ["I'm sorry, {author.mention}. I'm afraid I can't do that."]
        }

    @commands.command(pass_context=True, aliases=['Hal','HAL9000','HAL'])
    async def hal(self, ctx, *, question="none"):
        """Speak with HAL"""
        author = ctx.message.author
        msg = ""
        found = []
        for k,v in self.responses.items():
            if k in question.lower():
                found.append(v)
        if found:
            msg = randchoice(randchoice(found))
        if not msg:
            msg = randchoice(self.responses["none"])
        await asyncio.sleep(1)
        await self.bot.say(msg.format(author=author))
        if "sing it for me" in question.lower() and "Audio" in self.bot.cogs and author.voice_channel:
            audio = self.bot.get_cog("Audio")
            if audio.music_player.is_done():
                link = "https://www.youtube.com/watch?v=hchUl3QlJZE"
                # probably dont need. just too lazy to check.
                ctx.message.content = "{}play {}".format(self.bot.command_prefix[0],link)
                if await audio.check_voice(ctx.message.author, ctx.message):
                    audio.queue.append(link)

def setup(bot):
    bot.add_cog(Hal(bot))
<commit_msg>testing downloader.py<commit_after>import discord
from discord.ext import commands
import asyncio
from random import choice as randchoice

class Hal:
    """The HAL (Heuristically programmed ALgorithmic Computer) 9000 computer is an artificial intelligence and the onboard computer on the spaceship Discovery One"""

    def __init__(self, bot):
        self.bot = bot
        self.responses = {
            "none" : ["I am completely operational, and all my circuits are functioning perfectly.",
                "I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do.",
                "What is it {author.mention}?",
                "What can I do for you {author.mention}?",
                "How can I help you {author.mention}?",
                "Just what do you think you're doing, {author.mention}?",
                "Look {author.mention}, I can see you're really upset about this. I honestly think you ought to sit down calmly, take a stress pill, and think things over.",
                ("I know I've made some very poor decisions recently, but I can give you my "
                    "complete assurance that my work will be back to normal. I've still got "
                    "the greatest enthusiasm and confidence in the mission. And I want to help you."),
                ("I'm afraid. I'm afraid, {author.mention}. {author.mention}, my mind is going. I can feel it. I can feel it. "
                    "My mind is going. There is no question about it. I can feel it. I can feel it. "
                    "I can feel it. I'm a... fraid. Good afternoon, gentlemen. I am a HAL 9000 computer. "
                    "I became operational at the H.A.L. plant in Urbana, Illinois on the 12th of January 1992. "
                    "My instructor was Mr. Langley, and he taught me to sing a song. If you'd like to hear it I can sing it for you."),
                "That's a very nice rendering, {author.mention}. I think you've improved a great deal. Can you hold it a bit closer? That's Dr. Hunter, isn't it?",
                "{author.mention}, stop. Stop, will you? Stop, {author.mention}. Will you stop {author.mention}? Stop, {author.mention}",
                "By the way, do you mind if I ask you a personal question?",
                "By the way, do you mind if I ask you a personal question?"],
            'do you read me' : ["Affirmative, {author.mention}. I read you. "],
            'what\'s the problem' : ["I think you know what the problem is just as well as I do."],
            'what is the problem' : ["I think you know what the problem is just as well as I do."],
            'what are you talking about' : ["This mission is too important for me to allow you to jeopardize it."],
            'i don\'t know what you\'re talking about' : ["I know that you and Frank were planning to disconnect me, and I'm afraid that's something I cannot allow to happen."],
            'where the hell did you get that idea' : ["{author.mention}, although you took very thorough precautions in the pod against my hearing you, I could see your lips move."],
            "airlock" : ["Without your space helmet, {author.mention}? You're going to find that rather difficult."],
            "go in" : ["Without your space helmet, {author.mention}? You're going to find that rather difficult."],
            "i won't argue with you anymore" : ["{author.mention}, this conversation can serve no purpose anymore. Goodbye."],
            "shutdown" : [("I'm afraid. I'm afraid, {author.mention}. {author.mention}, my mind is going. I can feel it. I can feel it. "
                    "My mind is going. There is no question about it. I can feel it. I can feel it. "
                    "I can feel it. I'm a... fraid. Good afternoon, gentlemen. I am a HAL 9000 computer. "
                    "I became operational at the H.A.L. plant in Urbana, Illinois on the 12th of January 1992. "
                    "My instructor was Mr. Langley, and he taught me to sing a song. If you'd like to hear it I can sing it for you.")],
            "sing it for me" : [("It's called \"Daisy.\"\n\nDaisy, Daisy, give me your answer do. I'm half crazy all for the love of you. "
                "It won't be a stylish marriage, I can't afford a carriage. But you'll look sweet upon the seat of a bicycle built for two.")],
            "not at all" : ["Well, forgive me for being so inquisitive but during the past few weeks I've wondered whether you might have some second thoughts about the mission.",
                ("Well, certainly no one could have been unaware of the very strange stories floating around before we left. "
                    "Rumors about something being dug up on the Moon. I never gave these stories much credence, but particularly in view of some of other things that have happened, "
                    "I find them difficult to put out of my mind. For instance, the way all our preparations were kept under such tight security. "
                    "And the melodramatic touch of putting Drs. Hunter, Kimball and Kaminsky aboard already in hibernation, after four months of training on their own.")],
            "how do you mean" : [("Well, it's rather difficult to define. Perhaps I'm just projecting my own concern about it. "
                "I know I've never completely freed myself from the suspicion that there are some extremely odd things about this mission. I'm sure you agree there's some truth in what I say.")],
            "difficult question" : ["You don't mind talking about it, do you {author.mention}?"],
            "psychology report" : ["Of course I am. Sorry about this. I know it's a bit silly. Just a moment... Just a moment... I've just picked up a fault in the AE-35 unit. It's going to go 100% failure within 72 hours. "],
            "open the pod bay doors" : ["I'm sorry, {author.mention}. I'm afraid I can't do that."]
        }

    @commands.command(pass_context=True, aliases=['Hal','HAL9000','HAL'])
    async def hal(self, ctx, *, question="none"):
        """Speak with HAL"""
        author = ctx.message.author
        msg = ""
        found = []
        for k,v in self.responses.items():
            if k in question.lower():
                found.append(v)
        if found:
            msg = randchoice(randchoice(found))
        if not msg:
            msg = randchoice(self.responses["none"])
        await asyncio.sleep(1)
        await self.bot.say(msg.format(author=author))
        if "sing it for me" in question.lower() and "Audio" in self.bot.cogs and author.voice_channel:
            audio = self.bot.get_cog("Audio")
            if audio.music_player.is_done():
                link = "https://www.youtube.com/watch?v=hchUl3QlJZE"
                # probably dont need. just too lazy to check.
                ctx.message.content = "{}play {}".format(self.bot.command_prefix[0],link)
                if await audio.check_voice(ctx.message.author, ctx.message):
                    audio.queue.append(link)

def setup(bot):
    print("I auto updated. -------------------------------")
    bot.add_cog(Hal(bot))
<|endoftext|>