<commit_before>""" The CLI interface for aomi """
from __future__ import print_function
import os
import sys
from argparse import ArgumentParser
import aomi.vault
import aomi.render
import aomi.template
import aomi.validation
import aomi.util
import aomi.filez
import aomi.seed_action
from aomi.helpers import VERSION as version
from aomi.error import unhandled

def extract_file_args(subparsers):
    """Add the command line options for the extract_file operation"""
    extract_parser = subparsers.add_parser('extract_file')
    extract_parser.add_argument('vault_path',
                                help='Full path (including key) to secret')
    extract_parser.add_argument('destination',
                                help='Location of destination file')
    base_args(extract_parser)

def mapping_args(parser):
    """Add various variable mapping command line options to the parser"""
    parser.add_argument('--add-prefix',
                        dest='add_prefix',
                        help='Specify a prefix to use when '
                        'generating secret key names')
    parser.add_argument('--add-suffix',
                        dest='add_suffix',
                        help='Specify a suffix to use when '
                        'generating secret key names')
    parser.add_argument('--merge-path',
                        dest='merge_path',
                        action='store_true',
                        default=True,
                        help='merge vault path and key name')
    parser.add_argument('--no-merge-path',
                        dest='merge_path',
                        action='store_false',
                        default=True,
                        help='do not merge vault path and key name')
    parser.add_argument('--key-map',
                        dest='key_map',
                        action='append',
                        type=str,
                        default=[])

def export_arg(parser):
    """Add the export argument to a parser"""
    parser.add_argument('--export',
                        dest='export',
                        help='Export declared variables',
                        action='store_true')

def aws_env_args(subparsers):
    """Add command line options for the aws_environment operation"""
    env_parser = subparsers.add_parser('aws_environment')
    env_parser.add_argument('vault_path',
                            help='Full path(s) to the AWS secret')
    export_arg(env_parser)
    base_args(env_parser)

def environment_args(subparsers):
    """Add command line options for the environment operation"""
    env_parser = subparsers.add_parser('environment')
    env_parser.add_argument('vault_paths',
                            help='Full path(s) to secret',
                            nargs='+')
    env_parser.add_argument('--prefix',
                            dest='prefix',
                            help='Old style prefix to use when'
                            'generating secret key names')
    export_arg(env_parser)
    mapping_args(env_parser)
    base_args(env_parser)

def template_args(subparsers):
    """Add command line options for the template operation"""
    template_parser = subparsers.add_parser('template')
    template_parser.add_argument('template',
                                 help='Template source',
                                 nargs='?')
    template_parser.add_argument('destination',
                                 help='Path to write rendered template',
                                 nargs='?')
    template_parser.add_argument('vault_paths',
                                 help='Full path(s) to secret',
                                 nargs='*')
    template_parser.add_argument('--builtin-list',
                                 dest='builtin_list',
                                 help='Display a list of builtin templates',
                                 action='store_true',
                                 default=False)
    template_parser.add_argument('--builtin-info',
                                 dest='builtin_info',
                                 help='Display information on a '
                                 'particular builtin template')
    vars_args(template_parser)
    mapping_args(template_parser)
    base_args(template_parser)

def secretfile_args(parser):
    """Add Secretfile management command line arguments to parser"""
    parser.add_argument('--secrets',
                        dest='secrets',
                        help='Path where secrets are stored',
                        default=os.path.join(os.getcwd(), ".secrets"))
    parser.add_argument('--policies',
                        dest='policies',
                        help='Path where policies are stored',
                        default=os.path.join(os.getcwd(), "vault", ""))
    parser.add_argument('--secretfile',
                        dest='secretfile',
                        help='Secretfile to use',
                        default=os.path.join(os.getcwd(), "Secretfile"))
    parser.add_argument('--tags',
                        dest='tags',
                        help='Tags of things to seed',
                        default=[],
                        type=str,
                        action='append')
    parser.add_argument('--include',
                        dest='include',
                        help='Specify paths to include',
                        default=[],
                        type=str,
                        action='append')
    parser.add_argument('--exclude',
                        dest='exclude',
                        help='Specify paths to exclude',
                        default=[],
                        type=str,
                        action='append')

def base_args(parser):
    """Add the generic command line options"""
    parser.add_argument('--verbose',
                        dest='verbose',
                        help='Verbose output',
                        action='store_true')
    parser.add_argument('--metadata',
                        dest='metadata',
                        help='A series of key=value pairs for token metadata.',
                        default='')
    parser.add_argument('--lease',
                        dest='lease',
                        help='Lease time for intermediary token.',
                        default='10s')
    parser.add_argument('--reuse-token',
                        dest='reuse_token',
                        help='Whether to reuse the existing token. Note this will' \
                        ' cause metadata to not be preserved',
                        action='store_true')

def seed_args(subparsers):
    """Add command line options for the seed operation"""
    seed_parser = subparsers.add_parser('seed')
    secretfile_args(seed_parser)
    vars_args(seed_parser)
    seed_parser.add_argument('--mount-only',
                             dest='mount_only',
                             help='Only mount paths if needed',
                             default=False,
                             action='store_true')
    seed_parser.add_argument('--thaw-from',
                             dest='thaw_from',
                             help='Thaw an ICE file containing secrets')
    base_args(seed_parser)

def archive_args(parser):
    """Add the command line options for archive related operations"""
    parser.add_argument('icefile',
                        help='Path to the encrypted archive'
                        'file of frozen secrets')

def thaw_args(subparsers):
    """Add command line options for the thaw operation"""
    thaw_parser = subparsers.add_parser('thaw')
    secretfile_args(thaw_parser)
    archive_args(thaw_parser)
    vars_args(thaw_parser)
    base_args(thaw_parser)

def freeze_args(subparsers):
    """Add command line options for the freeze operation"""
    freeze_parser = subparsers.add_parser('freeze')
    secretfile_args(freeze_parser)
    archive_args(freeze_parser)
    vars_args(freeze_parser)
    base_args(freeze_parser)

def password_args(subparsers):
    """Add command line options for the set_password operation"""
    password_parser = subparsers.add_parser('set_password')
    password_parser.add_argument('vault_path',
                                 help='Path which contains password'
                                 'secret to be udpated')
    base_args(password_parser)

def vars_args(parser):
    """Add various command line options for external vars"""
    parser.add_argument('--extra-vars',
                        dest='extra_vars',
                        help='Extra template variables',
                        default=[],
                        type=str,
                        action='append')
    parser.add_argument('--extra-vars-file',
                        dest='extra_vars_file',
                        help='YAML files full of variables',
                        default=[],
                        type=str,
                        action='append')

def token_args(subparsers):
    """Add the CLI options for the token operation"""
    token_parser = subparsers.add_parser('token')
    base_args(token_parser)

def parser_factory(fake_args=None):
    """Return a proper contextual OptionParser"""
    parser = ArgumentParser(description='aomi')
    subparsers = parser.add_subparsers(dest='operation',
                                       help='aomi operation')
    extract_file_args(subparsers)
    environment_args(subparsers)
    aws_env_args(subparsers)
    seed_args(subparsers)
    freeze_args(subparsers)
    thaw_args(subparsers)
    template_args(subparsers)
    password_args(subparsers)
    token_args(subparsers)
    subparsers.add_parser('help')

    if fake_args is None:
        return parser, parser.parse_args()

    return parser, parser.parse_args(fake_args)

def parse_extra_vars(extra_vars):
    """Parse out a hash from a list of key=value strings"""
    ev_obj = {}
    for extra_var in extra_vars:
        key, val = extra_var.split('=')
        ev_obj[key] = val

    return ev_obj

def template_runner(client, parser, args):
    """Executes template related operations"""
    if args.builtin_list:
        aomi.template.builtin_list()
    elif args.builtin_info:
        aomi.template.builtin_info(args.builtin_info)
    elif args.template and args.destination and args.vault_paths:
        aomi.render.template(client, args.template,
                             args.destination,
                             args.vault_paths,
                             args)
    else:
        parser.print_usage()
        sys.exit(2)

    sys.exit(0)

def action_runner(parser, args):
    """Run appropriate action, or throw help"""

    if args.operation == 'help':
        print("aomi v%s" % version)
        print("Get started with aomi https://autodesk.github.io/aomi/quickstart")
        parser.print_help()
        sys.exit(0)

    client = aomi.vault.client(args.operation, args)
    if args.operation == 'extract_file':
        aomi.render.raw_file(client, args.vault_path, args.destination, args)
        sys.exit(0)
    elif args.operation == 'environment':
        aomi.render.env(client, args.vault_paths, args)
        sys.exit(0)
    elif args.operation == 'aws_environment':
        aomi.render.aws(client, args.vault_path, args)
        sys.exit(0)
    elif args.operation == 'seed':
        aomi.validation.gitignore(args)
        aomi.seed_action.seed(client, args)
        sys.exit(0)
    elif args.operation == 'template':
        template_runner(client, parser, args)
    elif args.operation == 'token':
        print(client.token)
        sys.exit(0)
    elif args.operation == 'set_password':
        aomi.util.password(client, args.vault_path, args)
        sys.exit(0)
    elif args.operation == 'freeze':
        aomi.filez.freeze(args.icefile, args)
        sys.exit(0)
    elif args.operation == 'thaw':
        aomi.filez.thaw(args.icefile, args)
        sys.exit(0)

    parser.print_usage()
    sys.exit(2)

def main():
    """Entrypoint, sweet Entrypoint"""
    parser, args = parser_factory()
    try:
        action_runner(parser, args)

    # this is our uncaught handler so yes we want to actually
    # catch every error. the format may vary based on the error handler tho
    except Exception as uncaught:  # pylint: disable=broad-except
        unhandled(uncaught, args)
        sys.exit(1)
<commit_msg>forgot to lint<commit_after>""" The CLI interface for aomi """
from __future__ import print_function
import os
import sys
from argparse import ArgumentParser
import aomi.vault
import aomi.render
import aomi.template
import aomi.validation
import aomi.util
import aomi.filez
import aomi.seed_action
from aomi.helpers import VERSION as version
from aomi.error import unhandled

def extract_file_args(subparsers):
    """Add the command line options for the extract_file operation"""
    extract_parser = subparsers.add_parser('extract_file')
    extract_parser.add_argument('vault_path',
                                help='Full path (including key) to secret')
    extract_parser.add_argument('destination',
                                help='Location of destination file')
    base_args(extract_parser)

def mapping_args(parser):
    """Add various variable mapping command line options to the parser"""
    parser.add_argument('--add-prefix',
                        dest='add_prefix',
                        help='Specify a prefix to use when '
                        'generating secret key names')
    parser.add_argument('--add-suffix',
                        dest='add_suffix',
                        help='Specify a suffix to use when '
                        'generating secret key names')
    parser.add_argument('--merge-path',
                        dest='merge_path',
                        action='store_true',
                        default=True,
                        help='merge vault path and key name')
    parser.add_argument('--no-merge-path',
                        dest='merge_path',
                        action='store_false',
                        default=True,
                        help='do not merge vault path and key name')
    parser.add_argument('--key-map',
                        dest='key_map',
                        action='append',
                        type=str,
                        default=[])

def export_arg(parser):
    """Add the export argument to a parser"""
    parser.add_argument('--export',
                        dest='export',
                        help='Export declared variables',
                        action='store_true')

def aws_env_args(subparsers):
    """Add command line options for the aws_environment operation"""
    env_parser = subparsers.add_parser('aws_environment')
    env_parser.add_argument('vault_path',
                            help='Full path(s) to the AWS secret')
    export_arg(env_parser)
    base_args(env_parser)

def environment_args(subparsers):
    """Add command line options for the environment operation"""
    env_parser = subparsers.add_parser('environment')
    env_parser.add_argument('vault_paths',
                            help='Full path(s) to secret',
                            nargs='+')
    env_parser.add_argument('--prefix',
                            dest='prefix',
                            help='Old style prefix to use when'
                            'generating secret key names')
    export_arg(env_parser)
    mapping_args(env_parser)
    base_args(env_parser)

def template_args(subparsers):
    """Add command line options for the template operation"""
    template_parser = subparsers.add_parser('template')
    template_parser.add_argument('template',
                                 help='Template source',
                                 nargs='?')
    template_parser.add_argument('destination',
                                 help='Path to write rendered template',
                                 nargs='?')
    template_parser.add_argument('vault_paths',
                                 help='Full path(s) to secret',
                                 nargs='*')
    template_parser.add_argument('--builtin-list',
                                 dest='builtin_list',
                                 help='Display a list of builtin templates',
                                 action='store_true',
                                 default=False)
    template_parser.add_argument('--builtin-info',
                                 dest='builtin_info',
                                 help='Display information on a '
                                 'particular builtin template')
    vars_args(template_parser)
    mapping_args(template_parser)
    base_args(template_parser)

def secretfile_args(parser):
    """Add Secretfile management command line arguments to parser"""
    parser.add_argument('--secrets',
                        dest='secrets',
                        help='Path where secrets are stored',
                        default=os.path.join(os.getcwd(), ".secrets"))
    parser.add_argument('--policies',
                        dest='policies',
                        help='Path where policies are stored',
                        default=os.path.join(os.getcwd(), "vault", ""))
    parser.add_argument('--secretfile',
                        dest='secretfile',
                        help='Secretfile to use',
                        default=os.path.join(os.getcwd(), "Secretfile"))
    parser.add_argument('--tags',
                        dest='tags',
                        help='Tags of things to seed',
                        default=[],
                        type=str,
                        action='append')
    parser.add_argument('--include',
                        dest='include',
                        help='Specify paths to include',
                        default=[],
                        type=str,
                        action='append')
    parser.add_argument('--exclude',
                        dest='exclude',
                        help='Specify paths to exclude',
                        default=[],
                        type=str,
                        action='append')

def base_args(parser):
    """Add the generic command line options"""
    parser.add_argument('--verbose',
                        dest='verbose',
                        help='Verbose output',
                        action='store_true')
    parser.add_argument('--metadata',
                        dest='metadata',
                        help='A series of key=value pairs for token metadata.',
                        default='')
    parser.add_argument('--lease',
                        dest='lease',
                        help='Lease time for intermediary token.',
                        default='10s')
    parser.add_argument('--reuse-token',
                        dest='reuse_token',
                        help='Whether to reuse the existing token. Note'
                        ' this will cause metadata to not be preserved',
                        action='store_true')

def seed_args(subparsers):
    """Add command line options for the seed operation"""
    seed_parser = subparsers.add_parser('seed')
    secretfile_args(seed_parser)
    vars_args(seed_parser)
    seed_parser.add_argument('--mount-only',
                             dest='mount_only',
                             help='Only mount paths if needed',
                             default=False,
                             action='store_true')
    seed_parser.add_argument('--thaw-from',
                             dest='thaw_from',
                             help='Thaw an ICE file containing secrets')
    base_args(seed_parser)

def archive_args(parser):
    """Add the command line options for archive related operations"""
    parser.add_argument('icefile',
                        help='Path to the encrypted archive'
                        'file of frozen secrets')

def thaw_args(subparsers):
    """Add command line options for the thaw operation"""
    thaw_parser = subparsers.add_parser('thaw')
    secretfile_args(thaw_parser)
    archive_args(thaw_parser)
    vars_args(thaw_parser)
    base_args(thaw_parser)

def freeze_args(subparsers):
    """Add command line options for the freeze operation"""
    freeze_parser = subparsers.add_parser('freeze')
    secretfile_args(freeze_parser)
    archive_args(freeze_parser)
    vars_args(freeze_parser)
    base_args(freeze_parser)

def password_args(subparsers):
    """Add command line options for the set_password operation"""
    password_parser = subparsers.add_parser('set_password')
    password_parser.add_argument('vault_path',
                                 help='Path which contains password'
                                 'secret to be udpated')
    base_args(password_parser)

def vars_args(parser):
    """Add various command line options for external vars"""
    parser.add_argument('--extra-vars',
                        dest='extra_vars',
                        help='Extra template variables',
                        default=[],
                        type=str,
                        action='append')
    parser.add_argument('--extra-vars-file',
                        dest='extra_vars_file',
                        help='YAML files full of variables',
                        default=[],
                        type=str,
                        action='append')

def token_args(subparsers):
    """Add the CLI options for the token operation"""
    token_parser = subparsers.add_parser('token')
    base_args(token_parser)

def parser_factory(fake_args=None):
    """Return a proper contextual OptionParser"""
    parser = ArgumentParser(description='aomi')
    subparsers = parser.add_subparsers(dest='operation',
                                       help='aomi operation')
    extract_file_args(subparsers)
    environment_args(subparsers)
    aws_env_args(subparsers)
    seed_args(subparsers)
    freeze_args(subparsers)
    thaw_args(subparsers)
    template_args(subparsers)
    password_args(subparsers)
    token_args(subparsers)
    subparsers.add_parser('help')

    if fake_args is None:
        return parser, parser.parse_args()

    return parser, parser.parse_args(fake_args)

def parse_extra_vars(extra_vars):
    """Parse out a hash from a list of key=value strings"""
    ev_obj = {}
    for extra_var in extra_vars:
        key, val = extra_var.split('=')
        ev_obj[key] = val

    return ev_obj

def template_runner(client, parser, args):
    """Executes template related operations"""
    if args.builtin_list:
        aomi.template.builtin_list()
    elif args.builtin_info:
        aomi.template.builtin_info(args.builtin_info)
    elif args.template and args.destination and args.vault_paths:
        aomi.render.template(client, args.template,
                             args.destination,
                             args.vault_paths,
                             args)
    else:
        parser.print_usage()
        sys.exit(2)

    sys.exit(0)

def action_runner(parser, args):
    """Run appropriate action, or throw help"""

    if args.operation == 'help':
        print("aomi v%s" % version)
        print('Get started with aomi'
              ' https://autodesk.github.io/aomi/quickstart')
        parser.print_help()
        sys.exit(0)

    client = aomi.vault.client(args.operation, args)
    if args.operation == 'extract_file':
        aomi.render.raw_file(client, args.vault_path, args.destination, args)
        sys.exit(0)
    elif args.operation == 'environment':
        aomi.render.env(client, args.vault_paths, args)
        sys.exit(0)
    elif args.operation == 'aws_environment':
        aomi.render.aws(client, args.vault_path, args)
        sys.exit(0)
    elif args.operation == 'seed':
        aomi.validation.gitignore(args)
        aomi.seed_action.seed(client, args)
        sys.exit(0)
    elif args.operation == 'template':
        template_runner(client, parser, args)
    elif args.operation == 'token':
        print(client.token)
        sys.exit(0)
    elif args.operation == 'set_password':
        aomi.util.password(client, args.vault_path, args)
        sys.exit(0)
    elif args.operation == 'freeze':
        aomi.filez.freeze(args.icefile, args)
        sys.exit(0)
    elif args.operation == 'thaw':
        aomi.filez.thaw(args.icefile, args)
        sys.exit(0)

    parser.print_usage()
    sys.exit(2)

def main():
    """Entrypoint, sweet Entrypoint"""
    parser, args = parser_factory()
    try:
        action_runner(parser, args)

    # this is our uncaught handler so yes we want to actually
    # catch every error. the format may vary based on the error handler tho
    except Exception as uncaught:  # pylint: disable=broad-except
        unhandled(uncaught, args)
        sys.exit(1)
<|endoftext|>


<commit_before>from django.conf.urls import patterns, url, include
import cog.views
import django_openid_auth.views
import django.contrib.auth.views
import django.views
from cog.models import settings

urlpatterns = [

    # FIXME: top-level index
    #url(r'^index/$', TemplateView.as_view(template_name="cog/index.html")),

    # site home
    url(r'^$', cog.views.site_home, name='site_home' ) ,

    # COG administration
    url(r'^cogadmin/projects/$', cog.views.admin_projects, name='admin_projects' ),
    url(r'^cogadmin/peers/$', cog.views.admin_peers, name='admin_peers' ),
    url(r'^cogadmin/users/$', cog.views.admin_users, name='admin_users' ),

    url(r'^search/(?P<project_short_name>.+)/$', cog.views.search, name='search' ),
    url(r'^search_profile/config/(?P<project_short_name>.+)/$', cog.views.search_profile_config, name='search_profile_config'),
    url(r'^search_profile/export/(?P<project_short_name>.+)/$', cog.views.search_profile_export, name='search_profile_export'),
    url(r'^search_profile/import/(?P<project_short_name>.+)/$', cog.views.search_profile_import, name='search_profile_import'),
    url(r'^search_profile/order/(?P<project_short_name>.+)/$', cog.views.search_profile_order, name='search_profile_order' ),
    url(r'^search_facet/add/(?P<project_short_name>.+)/$', cog.views.search_facet_add, name='search_facet_add'),
    url(r'^search_facet/update/(?P<facet_id>.+)/$', cog.views.search_facet_update, name='search_facet_update'),
    url(r'^search_facet/delete/(?P<facet_id>.+)/$', cog.views.search_facet_delete, name='search_facet_delete'),
    url(r'^search_group/add/(?P<project_short_name>.+)/$', cog.views.search_group_add, name='search_group_add'),
    url(r'^search_group/update/(?P<group_id>.+)/$', cog.views.search_group_update, name='search_group_update'),
    url(r'^search_group/delete/(?P<group_id>.+)/$', cog.views.search_group_delete, name='search_group_delete'),
    url(r'^search_files/(?P<dataset_id>.+)/(?P<index_node>.+)/$', cog.views.search_files, name='search_files'),
    url(r'^metadata_display/(?P<project_short_name>.+)/$', cog.views.metadata_display, name='metadata_display' ),
    url(r'^search_reload/$', cog.views.search_reload, name='search_reload' ),

    # authentication options
    # a) django (username/password) login
    #url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'cog/account/login.html'}, name='login'),
    url(r'^login2/$', django.contrib.auth.views.login, {'template_name': 'cog/account/login.html'}, name='login'),

    # b) combined django + openid login
    #url(r'^login/$', custom_login, {'template_name': 'cog/openid/login2.html'}, name='login'),
    #url(r'^openid/login/$', 'django_openid_auth.views.login_begin', {'template_name': 'cog/openid/login2.html'}, name='openid-login'),

    # c) openid-only login
    url(r'^login/$', cog.views.custom_login, {'template_name': 'cog/openid/login.html'}, name='login'),
    url(r'^openid/login/$', django_openid_auth.views.login_begin, {'template_name': 'cog/openid/login.html'}, name='openid-login'),

    # b) or c)
    #url(r'^openid/complete/$', 'django_openid_auth.views.login_complete', name='openid-complete'),
    url(r'^openid/complete/$', cog.views.custom_login_complete, name='openid-complete'),
    url(r'^openid/logo.gif$', django_openid_auth.views.logo, name='openid-logo'),

    # force redirection to login page after logout
    #url(r'^logout/$', 'django.contrib.auth.views.logout_then_login', name='logout'),
    # use next=... to redirect to previous page after logout
    url(r'^logout/$', django.contrib.auth.views.logout, name='logout'),

    # user management
    url(r'^user/add/$', cog.views.user_add, name='user_add' ),
    url(r'^user/update/(?P<user_id>\d+)/$', cog.views.user_update, name='user_update' ),
    url(r'^user/delete/(?P<user_id>\d+)/$', cog.views.user_delete, name='user_delete' ),
    url(r'^user/detail/(?P<user_id>\d+)/$', cog.views.user_detail, name='user_detail'),
    url(r'^password/update/(?P<user_id>\d+)/$', cog.views.password_update, name='password_update'),
    url(r'^password/reset/$', cog.views.password_reset, name='password_reset'),
    url(r'^user/reminder/$', cog.views.user_reminder, name='user_reminder'),
    url(r'^user/byopenid/$', cog.views.user_byopenid, name='user_byopenid'),
    url(r'^user/image/$', cog.views.user_image, name='user_image'),
    url(r'^user/profile/(?P<user_id>\d+)/$', cog.views.user_profile_redirect, name='user_profile_redirect'),

    # data cart
    url(r'^datacart/display/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_display, name='datacart_display'),
    url(r'^datacart/add/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_add, name='datacart_add'),
    url(r'^datacart/delete/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_delete, name='datacart_delete'),
    url(r'^datacart/empty/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_empty, name='datacart_empty'),
    url(r'^datacart/wget/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_wget, name='datacart_wget'),
    url(r'^datacart/add_all/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_add_all, name='datacart_add_all'),
    url(r'^datacart/delete_all/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_delete_all, name='datacart_delete_all'),
    url(r'^datacart/byopenid/$', cog.views.datacart_byopenid, name='datacart_byopenid'),

    # projects
    url(r'^project/add/$', cog.views.project_add, name='project_add' ),
    url(r'^project/update/(?P<project_short_name>.+)/$', cog.views.project_update, name='project_update' ),
    url(r'^project/delete/(?P<project_short_name>.+)/$', cog.views.project_delete, name='project_delete' ),
    url(r'^project/index/(?P<project_short_name>.+)/$', cog.views.project_index, name='project_index' ),

    # news
    url(r'^news/list/(?P<project_short_name>.+)/$', cog.views.news_list, name='news_list'),
    url(r'^news/add/(?P<project_short_name>.+)/$', cog.views.news_add, name='news_add'),
    url(r'^news/detail/(?P<news_id>\d+)/$', cog.views.news_detail, name='news_detail'),
    url(r'^news/update/(?P<news_id>\d+)/$', cog.views.news_update, name='news_update'),
    url(r'^news/delete/(?P<news_id>\d+)/$', cog.views.news_delete, name='news_delete'),

    # posts
    url(r'^post/add/(?P<project_short_name>.+)/$', cog.views.post_add, name='post_add'),
    url(r'^post/update/(?P<post_id>\d+)/$', cog.views.post_update, name='post_update'),
    url(r'^post/detail/(?P<post_id>\d+)/$', cog.views.post_detail, name='post_detail'),
    url(r'^post/list/(?P<project_short_name>.+)/$', cog.views.post_list, name='post_list'),
    url(r'^post/delete/(?P<post_id>\d+)/$', cog.views.post_delete, name='post_delete'),
    url(r'^post/cancel/(?P<post_id>\d+)/$', cog.views.post_cancel, name='post_cancel'),

    # documents
    url(r'^doc/add/(?P<project_short_name>.+)/$', cog.views.doc_add, name='doc_add'),
    url(r'^doc/detail/(?P<doc_id>\d+)/$', cog.views.doc_detail, name='doc_detail'),
    url(r'^doc/update/(?P<doc_id>\d+)/$', cog.views.doc_update, name='doc_update'),
    url(r'^doc/remove/(?P<doc_id>\d+)/$', cog.views.doc_remove, name='doc_remove'),
    url(r'^doc/list/(?P<project_short_name>.+)/$', cog.views.doc_list, name='doc_list'),
     url(r'^doc/upload/(?P<project_short_name>.+)/$', cog.views.doc_upload, name='doc_upload'),

    # posts and documents
    url(r'^post/add_doc/(?P<post_id>\d+)/$', cog.views.post_add_doc, name='post_add_doc'),
    url(r'^post/remove_doc/(?P<post_id>\d+)/(?P<doc_id>\d+)/$', cog.views.post_remove_doc, name='post_remove_doc'),

    # signals
    url(r'^signal/list/(?P<project_short_name>.+)/$', cog.views.signal_list, name='signal_list'),

    # project membership
    url(r'^membership/request/(?P<project_short_name>[^/]+)/$', cog.views.membership_request, name='membership_request' ),
    url(r'^membership/list/enrolled/(?P<project_short_name>[^/]+)/$', cog.views.membership_list_enrolled, name='membership_list_enrolled' ),
    url(r'^membership/list/requested/(?P<project_short_name>[^/]+)/$', cog.views.membership_list_requested, name='membership_list_requested' ),
    url(r'^membership/list/all/(?P<project_short_name>[^/]+)/$', cog.views.membership_list_all, name='membership_list_all' ),
    url(r'^membership/process/(?P<project_short_name>[^/]+)/$', cog.views.membership_process, name='membership_process' ),
    url(r'^membership/remove/(?P<project_short_name>[^/]+)/$', cog.views.membership_remove, name='membership_remove' ),

    # group membership (data access control)
    url(r'^ac/subscribe/(?P<group_name>[^/]+)/$', cog.views.ac_subscribe, name='ac_subscribe' ),
    url(r'^ac/process/(?P<group_name>[^/]+)/(?P<user_id>\d+)/$', cog.views.ac_process, name='ac_process' ),
    url(r'^ac/list/$', cog.views.ac_list, name='ac_list' ),

    # project tags
    url(r'^projects/(?P<project_short_name>[^/]+)/tags/update/$', cog.views.tags_update, name='tags_update'),

    # project browser
    url(r'^project_browser/(?P<project_short_name>[^/]+)/browse/(?P<tab>[^/]+)/$', cog.views.project_browser, name='project_browser'),
    # the following matches on Apache httpd
    url(r'^project_browser/browse/(?P<tab>[^/]+)/$', cog.views.project_empty_browser, name='project_empty_browser'),
    # the following matches on django development server
    url(r'^project_browser//browse/(?P<tab>[^/]+)/$', cog.views.project_empty_browser, name='project_empty_browser'),
    # save/delete user tags
    url(r'^project_browser/save_user_tag/', cog.views.save_user_tag, name='save_user_tag'),
    url(r'^project_browser/delete_user_tag/', cog.views.delete_user_tag, name='delete_user_tag'),

    # NAVBAR URLs
    url(r'', include('cog.urls_navbar')),

    # project generic pages
    # Note: these URLs must come last because the last URL matches everything within the project!
    #url(r'^projects/$', 'cog.views.index', name='unspecified_project'),
    url(r'^projects/(?P<project_short_name>[^/]+)/$', cog.views.project_home, name='project_home'),
    url(r'^projects/(?P<project_short_name>[^/]+)/.+$', cog.views.page_detail, name='page_detail'),

    # resized project media (must be served without any access control since they are not wrapped by "Doc" objects)
    url(r'^site_media/(?P<path>.*_thumbnail.*)$', django.views.static.serve, {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_small.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_medium.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_big.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_large.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    # project media
    url(r'^site_media/projects/(?P<path>.*)$', cog.views.doc_download, name='doc_download'),
    # project data
    #url(r'^site_media/data/(?P<path>.*)$', 'cog.views.data_download', name='data_download'),

    # information shared with other sites
    url(r'^share/projects/$', cog.views.share_projects, name='share_projects'),
    url(r'^share/groups/$', cog.views.share_groups, name='share_groups'),
    url(r'^share/user/$', cog.views.share_user, name='share_user'),
    url(r'^share/sync/projects/$', cog.views.sync_projects, name='sync_projects'),

    # comments
    url(r'^comments/delete_comment/(?P<id>.*)/$', cog.views.views_common.deleteComment, name='delete_comment'),

    # Globus integration
    url(r'^globus/download/$', cog.views.views_globus.download, name='globus_download'),
    url(r'^globus/transfer/$', cog.views.views_globus.transfer, name='globus_transfer'),
    url(r'^globus/oauth/$', cog.views.views_globus.oauth, name='globus_oauth'),
    url(r'^globus/token/$', cog.views.views_globus.token, name='globus_token'),
    url(r'^globus/submit/$', cog.views.views_globus.submit, name='globus_submit'),
    url(r'^globus/script/$', cog.views.views_globus.script, name='globus_script'),

]
<commit_msg>Returning 404 not found for some URL extensions.<commit_after>from django.conf.urls import patterns, url, include
import cog.views
import django_openid_auth.views
import django.contrib.auth.views
from django.http.response import HttpResponseNotFound
import django.views
from cog.models import settings

urlpatterns = [

    # FIXME: top-level index
    #url(r'^index/$', TemplateView.as_view(template_name="cog/index.html")),

    # forbidden extensions
    url(r'.*\.asp$', HttpResponseNotFound),
    url(r'.*\.aspx$', HttpResponseNotFound),
    url(r'.*\.cfm$', HttpResponseNotFound),
    url(r'.*\.cgi$', HttpResponseNotFound),
    url(r'.*\.jsp$', HttpResponseNotFound),
    url(r'.*\.php$', HttpResponseNotFound),
    url(r'.*\.php3$', HttpResponseNotFound),
    url(r'.*\.pl$', HttpResponseNotFound),
    url(r'.*\.shtml$', HttpResponseNotFound),

    # site home
    url(r'^$', cog.views.site_home, name='site_home' ) ,

    # COG administration
    url(r'^cogadmin/projects/$', cog.views.admin_projects, name='admin_projects' ),
    url(r'^cogadmin/peers/$', cog.views.admin_peers, name='admin_peers' ),
    url(r'^cogadmin/users/$', cog.views.admin_users, name='admin_users' ),

    url(r'^search/(?P<project_short_name>.+)/$', cog.views.search, name='search' ),
    url(r'^search_profile/config/(?P<project_short_name>.+)/$', cog.views.search_profile_config, name='search_profile_config'),
    url(r'^search_profile/export/(?P<project_short_name>.+)/$', cog.views.search_profile_export, name='search_profile_export'),
    url(r'^search_profile/import/(?P<project_short_name>.+)/$', cog.views.search_profile_import, name='search_profile_import'),
    url(r'^search_profile/order/(?P<project_short_name>.+)/$', cog.views.search_profile_order, name='search_profile_order' ),
    url(r'^search_facet/add/(?P<project_short_name>.+)/$', cog.views.search_facet_add, name='search_facet_add'),
    url(r'^search_facet/update/(?P<facet_id>.+)/$', cog.views.search_facet_update, name='search_facet_update'),
    url(r'^search_facet/delete/(?P<facet_id>.+)/$', cog.views.search_facet_delete, name='search_facet_delete'),
    url(r'^search_group/add/(?P<project_short_name>.+)/$', cog.views.search_group_add, name='search_group_add'),
    url(r'^search_group/update/(?P<group_id>.+)/$', cog.views.search_group_update, name='search_group_update'),
    url(r'^search_group/delete/(?P<group_id>.+)/$', cog.views.search_group_delete, name='search_group_delete'),
    url(r'^search_files/(?P<dataset_id>.+)/(?P<index_node>.+)/$', cog.views.search_files, name='search_files'),
    url(r'^metadata_display/(?P<project_short_name>.+)/$', cog.views.metadata_display, name='metadata_display' ),
    url(r'^search_reload/$', cog.views.search_reload, name='search_reload' ),

    # authentication options
    # a) django (username/password) login
    #url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'cog/account/login.html'}, name='login'),
    url(r'^login2/$', django.contrib.auth.views.login, {'template_name': 'cog/account/login.html'}, name='login'),

    # b) combined django + openid login
    #url(r'^login/$', custom_login, {'template_name': 'cog/openid/login2.html'}, name='login'),
    #url(r'^openid/login/$', 'django_openid_auth.views.login_begin', {'template_name': 'cog/openid/login2.html'}, name='openid-login'),

    # c) openid-only login
    url(r'^login/$', cog.views.custom_login, {'template_name': 'cog/openid/login.html'}, name='login'),
    url(r'^openid/login/$', django_openid_auth.views.login_begin, {'template_name': 'cog/openid/login.html'}, name='openid-login'),

    # b) or c)
    #url(r'^openid/complete/$', 'django_openid_auth.views.login_complete', name='openid-complete'),
    url(r'^openid/complete/$', cog.views.custom_login_complete, name='openid-complete'),
    url(r'^openid/logo.gif$', django_openid_auth.views.logo, name='openid-logo'),

    # force redirection to login page after logout
    #url(r'^logout/$', 'django.contrib.auth.views.logout_then_login', name='logout'),
    # use next=... to redirect to previous page after logout
    url(r'^logout/$', django.contrib.auth.views.logout, name='logout'),

    # user management
    url(r'^user/add/$', cog.views.user_add, name='user_add' ),
    url(r'^user/update/(?P<user_id>\d+)/$', cog.views.user_update, name='user_update' ),
    url(r'^user/delete/(?P<user_id>\d+)/$', cog.views.user_delete, name='user_delete' ),
    url(r'^user/detail/(?P<user_id>\d+)/$', cog.views.user_detail, name='user_detail'),
    url(r'^password/update/(?P<user_id>\d+)/$', cog.views.password_update, name='password_update'),
    url(r'^password/reset/$', cog.views.password_reset, name='password_reset'),
    url(r'^user/reminder/$', cog.views.user_reminder, name='user_reminder'),
    url(r'^user/byopenid/$', cog.views.user_byopenid, name='user_byopenid'),
    url(r'^user/image/$', cog.views.user_image, name='user_image'),
    url(r'^user/profile/(?P<user_id>\d+)/$', cog.views.user_profile_redirect, name='user_profile_redirect'),

    # data cart
    url(r'^datacart/display/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_display, name='datacart_display'),
    url(r'^datacart/add/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_add, name='datacart_add'),
    url(r'^datacart/delete/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_delete, name='datacart_delete'),
    url(r'^datacart/empty/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_empty, name='datacart_empty'),
    url(r'^datacart/wget/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_wget, name='datacart_wget'),
    url(r'^datacart/add_all/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_add_all, name='datacart_add_all'),
    url(r'^datacart/delete_all/(?P<site_id>\d+)/(?P<user_id>\d+)/$', cog.views.datacart_delete_all, name='datacart_delete_all'),
    url(r'^datacart/byopenid/$', cog.views.datacart_byopenid, name='datacart_byopenid'),

    # projects
    url(r'^project/add/$', cog.views.project_add, name='project_add' ),
    url(r'^project/update/(?P<project_short_name>.+)/$', cog.views.project_update, name='project_update' ),
    url(r'^project/delete/(?P<project_short_name>.+)/$', cog.views.project_delete, name='project_delete' ),
    url(r'^project/index/(?P<project_short_name>.+)/$', cog.views.project_index, name='project_index' ),

    # news
    url(r'^news/list/(?P<project_short_name>.+)/$', cog.views.news_list, name='news_list'),
    url(r'^news/add/(?P<project_short_name>.+)/$', cog.views.news_add, name='news_add'),
    url(r'^news/detail/(?P<news_id>\d+)/$', cog.views.news_detail, name='news_detail'),
    url(r'^news/update/(?P<news_id>\d+)/$', cog.views.news_update, name='news_update'),
    url(r'^news/delete/(?P<news_id>\d+)/$', cog.views.news_delete, name='news_delete'),

    # posts
    url(r'^post/add/(?P<project_short_name>.+)/$', cog.views.post_add, name='post_add'),
    url(r'^post/update/(?P<post_id>\d+)/$', cog.views.post_update, name='post_update'),
    url(r'^post/detail/(?P<post_id>\d+)/$', cog.views.post_detail, name='post_detail'),
    url(r'^post/list/(?P<project_short_name>.+)/$', cog.views.post_list, name='post_list'),
    url(r'^post/delete/(?P<post_id>\d+)/$', cog.views.post_delete, name='post_delete'),
    url(r'^post/cancel/(?P<post_id>\d+)/$', cog.views.post_cancel, name='post_cancel'),

    # documents
    url(r'^doc/add/(?P<project_short_name>.+)/$', cog.views.doc_add, name='doc_add'),
    url(r'^doc/detail/(?P<doc_id>\d+)/$', cog.views.doc_detail, name='doc_detail'),
    url(r'^doc/update/(?P<doc_id>\d+)/$', cog.views.doc_update, name='doc_update'),
    url(r'^doc/remove/(?P<doc_id>\d+)/$', cog.views.doc_remove, name='doc_remove'),
    url(r'^doc/list/(?P<project_short_name>.+)/$', cog.views.doc_list, name='doc_list'),
     url(r'^doc/upload/(?P<project_short_name>.+)/$', cog.views.doc_upload, name='doc_upload'),

    # posts and documents
    url(r'^post/add_doc/(?P<post_id>\d+)/$', cog.views.post_add_doc, name='post_add_doc'),
    url(r'^post/remove_doc/(?P<post_id>\d+)/(?P<doc_id>\d+)/$', cog.views.post_remove_doc, name='post_remove_doc'),

    # signals
    url(r'^signal/list/(?P<project_short_name>.+)/$', cog.views.signal_list, name='signal_list'),

    # project membership
    url(r'^membership/request/(?P<project_short_name>[^/]+)/$', cog.views.membership_request, name='membership_request' ),
    url(r'^membership/list/enrolled/(?P<project_short_name>[^/]+)/$', cog.views.membership_list_enrolled, name='membership_list_enrolled' ),
    url(r'^membership/list/requested/(?P<project_short_name>[^/]+)/$', cog.views.membership_list_requested, name='membership_list_requested' ),
    url(r'^membership/list/all/(?P<project_short_name>[^/]+)/$', cog.views.membership_list_all, name='membership_list_all' ),
    url(r'^membership/process/(?P<project_short_name>[^/]+)/$', cog.views.membership_process, name='membership_process' ),
    url(r'^membership/remove/(?P<project_short_name>[^/]+)/$', cog.views.membership_remove, name='membership_remove' ),

    # group membership (data access control)
    url(r'^ac/subscribe/(?P<group_name>[^/]+)/$', cog.views.ac_subscribe, name='ac_subscribe' ),
    url(r'^ac/process/(?P<group_name>[^/]+)/(?P<user_id>\d+)/$', cog.views.ac_process, name='ac_process' ),
    url(r'^ac/list/$', cog.views.ac_list, name='ac_list' ),

    # project tags
    url(r'^projects/(?P<project_short_name>[^/]+)/tags/update/$', cog.views.tags_update, name='tags_update'),

    # project browser
    url(r'^project_browser/(?P<project_short_name>[^/]+)/browse/(?P<tab>[^/]+)/$', cog.views.project_browser, name='project_browser'),
    # the following matches on Apache httpd
    url(r'^project_browser/browse/(?P<tab>[^/]+)/$', cog.views.project_empty_browser, name='project_empty_browser'),
    # the following matches on django development server
    url(r'^project_browser//browse/(?P<tab>[^/]+)/$', cog.views.project_empty_browser, name='project_empty_browser'),
    # save/delete user tags
    url(r'^project_browser/save_user_tag/', cog.views.save_user_tag, name='save_user_tag'),
    url(r'^project_browser/delete_user_tag/', cog.views.delete_user_tag, name='delete_user_tag'),

    # NAVBAR URLs
    url(r'', include('cog.urls_navbar')),

    # project generic pages
    # Note: these URLs must come last because the last URL matches everything within the project!
    #url(r'^projects/$', 'cog.views.index', name='unspecified_project'),
    url(r'^projects/(?P<project_short_name>[^/]+)/$', cog.views.project_home, name='project_home'),
    url(r'^projects/(?P<project_short_name>[^/]+)/.+$', cog.views.page_detail, name='page_detail'),

    # resized project media (must be served without any access control since they are not wrapped by "Doc" objects)
    url(r'^site_media/(?P<path>.*_thumbnail.*)$', django.views.static.serve, {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_small.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_medium.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_big.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    #url(r'^site_media/(?P<path>.*_large.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT} ),
    # project media
    url(r'^site_media/projects/(?P<path>.*)$', cog.views.doc_download, name='doc_download'),
    # project data
    #url(r'^site_media/data/(?P<path>.*)$', 'cog.views.data_download', name='data_download'),

    # information shared with other sites
    url(r'^share/projects/$', cog.views.share_projects, name='share_projects'),
    url(r'^share/groups/$', cog.views.share_groups, name='share_groups'),
    url(r'^share/user/$', cog.views.share_user, name='share_user'),
    url(r'^share/sync/projects/$', cog.views.sync_projects, name='sync_projects'),

    # comments
    url(r'^comments/delete_comment/(?P<id>.*)/$', cog.views.views_common.deleteComment, name='delete_comment'),

    # Globus integration
    url(r'^globus/download/$', cog.views.views_globus.download, name='globus_download'),
    url(r'^globus/transfer/$', cog.views.views_globus.transfer, name='globus_transfer'),
    url(r'^globus/oauth/$', cog.views.views_globus.oauth, name='globus_oauth'),
    url(r'^globus/token/$', cog.views.views_globus.token, name='globus_token'),
    url(r'^globus/submit/$', cog.views.views_globus.submit, name='globus_submit'),
    url(r'^globus/script/$', cog.views.views_globus.script, name='globus_script'),

]
<|endoftext|>


<commit_before>
from twisted.internet import reactor

from twisted.trial.unittest import TestCase

from game.environment import Environment
from game.direction import EAST
from game.player import Player

from game.controller import PlayerController

from game.view import Window
from game.view import PlayerView

class PlayerTests(TestCase):
    def setUp(self):
        self.environment = Environment(50, reactor)
        self.environment.start()
        self.player = Player(
            (0, 0),
            speed=75,
            seconds=self.environment.seconds)

        # XXX PRIVATE VARIABLE USAGE ZOMG
        print getattr(self, self._testMethodName).__doc__

    def tearDown(self):
        self.environment.stop() # clean up pending calls
        if not raw_input("Did it work?").lower().startswith('y'):
            self.fail("User specified test failure")

    def test_tedium(self):
        """
        * A 320x240 window, black background, should be displayed.
        * Alt-f4 should close the window.
        """
        window = Window(self.environment)
        return window.go()

    def test_initial_position(self):
        """
        The player image should be displayed at the bottom-left corner of the
        window.
        """
        window = Window(self.environment)
        view = PlayerView(self.player)
        window.add(view)

        return window.go()

    def test_moves_around(self):
        """
        The player image should move from the bottom left of the screen to the
        bottom right of the screen.
        """
        window = Window(self.environment)
        view = PlayerView(self.player)
        window.add(view)
        self.player.setDirection(EAST)
        return window.go()

    def test_input_directs_player(self):
        """
        The arrow keys should direct the player in eight directions.
        """
        window = Window(self.environment)
        view = PlayerView(self.player)
        window.add(view)
        window.submitTo(PlayerController(self.player))
        return window.go()
<commit_msg>Functional test for terrain rendering<commit_after>
from twisted.internet import reactor

from twisted.trial.unittest import TestCase

from game.environment import Environment
from game.direction import EAST
from game.player import Player

from game.controller import PlayerController

from game.view import Window, loadImage
from game.view import PlayerView, TerrainView
from game.terrain import GRASS

class FunctionalTestMixin:
    def setUp(self):
        # XXX PRIVATE VARIABLE USAGE ZOMG
        print getattr(self, self._testMethodName).__doc__

    def tearDown(self):
        if not raw_input("Did it work?").lower().startswith('y'):
            self.fail("User specified test failure")

class PlayerTests(FunctionalTestMixin, TestCase):
    def setUp(self):
        self.environment = Environment(50, reactor)
        self.environment.start()
        self.player = Player(
            (0, 0),
            speed=75,
            seconds=self.environment.seconds)

        FunctionalTestMixin.setUp(self)

    def tearDown(self):
        self.environment.stop() # clean up pending calls
        FunctionalTestMixin.tearDown(self)

    def test_tedium(self):
        """
        * A 320x240 window, black background, should be displayed.
        * Alt-f4 should close the window.
        """
        window = Window(self.environment)
        return window.go()

    def test_initial_position(self):
        """
        The player image should be displayed at the bottom-left corner of the
        window.
        """
        window = Window(self.environment)
        view = PlayerView(self.player)
        window.add(view)

        return window.go()

    def test_moves_around(self):
        """
        The player image should move from the bottom left of the screen to the
        bottom right of the screen.
        """
        window = Window(self.environment)
        view = PlayerView(self.player)
        window.add(view)
        self.player.setDirection(EAST)
        return window.go()

    def test_input_directs_player(self):
        """
        The arrow keys should direct the player in eight directions.
        """
        window = Window(self.environment)
        view = PlayerView(self.player)
        window.add(view)
        window.submitTo(PlayerController(self.player))
        return window.go()

class TerrainTests(FunctionalTestMixin, TestCase):
    """
    Tests for how terrain is rendered in the view.
    """
    def test_singleTile(self):
        """
        There should be a single square of grass terrain in the bottom left
        corner.
        """
        environment = Environment(50, reactor)
        window = Window(environment)
        view = TerrainView({(0, 0): GRASS}, loadImage)
        window.add(view)
        return window.go()
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Script to extract the event data attribute containers schema."""

from __future__ import print_function
from __future__ import unicode_literals

import argparse
import importlib
import inspect
import logging
import pkgutil
import sys

from plaso.containers import events

class EventDataAttributeContainersSchemaExtractor(object):
  """Event data attribute containers schema extractor."""

  def FormatSchema(self, attribute_containers):
    """Formats the event data attribute containers as a schema.

    Args:
      attribute_containers (list[class]): event data attribute container
          classes.

    Returns:
      str: event data schema.
    """
    lines = []

    for cls in sorted(attribute_containers, key=lambda cls: cls.DATA_TYPE):
      try:
        event_data = cls()
      except TypeError:
        logging.warning('Unable to inspect: {0:s}'.format(cls.DATA_TYPE))
        continue

      lines.append('{0:s}'.format(event_data.data_type))
      for name in sorted(event_data.GetAttributeNames()):
        lines.append('  {0:s}'.format(name))
      lines.append('')

    return '\n'.join(lines)

  def _GetAttributeContainersFromPackage(self, package):
    """Retrieves event data attribute containers from a package.

    Args:
      package (list[str]): package name segments such as ["plaso", "parsers"].

    Returns:
      list[class]: event data attribute container classes.
    """
    attribute_containers = []
    package_path = '/'.join(package)
    for _, name, is_package in pkgutil.iter_modules(path=[package_path]):
      if package_path == 'plaso/containers' and name in ('errors', 'events'):
        continue

      sub_package = list(package)
      sub_package.append(name)
      if is_package:
        sub_containers = self._GetAttributeContainersFromPackage(sub_package)
        attribute_containers.extend(sub_containers)
      else:
        module_path = '.'.join(sub_package)
        module_object = importlib.import_module(module_path)
        for _, cls in inspect.getmembers(module_object, inspect.isclass):
          if issubclass(cls, events.EventData):
            attribute_containers.append(cls)

    return attribute_containers

  def GetAttributeContainers(self):
    """Retrieves event data attribute containers from Plaso.

    Returns:
      list[plaso.EventData]: event data attribute containers.
    """
    return self._GetAttributeContainersFromPackage(['plaso'])

def Main():
  """The main program function.

  Returns:
    bool: True if successful or False if not.
  """
  argument_parser = argparse.ArgumentParser(description=(
      'Extract the event data schema from Plaso.'))

  argument_parser.parse_args()

  extractor = EventDataAttributeContainersSchemaExtractor()

  attribute_containers = extractor.GetAttributeContainers()
  if not attribute_containers:
    print('Unable to determine event data attribute containers')
    return False

  schema = extractor.FormatSchema(attribute_containers)
  print(schema)

  return True

if __name__ == '__main__':
  if not Main():
    sys.exit(1)
  else:
    sys.exit(0)
<commit_msg>Changed export event data script to not print internal attributes (#3186)<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Script to extract the event data attribute containers schema."""

from __future__ import print_function
from __future__ import unicode_literals

import argparse
import importlib
import inspect
import logging
import pkgutil
import sys

from plaso.containers import events

class EventDataAttributeContainersSchemaExtractor(object):
  """Event data attribute containers schema extractor."""

  def FormatSchema(self, attribute_containers):
    """Formats the event data attribute containers as a schema.

    Args:
      attribute_containers (list[class]): event data attribute container
          classes.

    Returns:
      str: event data schema.
    """
    lines = []

    for cls in sorted(attribute_containers, key=lambda cls: cls.DATA_TYPE):
      try:
        event_data = cls()
      except TypeError:
        logging.warning('Unable to inspect: {0:s}'.format(cls.DATA_TYPE))
        continue

      lines.append('{0:s}'.format(event_data.data_type))
      for name in sorted(event_data.GetAttributeNames()):
        if name and name[0] != '_':
          lines.append('  {0:s}'.format(name))
      lines.append('')

    return '\n'.join(lines)

  def _GetAttributeContainersFromPackage(self, package):
    """Retrieves event data attribute containers from a package.

    Args:
      package (list[str]): package name segments such as ["plaso", "parsers"].

    Returns:
      list[class]: event data attribute container classes.
    """
    attribute_containers = []
    package_path = '/'.join(package)
    for _, name, is_package in pkgutil.iter_modules(path=[package_path]):
      if package_path == 'plaso/containers' and name in ('errors', 'events'):
        continue

      sub_package = list(package)
      sub_package.append(name)
      if is_package:
        sub_containers = self._GetAttributeContainersFromPackage(sub_package)
        attribute_containers.extend(sub_containers)
      else:
        module_path = '.'.join(sub_package)
        module_object = importlib.import_module(module_path)
        for _, cls in inspect.getmembers(module_object, inspect.isclass):
          if issubclass(cls, events.EventData):
            attribute_containers.append(cls)

    return attribute_containers

  def GetAttributeContainers(self):
    """Retrieves event data attribute containers from Plaso.

    Returns:
      list[plaso.EventData]: event data attribute containers.
    """
    return self._GetAttributeContainersFromPackage(['plaso'])

def Main():
  """The main program function.

  Returns:
    bool: True if successful or False if not.
  """
  argument_parser = argparse.ArgumentParser(description=(
      'Extract the event data schema from Plaso.'))

  argument_parser.parse_args()

  extractor = EventDataAttributeContainersSchemaExtractor()

  attribute_containers = extractor.GetAttributeContainers()
  if not attribute_containers:
    print('Unable to determine event data attribute containers')
    return False

  schema = extractor.FormatSchema(attribute_containers)
  print(schema)

  return True

if __name__ == '__main__':
  if not Main():
    sys.exit(1)
  else:
    sys.exit(0)
<|endoftext|>


<commit_before>from sqlalchemy import Table, Column, Integer, String, MetaData
from sqlalchemy.sql import select, insert, text
from sqlalchemy import func

import ckan.model as model
from ckan.authz import Authorizer
from ckan.model.authz import PSEUDO_USER__VISITOR
from ckan.lib.base import *

def init_tables():
    metadata = MetaData()
    package_stats = Table('package_stats', metadata,
                          Column('package_id', String(60),
                                 primary_key=True),
                          Column('visits_recently', Integer),
                          Column('visits_ever', Integer))
    resource_stats = Table('resource_stats', metadata,
                           Column('resource_id', String(60),
                                  primary_key=True),
                           Column('visits_recently', Integer),
                           Column('visits_ever', Integer))
    metadata.create_all(model.meta.engine)

def get_table(name):
    meta = MetaData()
    meta.reflect(bind=model.meta.engine)
    return meta.tables[name]

def _update_visits(table_name, item_id, recently, ever):
    stats = get_table(table_name)
    id_col_name = "%s_id" % table_name[:-len("_stats")]
    id_col = getattr(stats.c, id_col_name)
    s = select([func.count(id_col)],
               id_col == item_id)
    connection = model.Session.connection()
    count = connection.execute(s).fetchone()
    if count and count[0]:
        connection.execute(stats.update()\
            .where(id_col == item_id)\
            .values(visits_recently=recently,
                    visits_ever=ever))
    else:
        values = {id_col_name: item_id,
                  'visits_recently': recently,
                  'visits_ever': ever}
        connection.execute(stats.insert()\
                           .values(**values))

def update_resource_visits(resource_id, recently, ever):
    return _update_visits("resource_stats",
                          resource_id,
                          recently,
                          ever)

def update_package_visits(package_id, recently, ever):
    return _update_visits("package_stats",
                          package_id,
                          recently,
                          ever)

def get_resource_visits_for_url(url):
    connection = model.Session.connection()
    count = connection.execute(
        text("""SELECT visits_ever FROM resource_stats, resource
        WHERE resource_id = resource.id
        AND resource.url = :url"""), url=url).fetchone()
    return count and count[0] or ""

def get_top_packages(limit=20):
    items = []
    authorizer = Authorizer()
    q = authorizer.authorized_query(PSEUDO_USER__VISITOR,
                                    model.Package)
    connection = model.Session.connection()
    package_stats = get_table('package_stats')
    s = select([package_stats.c.package_id,
                package_stats.c.visits_recently,
                package_stats.c.visits_ever])\
                .order_by(package_stats.c.visits_recently.desc())
    res = connection.execute(s).fetchmany(limit)
    for package_id, recent, ever in res:
        item = q.filter("package.id = '%s'" % package_id)
        if not item.count():
            continue
        items.append((item.first(), recent, ever))
    return items

def get_top_resources(limit=20):
    items = []
    connection = model.Session.connection()
    resource_stats = get_table('resource_stats')
    s = select([resource_stats.c.resource_id,
                resource_stats.c.visits_recently,
                resource_stats.c.visits_ever])\
                .order_by(resource_stats.c.visits_recently.desc())
    res = connection.execute(s).fetchmany(limit)
    for resource_id, recent, ever in res:
        item = model.Session.query(model.Resource)\
               .filter("resource.id = '%s'" % resource_id)
        if not item.count():
            continue
        items.append((item.first(), recent, ever))
    return items
<commit_msg>cache table reflection (it was *very* slow)<commit_after>from sqlalchemy import Table, Column, Integer, String, MetaData
from sqlalchemy.sql import select, insert, text
from sqlalchemy import func

import ckan.model as model
from ckan.authz import Authorizer
from ckan.model.authz import PSEUDO_USER__VISITOR
from ckan.lib.base import *

cached_tables = {}

def init_tables():
    metadata = MetaData()
    package_stats = Table('package_stats', metadata,
                          Column('package_id', String(60),
                                 primary_key=True),
                          Column('visits_recently', Integer),
                          Column('visits_ever', Integer))
    resource_stats = Table('resource_stats', metadata,
                           Column('resource_id', String(60),
                                  primary_key=True),
                           Column('visits_recently', Integer),
                           Column('visits_ever', Integer))
    metadata.create_all(model.meta.engine)

def get_table(name):
    if name not in cached_tables:
        meta = MetaData()
        meta.reflect(bind=model.meta.engine)
        table = meta.tables[name]
        cached_tables[name] = table
    return cached_tables[name]

def _update_visits(table_name, item_id, recently, ever):
    stats = get_table(table_name)
    id_col_name = "%s_id" % table_name[:-len("_stats")]
    id_col = getattr(stats.c, id_col_name)
    s = select([func.count(id_col)],
               id_col == item_id)
    connection = model.Session.connection()
    count = connection.execute(s).fetchone()
    if count and count[0]:
        connection.execute(stats.update()\
            .where(id_col == item_id)\
            .values(visits_recently=recently,
                    visits_ever=ever))
    else:
        values = {id_col_name: item_id,
                  'visits_recently': recently,
                  'visits_ever': ever}
        connection.execute(stats.insert()\
                           .values(**values))

def update_resource_visits(resource_id, recently, ever):
    return _update_visits("resource_stats",
                          resource_id,
                          recently,
                          ever)

def update_package_visits(package_id, recently, ever):
    return _update_visits("package_stats",
                          package_id,
                          recently,
                          ever)

def get_resource_visits_for_url(url):
    connection = model.Session.connection()
    count = connection.execute(
        text("""SELECT visits_ever FROM resource_stats, resource
        WHERE resource_id = resource.id
        AND resource.url = :url"""), url=url).fetchone()
    return count and count[0] or ""

def get_top_packages(limit=20):
    items = []
    authorizer = Authorizer()
    q = authorizer.authorized_query(PSEUDO_USER__VISITOR,
                                    model.Package)
    connection = model.Session.connection()
    package_stats = get_table('package_stats')
    s = select([package_stats.c.package_id,
                package_stats.c.visits_recently,
                package_stats.c.visits_ever])\
                .order_by(package_stats.c.visits_recently.desc())
    res = connection.execute(s).fetchmany(limit)
    for package_id, recent, ever in res:
        item = q.filter("package.id = '%s'" % package_id)
        if not item.count():
            continue
        items.append((item.first(), recent, ever))
    return items

def get_top_resources(limit=20):
    items = []
    connection = model.Session.connection()
    resource_stats = get_table('resource_stats')
    s = select([resource_stats.c.resource_id,
                resource_stats.c.visits_recently,
                resource_stats.c.visits_ever])\
                .order_by(resource_stats.c.visits_recently.desc())
    res = connection.execute(s).fetchmany(limit)
    for resource_id, recent, ever in res:
        item = model.Session.query(model.Resource)\
               .filter("resource.id = '%s'" % resource_id)
        if not item.count():
            continue
        items.append((item.first(), recent, ever))
    return items
<|endoftext|>


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

from hwt.code import connect, If, In
from hwt.code_utils import rename_signal
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.defs import BIT
from hwt.hdl.types.struct import HStruct
from hwtLib.amba.axi_comp.oooOp.outOfOrderCummulativeOp import OutOfOrderCummulativeOp
from hwtLib.amba.axi_comp.oooOp.utils import OOOOpPipelineStage

class OooOpExampleCounterHashTable(OutOfOrderCummulativeOp):
    """
    This components mantains the hash table where value is a counter.
    This hash table is accesed throught the axi interface.
    These counters are incremented using "dataIn" interface in a coherent way.
    The operation may finish out of order but the data on "dataOut" and in the memory
    will be correct. The same applays for the swap operations (all operations).

    .. hwt-schematic:: _example_OooOpExampleCounterHashTable
    """

    class OPERATION():
        # if swap the original item from main memory will be stored in transaction_state.original_data
        # (the place where original insert/lookup key was stored)
        # and the item which was in initial swap transaction will be stored in main state
        SWAP = 0  # insert and return original key, item_valid, value (can be also used to delete the item)
        LOOKUP_OR_SWAP = 1  # lookup and update if key found or swap key, item_valid, value
        LOOKUP = 2  # lookup and update if key found else perfor no state update

    def _config(self):
        OutOfOrderCummulativeOp._config(self)
        # state in main memory
        self.MAIN_STATE_T = HStruct(
            (BIT, "item_valid"),
            (Bits(32), "key"),
            (Bits(self.DATA_WIDTH - 32 - 1), "value"),
        )
        # the transaction always just increments the counter
        # so there is no need for transaction state
        self.TRANSACTION_STATE_T = HStruct(
            # if true the key was modified during processing
            # and we need to recirculate the transaction in pipeline
            # (which should be done by parent component and it does not happen automatically)
            (BIT, "reset"),
            # container of original key and data for insert or match
            (self.MAIN_STATE_T, "original_data"),
            # for output 1 if key was same as key in lookup transaction
            (BIT, "key_match"),
            (Bits(2), "operation"),  # :see: :class:`~.OPERATION`
        )

    def _declr(self):
        OutOfOrderCummulativeOp._declr(self)
        swap_container_type = self.TRANSACTION_STATE_T.field_by_name["original_data"].dtype
        assert swap_container_type is self.MAIN_STATE_T, (swap_container_type, self.MAIN_STATE_T)

    def key_compare(self, k0, k1):
        return k0._eq(k1)

    def propagate_trans_st(self, stage_from: OOOOpPipelineStage, stage_to: OOOOpPipelineStage):
        """
        Pass the state of operation (lookup/swap) in pipeline
        in state before write_back chech if the key matches and
        """
        PIPELINE_CONFIG = self.PIPELINE_CONFIG
        src = stage_from.transaction_state
        dst = stage_to.transaction_state
        if stage_to.index == PIPELINE_CONFIG.WRITE_BACK - 1:
            key_match = rename_signal(self, stage_from.data.item_valid & self.key_compare(stage_from.data.key, src.original_data.key), "key_match")
            op = stage_from.transaction_state.operation
            return [
                dst.key_match(key_match),
                If(stage_from.valid & (op._eq(self.OPERATION.SWAP) | (op._eq(self.OPERATION.LOOKUP_OR_SWAP) & ~key_match)),
                    # swap or lookup_or_swap with not found, wee need to store original key
                    # as specified by :attr:`OooOpExampleCounterHashTable.OPERATION`
                    connect(stage_from.data, dst.original_data),
                    connect(src, dst, exclude=[dst.original_data, dst.key_match])
                ).Else(
                    connect(src, dst, exclude=[dst.key_match])
                )
            ]
        else:
            return dst(src)

    def write_cancel(self, write_back_st: OOOOpPipelineStage):
        """
        :return: signal which if it is 1 the transaction state update is not writen back to memory
            (e.g. 1 if key does not match and we do not want to update counters)
        """
        return write_back_st.valid & \
               ~write_back_st.transaction_state.key_match & \
               write_back_st.transaction_state.operation._eq(self.OPERATION.LOOKUP)

    def main_op_on_lookup_match_update(self, dst_stage: OOOOpPipelineStage, src_stage: OOOOpPipelineStage):
        return [
            dst_stage.data.value(src_stage.data.value + 1)
        ]

    def main_op(self, dst_stage: OOOOpPipelineStage, src_stage: OOOOpPipelineStage):
        """
        A main opration of counter incrementation

        :note: This function is called for write back state and its predecessor.
            However because of write bypass this function is called multiple times for each bypass as well.
        """
        dst = dst_stage.data
        src = src_stage.data
        prev_st = self.pipeline[dst_stage.index - 1]
        OP = self.OPERATION
        prev_st_op = prev_st.transaction_state.operation

        return If(prev_st.valid & prev_st.transaction_state.key_match & In(prev_st_op, [OP.LOOKUP, OP.LOOKUP_OR_SWAP]),
            # lookup or lookup_or_swap with found
            dst.item_valid(src.item_valid),
            dst.key(src.key),
            self.main_op_on_lookup_match_update(dst_stage, src_stage),
        ).Elif(prev_st.valid & prev_st_op._eq(OP.SWAP),
            # swap or lookup_or_swap with not found
            dst(prev_st.data),
        ).Elif(prev_st.valid & ~prev_st.transaction_state.key_match,
            #  not match not swap, keep as it is
            dst(src),
        )

def _example_OooOpExampleCounterHashTable():
    u = OooOpExampleCounterHashTable()
    u.ID_WIDTH = 6
    u.ADDR_WIDTH = 16 + 3
    u.MAIN_STATE_T = HStruct(
        (BIT, "item_valid"),
        (Bits(256), "key"),
        (Bits(32), "value"),
        (Bits(512 - 256 - 32 - 1), "padding"),
    )
    u.TRANSACTION_STATE_T = HStruct(
        (BIT, "reset"),
        (u.MAIN_STATE_T, "data"),
        (BIT, "key_match"),
        (Bits(2), "operation"),  # :see: :class:`~.OPERATION`
    )
    u.DATA_WIDTH = u.MAIN_STATE_T.bit_length()
    return u

if __name__ == "__main__":
    from hwt.synthesizer.utils import to_rtl_str
    u = _example_OooOpExampleCounterHashTable()
    print(to_rtl_str(u))
<commit_msg>_example_OooOpExampleCounterHashTable: fix names<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from hwt.code import connect, If, In
from hwt.code_utils import rename_signal
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.defs import BIT
from hwt.hdl.types.struct import HStruct
from hwtLib.amba.axi_comp.oooOp.outOfOrderCummulativeOp import OutOfOrderCummulativeOp
from hwtLib.amba.axi_comp.oooOp.utils import OOOOpPipelineStage

class OooOpExampleCounterHashTable(OutOfOrderCummulativeOp):
    """
    This components mantains the hash table where value is a counter.
    This hash table is accesed throught the axi interface.
    These counters are incremented using "dataIn" interface in a coherent way.
    The operation may finish out of order but the data on "dataOut" and in the memory
    will be correct. The same applays for the swap operations (all operations).

    .. hwt-schematic:: _example_OooOpExampleCounterHashTable
    """

    class OPERATION():
        # if swap the original item from main memory will be stored in transaction_state.original_data
        # (the place where original insert/lookup key was stored)
        # and the item which was in initial swap transaction will be stored in main state
        SWAP = 0  # insert and return original key, item_valid, value (can be also used to delete the item)
        LOOKUP_OR_SWAP = 1  # lookup and update if key found or swap key, item_valid, value
        LOOKUP = 2  # lookup and update if key found else perfor no state update

    def _config(self):
        OutOfOrderCummulativeOp._config(self)
        # state in main memory
        self.MAIN_STATE_T = HStruct(
            (BIT, "item_valid"),
            (Bits(32), "key"),
            (Bits(self.DATA_WIDTH - 32 - 1), "value"),
        )
        # the transaction always just increments the counter
        # so there is no need for transaction state
        self.TRANSACTION_STATE_T = HStruct(
            # if true the key was modified during processing
            # and we need to recirculate the transaction in pipeline
            # (which should be done by parent component and it does not happen automatically)
            (BIT, "reset"),
            # container of original key and data for insert or match
            (self.MAIN_STATE_T, "original_data"),
            # for output 1 if key was same as key in lookup transaction
            (BIT, "key_match"),
            (Bits(2), "operation"),  # :see: :class:`~.OPERATION`
        )

    def _declr(self):
        OutOfOrderCummulativeOp._declr(self)
        swap_container_type = self.TRANSACTION_STATE_T.field_by_name["original_data"].dtype
        assert swap_container_type is self.MAIN_STATE_T, (swap_container_type, self.MAIN_STATE_T)

    def key_compare(self, k0, k1):
        return k0._eq(k1)

    def propagate_trans_st(self, stage_from: OOOOpPipelineStage, stage_to: OOOOpPipelineStage):
        """
        Pass the state of operation (lookup/swap) in pipeline
        in state before write_back chech if the key matches and
        """
        PIPELINE_CONFIG = self.PIPELINE_CONFIG
        src = stage_from.transaction_state
        dst = stage_to.transaction_state
        if stage_to.index == PIPELINE_CONFIG.WRITE_BACK - 1:
            key_match = rename_signal(self, stage_from.data.item_valid & self.key_compare(stage_from.data.key, src.original_data.key), "key_match")
            op = stage_from.transaction_state.operation
            return [
                dst.key_match(key_match),
                If(stage_from.valid & (op._eq(self.OPERATION.SWAP) | (op._eq(self.OPERATION.LOOKUP_OR_SWAP) & ~key_match)),
                    # swap or lookup_or_swap with not found, wee need to store original key
                    # as specified by :attr:`OooOpExampleCounterHashTable.OPERATION`
                    connect(stage_from.data, dst.original_data),
                    connect(src, dst, exclude=[dst.original_data, dst.key_match])
                ).Else(
                    connect(src, dst, exclude=[dst.key_match])
                )
            ]
        else:
            return dst(src)

    def write_cancel(self, write_back_st: OOOOpPipelineStage):
        """
        :return: signal which if it is 1 the transaction state update is not writen back to memory
            (e.g. 1 if key does not match and we do not want to update counters)
        """
        return write_back_st.valid & \
               ~write_back_st.transaction_state.key_match & \
               write_back_st.transaction_state.operation._eq(self.OPERATION.LOOKUP)

    def main_op_on_lookup_match_update(self, dst_stage: OOOOpPipelineStage, src_stage: OOOOpPipelineStage):
        return [
            dst_stage.data.value(src_stage.data.value + 1)
        ]

    def main_op(self, dst_stage: OOOOpPipelineStage, src_stage: OOOOpPipelineStage):
        """
        A main opration of counter incrementation

        :note: This function is called for write back state and its predecessor.
            However because of write bypass this function is called multiple times for each bypass as well.
        """
        dst = dst_stage.data
        src = src_stage.data
        prev_st = self.pipeline[dst_stage.index - 1]
        OP = self.OPERATION
        prev_st_op = prev_st.transaction_state.operation

        return If(prev_st.valid & prev_st.transaction_state.key_match & In(prev_st_op, [OP.LOOKUP, OP.LOOKUP_OR_SWAP]),
            # lookup or lookup_or_swap with found
            dst.item_valid(src.item_valid),
            dst.key(src.key),
            self.main_op_on_lookup_match_update(dst_stage, src_stage),
        ).Elif(prev_st.valid & prev_st_op._eq(OP.SWAP),
            # swap or lookup_or_swap with not found
            dst(prev_st.data),
        ).Elif(prev_st.valid & ~prev_st.transaction_state.key_match,
            #  not match not swap, keep as it is
            dst(src),
        )

def _example_OooOpExampleCounterHashTable():
    u = OooOpExampleCounterHashTable()
    u.ID_WIDTH = 6
    u.ADDR_WIDTH = 16 + 3
    u.MAIN_STATE_T = HStruct(
        (BIT, "item_valid"),
        (Bits(256), "key"),
        (Bits(32), "value"),
        (Bits(512 - 256 - 32 - 1), "padding"),
    )
    u.TRANSACTION_STATE_T = HStruct(
        (BIT, "reset"),
        (u.MAIN_STATE_T, "original_data"),
        (BIT, "key_match"),
        (Bits(2), "operation"),  # :see: :class:`~.OPERATION`
    )
    u.DATA_WIDTH = u.MAIN_STATE_T.bit_length()
    return u

if __name__ == "__main__":
    from hwt.synthesizer.utils import to_rtl_str
    u = _example_OooOpExampleCounterHashTable()
    print(to_rtl_str(u))
<|endoftext|>