<commit_before>"""
The cython function was adapted from scikits-image (http://scikits-image.org/)
"""

import sys
import os
import shutil
import subprocess
import platform
from distutils.dist import Distribution
from distutils.command.config import config as distutils_config
from distutils import log
import optparse # deprecated in 2.7 for argparse

dummy_c_text = r'''
/* This file is generated from statsmodels/tools/_build.py to */
void do_nothing(void);
int main(void) {
    do_nothing();
    return 0;
}
'''

def has_c_compiler():
    c = distutils_config(Distribution())
    if platform.system() == "Windows": # HACK
        # this doesn't matter because mingw won't be given at install step
        # check if mingw was given in compiler options
        #parser = optparse.OptionParser()
        #parser.add_option('-c', '--compiler', dest='compiler')
        #options, args = parser.parse_args()
        #if options.compiler and 'mingw' in options.compiler:
        #    return True

        # if not, then check to see if compiler is set in disutils.cfg
        try: # Josef's code to check the distutils.cfg file
            c.distribution.parse_config_files(c.distribution.find_config_files())
            # this will raise a key error if there's not one
            c.distribution.command_options['build']['compiler'][1]
            return True
        except:
            pass
    # just see if there's a system compiler
    try:
        success = c.try_compile(dummy_c_text)
        return True
    except:
        log.info("No C compiler detected. Not installing Cython version "
                 "of files.")
        return False

def cython(pyx_files, working_path=''):
    """Use Cython to convert the given files to C.

    Parameters
    ----------
    pyx_files : list of str
        The input .pyx files.

    """
    # Do not build cython files if target is clean
    if len(sys.argv) >= 2 and sys.argv[1] == 'clean':
        return

    try:
        import Cython
    except ImportError:
        # If cython is not found, we do nothing -- the build will make use of
        # the distributed .c files
        print("Cython not found; falling back to pre-built %s" \
              % " ".join([f.replace('.pyx', '.c') for f in pyx_files]))
    else:
        for pyxfile in [os.path.join(working_path, f) for f in pyx_files]:

            #TODO: replace this with already written hash_funcs once merged
            # if the .pyx file stayed the same, we don't need to recompile
            #if not _changed(pyxfile):
            #    continue

            c_file = pyxfile[:-4] + '.c'

            # run cython compiler
            cmd = 'cython -o %s %s' % (c_file, pyxfile)
            print(cmd)

            if platform.system() == 'Windows':
                script_path = os.path.join(os.path.dirname(sys.executable),
                                  'Scripts', 'cython-script.py')
                if not os.path.exists(script_path):
                    script_path = os.path.join(os.path.dirname(sys.executable),
                                  'Scripts', 'cython.py')
                status = subprocess.call(
                           [sys.executable, script_path, '-o', c_file, pyxfile],
                           shell=True)
            else:
                status = subprocess.call(['cython', '-o', c_file, pyxfile])
<commit_msg>BLD: Add fallback for Cython on older Mac OS X<commit_after>"""
The cython function was adapted from scikits-image (http://scikits-image.org/)
"""

import sys
import os
import shutil
import subprocess
import platform
from distutils.dist import Distribution
from distutils.command.config import config as distutils_config
from distutils import log
import optparse # deprecated in 2.7 for argparse

dummy_c_text = r'''
/* This file is generated from statsmodels/tools/_build.py to */
void do_nothing(void);
int main(void) {
    do_nothing();
    return 0;
}
'''

def has_c_compiler():
    c = distutils_config(Distribution())
    if platform.system() == "Windows": # HACK
        # this doesn't matter because mingw won't be given at install step
        # check if mingw was given in compiler options
        #parser = optparse.OptionParser()
        #parser.add_option('-c', '--compiler', dest='compiler')
        #options, args = parser.parse_args()
        #if options.compiler and 'mingw' in options.compiler:
        #    return True

        # if not, then check to see if compiler is set in disutils.cfg
        try: # Josef's code to check the distutils.cfg file
            c.distribution.parse_config_files(c.distribution.find_config_files())
            # this will raise a key error if there's not one
            c.distribution.command_options['build']['compiler'][1]
            return True
        except:
            pass
    # just see if there's a system compiler
    try:
        success = c.try_compile(dummy_c_text)
        return True
    except:
        log.info("No C compiler detected. Not installing Cython version "
                 "of files.")
        return False

def cython(pyx_files, working_path=''):
    """Use Cython to convert the given files to C.

    Parameters
    ----------
    pyx_files : list of str
        The input .pyx files.

    """
    # Do not build cython files if target is clean
    if len(sys.argv) >= 2 and sys.argv[1] == 'clean':
        return

    try:
        import Cython
    except ImportError:
        # If cython is not found, we do nothing -- the build will make use of
        # the distributed .c files
        print("Cython not found; falling back to pre-built %s" \
              % " ".join([f.replace('.pyx', '.c') for f in pyx_files]))
    else:
        for pyxfile in [os.path.join(working_path, f) for f in pyx_files]:

            #TODO: replace this with already written hash_funcs once merged
            # if the .pyx file stayed the same, we don't need to recompile
            #if not _changed(pyxfile):
            #    continue

            c_file = pyxfile[:-4] + '.c'

            # run cython compiler
            cmd = 'cython -o %s %s' % (c_file, pyxfile)
            print(cmd)

            if platform.system() == 'Windows':
                script_path = os.path.join(os.path.dirname(sys.executable),
                                  'Scripts', 'cython-script.py')
                if not os.path.exists(script_path):
                    script_path = os.path.join(os.path.dirname(sys.executable),
                                  'Scripts', 'cython.py')
                status = subprocess.call(
                           [sys.executable, script_path, '-o', c_file, pyxfile],
                           shell=True)
            else:
                try:
                    status = subprocess.call(['cython', '-o', c_file, pyxfile])
                except OSError, err:
                    # Above is reported to fail on Mac OS X 10.6.8
                    # because cython is a shell alias in the terminal only
                    pkg_path = os.path.abspath(os.path.join(
                                       os.path.dirname(Cython.__file__), '..'))
                    script_path = os.path.join(pkg_path, 'cython.py')
                    if not os.path.exists(script_path):
                        script_path = os.path.join(pkg_path,
                                                   'cython-script.py')
                    status = subprocess.call([sys.executable, script_path,
                                                    '-o', c_file, pyxfile])

<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Copyright 2015 Flavio Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:

from __future__ import (absolute_import, division,
                        print_function, with_statement)
import yaml
import os

# Setting root path
ROOT = None
if os.path.abspath(__file__).endswith('.py') or \
        os.path.abspath(__file__).endswith('.pyc'):
    ROOT = os.path.dirname(os.path.abspath(__file__))
else:
    ROOT = os.path.abspath(__file__)

# Getting configuration paths and files from the environment
FIRENADO_CONFIG_FILE = None
try:
    FIRENADO_CONFIG_FILE = os.environ['FIRENADO_CONFIG_FILE']
except KeyError:
    FIRENADO_CONFIG_FILE = 'firenado.yaml'

stack = []

LIB_CONFIG_FILE = os.path.join(ROOT, 'conf', FIRENADO_CONFIG_FILE)

# Application file
APP_CONFIG_ROOT_PATH = os.path.join(os.getcwd())
# If FIRENADO_CURRENT_APP_PATH is not set than return current directory
# conf dir
APP_CONFIG_PATH = os.getenv('FIRENADO_CURRENT_APP_CONFIG_PATH',
                            os.path.join(APP_CONFIG_ROOT_PATH, 'conf'))
APP_CONFIG_FILE = os.path.join(APP_CONFIG_PATH, FIRENADO_CONFIG_FILE)

HAS_LIB_CONFIG_FILE = False
HAS_APP_CONFIG_FILE = False

if os.path.isfile(LIB_CONFIG_FILE):
    HAS_LIB_CONFIG_FILE = True
    stack.append(LIB_CONFIG_FILE)

if os.path.isfile(APP_CONFIG_FILE):
    if APP_CONFIG_FILE != LIB_CONFIG_FILE:
        HAS_APP_CONFIG_FILE = True
        stack.append(APP_CONFIG_FILE)

# Setting firenado's default variables

# Application section configuration
app = {}
# Key to to be used on on the session context to store and retrieve the current
# logged user
app['current_user_key'] = '__FIRENADO_CURRENT_USER_KEY__'
app['data'] = {}
app['data']['sources'] = []
app['pythonpath'] = None
app['port'] = 8888
app['login'] = {}
app['login']['urls'] = {}
app['login']['urls']['default'] = '/login'
app['is_on_dir'] = False

# Component section configutaion
components = {}

# Data section configuration
data = {}
data['connectors'] = {}

# Management section configuration
management = {}
management['commands'] = {}

def process_config(config):
    """ Populates firenado.conf attributes from the loaded configuration
    dict. It handles data and management aspects from the configuration.

    :param config: Loaded configuration dict
    """
    if 'components' in config:
        process_components_config_section(config['components'])
    if 'data' in config:
        process_data_config_section(config['data'])
    if 'management' in config:
        process_management_config_section(config['management'])

def process_app_config(config):
    """ Populates firenado.conf attributes from the loaded configuration
    dict. It handles everything that process_config does plus application
    configuation.

    :param config: Loaded configuration dict
    """
    process_config(config)
    if 'app' in config:
        process_app_config_section(config['app'])

def process_app_config_section(app_config):
    """ Processes the app section from a configuration dict.

    :param app_config: App section from a config dict
    data.
    """
    global app
    if 'data' in app_config:
        if 'sources' in app_config['data']:
            app['data']['sources'] = app_config['data']['sources']
    if 'pythonpath' in app_config:
        app['pythonpath'] = app_config['pythonpath']
    if 'port' in app_config:
        app['port'] = app_config['port']

def process_components_config_section(components_config):
    """ Processes the components section from a configuration dict.

    :param components_config: Data section from a config dict.
    """
    global components
    for component_config in components_config:
        if 'id' not in component_config:
            raise Exception('The component %s was defined without an id.' %
                            component_config)
        component_id = component_config['id']
        if component_id not in components:
            components[component_id] = {}
            components[component_id]['enabled'] = False
            components[component_id]['config'] = {}
        if 'class' in component_config:
            class_config_x = component_config['class'].split('.')
            components[component_id]['class'] = class_config_x[1]
            components[component_id]['module'] = '.'.join(class_config_x[:-1])
        if 'enabled' in component_config:
            components[component_id]['enabled'] = bool(
                component_config['enabled'])

def process_data_config_section(data_config):
    """ Processes the data configuration section from the configuration
    dict.

    :param data_config: Data configuration section from a config dict.
    """
    global data
    if 'connectors' in data_config:
        data['connectors'] = data_config['connectors']

def process_management_config_section(management_config):
    """ Processes the management section from a configuration dict.

    :param management_config: Management section from a config dict.
    """
    global management
    if 'commands' in management_config:
        management['commands'] = management_config['commands']

if HAS_LIB_CONFIG_FILE:
    lib_config = yaml.safe_load(file(LIB_CONFIG_FILE, 'r'))
    process_config(lib_config)

if HAS_APP_CONFIG_FILE:
    app_config = yaml.safe_load(file(APP_CONFIG_FILE, 'r'))
    process_app_config(app_config)
<commit_msg>Introduced data source configuration.<commit_after>#!/usr/bin/env python
#
# Copyright 2015 Flavio Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:

from __future__ import (absolute_import, division,
                        print_function, with_statement)
import yaml
import os

# Setting root path
ROOT = None
if os.path.abspath(__file__).endswith('.py') or \
        os.path.abspath(__file__).endswith('.pyc'):
    ROOT = os.path.dirname(os.path.abspath(__file__))
else:
    ROOT = os.path.abspath(__file__)

# Getting configuration paths and files from the environment
FIRENADO_CONFIG_FILE = None
try:
    FIRENADO_CONFIG_FILE = os.environ['FIRENADO_CONFIG_FILE']
except KeyError:
    FIRENADO_CONFIG_FILE = 'firenado.yaml'

stack = []

LIB_CONFIG_FILE = os.path.join(ROOT, 'conf', FIRENADO_CONFIG_FILE)

# Application file
APP_CONFIG_ROOT_PATH = os.path.join(os.getcwd())
# If FIRENADO_CURRENT_APP_PATH is not set than return current directory
# conf dir
APP_CONFIG_PATH = os.getenv('FIRENADO_CURRENT_APP_CONFIG_PATH',
                            os.path.join(APP_CONFIG_ROOT_PATH, 'conf'))
APP_CONFIG_FILE = os.path.join(APP_CONFIG_PATH, FIRENADO_CONFIG_FILE)

HAS_LIB_CONFIG_FILE = False
HAS_APP_CONFIG_FILE = False

if os.path.isfile(LIB_CONFIG_FILE):
    HAS_LIB_CONFIG_FILE = True
    stack.append(LIB_CONFIG_FILE)

if os.path.isfile(APP_CONFIG_FILE):
    if APP_CONFIG_FILE != LIB_CONFIG_FILE:
        HAS_APP_CONFIG_FILE = True
        stack.append(APP_CONFIG_FILE)

# Setting firenado's default variables

# Application section configuration
app = {}
# Key to to be used on on the session context to store and retrieve the current
# logged user
app['current_user_key'] = '__FIRENADO_CURRENT_USER_KEY__'
app['data'] = {}
app['data']['sources'] = []
app['pythonpath'] = None
app['port'] = 8888
app['login'] = {}
app['login']['urls'] = {}
app['login']['urls']['default'] = '/login'
app['is_on_dir'] = False

# Component section configutaion
components = {}

# Data section configuration
data = {}
data['connectors'] = {}
data['sources'] = {}

# Management section configuration
management = {}
management['commands'] = {}

def process_config(config):
    """ Populates firenado.conf attributes from the loaded configuration
    dict. It handles data and management aspects from the configuration.

    :param config: Loaded configuration dict
    """
    if 'components' in config:
        process_components_config_section(config['components'])
    if 'data' in config:
        process_data_config_section(config['data'])
    if 'management' in config:
        process_management_config_section(config['management'])

def process_app_config(config):
    """ Populates firenado.conf attributes from the loaded configuration
    dict. It handles everything that process_config does plus application
    configuation.

    :param config: Loaded configuration dict
    """
    process_config(config)
    if 'app' in config:
        process_app_config_section(config['app'])

def process_app_config_section(app_config):
    """ Processes the app section from a configuration dict.

    :param app_config: App section from a config dict
    data.
    """
    global app
    if 'data' in app_config:
        if 'sources' in app_config['data']:
            app['data']['sources'] = app_config['data']['sources']
    if 'pythonpath' in app_config:
        app['pythonpath'] = app_config['pythonpath']
    if 'port' in app_config:
        app['port'] = app_config['port']

def process_components_config_section(components_config):
    """ Processes the components section from a configuration dict.

    :param components_config: Data section from a config dict.
    """
    global components
    for component_config in components_config:
        if 'id' not in component_config:
            raise Exception('The component %s was defined without an id.' %
                            component_config)
        component_id = component_config['id']
        if component_id not in components:
            components[component_id] = {}
            components[component_id]['enabled'] = False
            components[component_id]['config'] = {}
        if 'class' in component_config:
            class_config_x = component_config['class'].split('.')
            components[component_id]['class'] = class_config_x[1]
            components[component_id]['module'] = '.'.join(class_config_x[:-1])
        if 'enabled' in component_config:
            components[component_id]['enabled'] = bool(
                component_config['enabled'])

def process_data_config_section(data_config):
    """ Processes the data configuration section from the configuration
    dict.

    :param data_config: Data configuration section from a config dict.
    """
    global data
    if 'connectors' in data_config:
        data['connectors'] = data_config['connectors']

def process_management_config_section(management_config):
    """ Processes the management section from a configuration dict.

    :param management_config: Management section from a config dict.
    """
    global management
    if 'commands' in management_config:
        management['commands'] = management_config['commands']

if HAS_LIB_CONFIG_FILE:
    lib_config = yaml.safe_load(file(LIB_CONFIG_FILE, 'r'))
    process_config(lib_config)

if HAS_APP_CONFIG_FILE:
    app_config = yaml.safe_load(file(APP_CONFIG_FILE, 'r'))
    process_app_config(app_config)
<|endoftext|>


<commit_before>import datetime
import random
import re

from django.conf import settings
from django.template.loader import render_to_string
from django.utils.hashcompat import sha_constructor

from couchdbkit.ext.django.schema import *
from django_couchdb_utils.auth.models import User

SHA1_RE = re.compile('^[a-f0-9]{40}$')

def activate_user(activation_key):
    """
    Validate an activation key and activate the corresponding
    ``User`` if valid.

    If the key is valid and has not expired, return the ``User``
    after activating.

    If the key is not valid or has expired, return ``False``.

    If the key is valid but the ``User`` is already active,
    return ``False``.

    To prevent reactivation of an account which has been
    deactivated by site administrators, the activation key is
    reset to the string constant ``RegistrationProfile.ACTIVATED``
    after successful activation.

    """
    # Make sure the key we're trying conforms to the pattern of a
    # SHA1 hash; if it doesn't, no point trying to look it up in
    # the database.
    if not SHA1_RE.search(activation_key):
        return False

    user = User.get_by_key(activation_key)

    if not user.activation_key_expired():
        del user.activation_key
        user.is_active = True
        user.save()
        return user

def create_inactive_user(username, email, password,
                         site, send_email=True):
    """
    Create a new, inactive ``User``, generate a
    ``RegistrationProfile`` and email its activation key to the
    ``User``, returning the new ``User``.

    By default, an activation email will be sent to the new
    user. To disable this, pass ``send_email=False``.

    """
    new_user = User()
    new_user.username = username
    new_user.email = email
    new_user.set_password(password)
    new_user.is_active = False
    create_profile(new_user)
    new_user.save()

    if send_email:
        new_user.send_activation_email(site)

    return new_user

def create_profile(user):
    """
    Create a ``RegistrationProfile`` for a given
    ``User``, and return the ``RegistrationProfile``.

    The activation key for the ``RegistrationProfile`` will be a
    SHA1 hash, generated from a combination of the ``User``'s
    username and a random salt.

    """
    salt = sha_constructor(str(random.random())).hexdigest()[:5]
    username = user.username
    if isinstance(username, unicode):
        username = username.encode('utf-8')
    user.activation_key = sha_constructor(salt+username).hexdigest()

def delete_expired_users():
    """
    Remove expired instances of ``RegistrationProfile`` and their
    associated ``User``s.

    Accounts to be deleted are identified by searching for
    instances of ``RegistrationProfile`` with expired activation
    keys, and then checking to see if their associated ``User``
    instances have the field ``is_active`` set to ``False``; any
    ``User`` who is both inactive and has an expired activation
    key will be deleted.

    It is recommended that this method be executed regularly as
    part of your routine site maintenance; this application
    provides a custom management command which will call this
    method, accessible as ``manage.py cleanupregistration``.

    Regularly clearing out accounts which have never been
    activated serves two useful purposes:

    1. It alleviates the ocasional need to reset a
       ``RegistrationProfile`` and/or re-send an activation email
       when a user does not receive or does not act upon the
       initial activation email; since the account will be
       deleted, the user will be able to simply re-register and
       receive a new activation key.

    2. It prevents the possibility of a malicious user registering
       one or more accounts and never activating them (thus
       denying the use of those usernames to anyone else); since
       those accounts will be deleted, the usernames will become
       available for use again.

    If you have a troublesome ``User`` and wish to disable their
    account while keeping it in the database, simply delete the
    associated ``RegistrationProfile``; an inactive ``User`` which
    does not have an associated ``RegistrationProfile`` will not
    be deleted.

    """
    for user in User.all_users():
        if user.activation_key_expired():
            if not user.is_active:
                user.delete()

def get_migration_user_data(user):
    """
    Returns the data that will be merged into the User object
    when migrating an ORM-based User to CouchDB
    """
    try:
        reg_profile = RegistrationProfile.objects.get(user=user)
        if reg_profile.activation_key != RegistrationProfile.ACTIVATED and \
            not user.is_active:
            return {'activation_key': reg_profile.activation_key}
    except:
        return {}

class User(User):
    """
    A simple profile which stores an activation key for use during
    user account registration.

    Generally, you will not want to interact directly with instances
    of this model; the provided manager includes methods
    for creating and activating new accounts, as well as for cleaning
    out accounts which have never been activated.

    While it is possible to use this model as the value of the
    ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do
    so. This model's sole purpose is to store data temporarily during
    account registration and activation.

    """
    activation_key = StringProperty()

    class Meta:
        app_label = 'registration_couchdb'

    @classmethod
    def get_by_key(cls, key):
        r = cls.view('registration_couchdb/users_by_activationkey',
                key          = key,
                include_docs = True,
            )
        return r.first() if r else None

    def activation_key_expired(self):
        """
        Determine whether this ``RegistrationProfile``'s activation
        key has expired, returning a boolean -- ``True`` if the key
        has expired.

        Key expiration is determined by a two-step process:

        1. If the user has already activated, the key will have been
           reset to the string constant ``ACTIVATED``. Re-activating
           is not permitted, and so this method returns ``True`` in
           this case.

        2. Otherwise, the date the user signed up is incremented by
           the number of days specified in the setting
           ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of
           days after signup during which a user is allowed to
           activate their account); if the result is less than or
           equal to the current date, the key has expired and this
           method returns ``True``.

        """
        expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
        return bool(getattr(self, 'activation_key', False) and \
               (self.date_joined + expiration_date <= datetime.datetime.now()))
    activation_key_expired.boolean = True

    def send_activation_email(self, site):
        """
        Send an activation email to the user associated with this
        ``RegistrationProfile``.

        The activation email will make use of two templates:

        ``registration/activation_email_subject.txt``
            This template will be used for the subject line of the
            email. Because it is used as the subject line of an email,
            this template's output **must** be only a single line of
            text; output longer than one line will be forcibly joined
            into only a single line.

        ``registration/activation_email.txt``
            This template will be used for the body of the email.

        These templates will each receive the following context
        variables:

        ``activation_key``
            The activation key for the new account.

        ``expiration_days``
            The number of days remaining during which the account may
            be activated.

        ``site``
            An object representing the site on which the user
            registered; depending on whether ``django.contrib.sites``
            is installed, this may be an instance of either
            ``django.contrib.sites.models.Site`` (if the sites
            application is installed) or
            ``django.contrib.sites.models.RequestSite`` (if
            not). Consult the documentation for the Django sites
            framework for details regarding these objects' interfaces.

        """
        ctx_dict = {'activation_key': self.activation_key,
                    'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
                    'site': site}
        subject = render_to_string('registration/activation_email_subject.txt',
                                   ctx_dict)
        # Email subject *must not* contain newlines
        subject = ''.join(subject.splitlines())

        message = render_to_string('registration/activation_email.txt',
                                   ctx_dict)

        self.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)

<commit_msg>remove unnecessary attribute of method<commit_after>import datetime
import random
import re

from django.conf import settings
from django.template.loader import render_to_string
from django.utils.hashcompat import sha_constructor

from couchdbkit.ext.django.schema import *
from django_couchdb_utils.auth.models import User

SHA1_RE = re.compile('^[a-f0-9]{40}$')

def activate_user(activation_key):
    """
    Validate an activation key and activate the corresponding
    ``User`` if valid.

    If the key is valid and has not expired, return the ``User``
    after activating.

    If the key is not valid or has expired, return ``False``.

    If the key is valid but the ``User`` is already active,
    return ``False``.

    To prevent reactivation of an account which has been
    deactivated by site administrators, the activation key is
    reset to the string constant ``RegistrationProfile.ACTIVATED``
    after successful activation.

    """
    # Make sure the key we're trying conforms to the pattern of a
    # SHA1 hash; if it doesn't, no point trying to look it up in
    # the database.
    if not SHA1_RE.search(activation_key):
        return False

    user = User.get_by_key(activation_key)

    if not user.activation_key_expired():
        del user.activation_key
        user.is_active = True
        user.save()
        return user

def create_inactive_user(username, email, password,
                         site, send_email=True):
    """
    Create a new, inactive ``User``, generate a
    ``RegistrationProfile`` and email its activation key to the
    ``User``, returning the new ``User``.

    By default, an activation email will be sent to the new
    user. To disable this, pass ``send_email=False``.

    """
    new_user = User()
    new_user.username = username
    new_user.email = email
    new_user.set_password(password)
    new_user.is_active = False
    create_profile(new_user)
    new_user.save()

    if send_email:
        new_user.send_activation_email(site)

    return new_user

def create_profile(user):
    """
    Create a ``RegistrationProfile`` for a given
    ``User``, and return the ``RegistrationProfile``.

    The activation key for the ``RegistrationProfile`` will be a
    SHA1 hash, generated from a combination of the ``User``'s
    username and a random salt.

    """
    salt = sha_constructor(str(random.random())).hexdigest()[:5]
    username = user.username
    if isinstance(username, unicode):
        username = username.encode('utf-8')
    user.activation_key = sha_constructor(salt+username).hexdigest()

def delete_expired_users():
    """
    Remove expired instances of ``RegistrationProfile`` and their
    associated ``User``s.

    Accounts to be deleted are identified by searching for
    instances of ``RegistrationProfile`` with expired activation
    keys, and then checking to see if their associated ``User``
    instances have the field ``is_active`` set to ``False``; any
    ``User`` who is both inactive and has an expired activation
    key will be deleted.

    It is recommended that this method be executed regularly as
    part of your routine site maintenance; this application
    provides a custom management command which will call this
    method, accessible as ``manage.py cleanupregistration``.

    Regularly clearing out accounts which have never been
    activated serves two useful purposes:

    1. It alleviates the ocasional need to reset a
       ``RegistrationProfile`` and/or re-send an activation email
       when a user does not receive or does not act upon the
       initial activation email; since the account will be
       deleted, the user will be able to simply re-register and
       receive a new activation key.

    2. It prevents the possibility of a malicious user registering
       one or more accounts and never activating them (thus
       denying the use of those usernames to anyone else); since
       those accounts will be deleted, the usernames will become
       available for use again.

    If you have a troublesome ``User`` and wish to disable their
    account while keeping it in the database, simply delete the
    associated ``RegistrationProfile``; an inactive ``User`` which
    does not have an associated ``RegistrationProfile`` will not
    be deleted.

    """
    for user in User.all_users():
        if user.activation_key_expired():
            if not user.is_active:
                user.delete()

def get_migration_user_data(user):
    """
    Returns the data that will be merged into the User object
    when migrating an ORM-based User to CouchDB
    """
    try:
        reg_profile = RegistrationProfile.objects.get(user=user)
        if reg_profile.activation_key != RegistrationProfile.ACTIVATED and \
            not user.is_active:
            return {'activation_key': reg_profile.activation_key}
    except:
        return {}

class User(User):
    """
    A simple profile which stores an activation key for use during
    user account registration.

    Generally, you will not want to interact directly with instances
    of this model; the provided manager includes methods
    for creating and activating new accounts, as well as for cleaning
    out accounts which have never been activated.

    While it is possible to use this model as the value of the
    ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do
    so. This model's sole purpose is to store data temporarily during
    account registration and activation.

    """
    activation_key = StringProperty()

    class Meta:
        app_label = 'registration_couchdb'

    @classmethod
    def get_by_key(cls, key):
        r = cls.view('registration_couchdb/users_by_activationkey',
                key          = key,
                include_docs = True,
            )
        return r.first() if r else None

    def activation_key_expired(self):
        """
        Determine whether this ``RegistrationProfile``'s activation
        key has expired, returning a boolean -- ``True`` if the key
        has expired.

        Key expiration is determined by a two-step process:

        1. If the user has already activated, the key will have been
           reset to the string constant ``ACTIVATED``. Re-activating
           is not permitted, and so this method returns ``True`` in
           this case.

        2. Otherwise, the date the user signed up is incremented by
           the number of days specified in the setting
           ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of
           days after signup during which a user is allowed to
           activate their account); if the result is less than or
           equal to the current date, the key has expired and this
           method returns ``True``.

        """
        expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
        return bool(getattr(self, 'activation_key', False) and \
               (self.date_joined + expiration_date <= datetime.datetime.now()))

    def send_activation_email(self, site):
        """
        Send an activation email to the user associated with this
        ``RegistrationProfile``.

        The activation email will make use of two templates:

        ``registration/activation_email_subject.txt``
            This template will be used for the subject line of the
            email. Because it is used as the subject line of an email,
            this template's output **must** be only a single line of
            text; output longer than one line will be forcibly joined
            into only a single line.

        ``registration/activation_email.txt``
            This template will be used for the body of the email.

        These templates will each receive the following context
        variables:

        ``activation_key``
            The activation key for the new account.

        ``expiration_days``
            The number of days remaining during which the account may
            be activated.

        ``site``
            An object representing the site on which the user
            registered; depending on whether ``django.contrib.sites``
            is installed, this may be an instance of either
            ``django.contrib.sites.models.Site`` (if the sites
            application is installed) or
            ``django.contrib.sites.models.RequestSite`` (if
            not). Consult the documentation for the Django sites
            framework for details regarding these objects' interfaces.

        """
        ctx_dict = {'activation_key': self.activation_key,
                    'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
                    'site': site}
        subject = render_to_string('registration/activation_email_subject.txt',
                                   ctx_dict)
        # Email subject *must not* contain newlines
        subject = ''.join(subject.splitlines())

        message = render_to_string('registration/activation_email.txt',
                                   ctx_dict)

        self.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)

<|endoftext|>


<commit_before>import time
import paho.mqtt.client as mqtt

class MQTTException(Exception):

    def __init__(self, message, value = None):

        super().__init__(message)
        self.value = value

class BaseClient():

    # initialize client
    def __init__(self,
                 broker,
                 stdout,
                 style,
                 verbosity = 1,
                 **kwargs):

        # initialize client
        self.stdout = stdout
        self.style = style
        self.broker = broker
        self.verbosity = verbosity

        self.debug = kwargs.pop('debug', False)
        self.forgive_mid = False

        if self.broker['CLIENT_ID']:
            self.client = mqtt.Client(self.broker['CLIENT_ID'],
                                      self.broker['CLEAN_SESSION'])
        else:
            self.client = mqtt.Client()
        self.client.on_connect = self.on_connect

        self.subscribed = {}
        self.published = {}

        self.client.on_publish = self.on_publish
        self.client.on_subscribe = self.on_subscribe
        self.client.on_disconnect = self.on_disconnect

        # default message handler
        self.client.on_message = self.on_message

        if self.broker['USERNAME'] and self.broker['PASSWORD']:
            self.client.username_pw_set(self.broker['USERNAME'],
                                        self.broker['PASSWORD'])

        self.connected = False

        self.client.connect(self.broker['HOST'],
                            self.broker['PORT'],
                            self.broker['KEEPALIVE'])

    def on_connect(self, client, userdata, flags, rc):

        if rc:
            raise MQTTException('Could not connect to brocker (rc = {})'.format(rc),
                                rc)

        self.connected = True

        # success!
        if self.verbosity > 0:
            self.stdout.write(self.style.SUCCESS(">> Connected to the MQTT brocker '{}:{}'".format(self.broker['HOST'], self.broker['PORT'])))

        return True

    def on_message(self, client, userdata, msg):
        pass

    def publish(self, topic, payload = None, qos = 0, retain = False):

        # NOTE: The whole forgive mid thing is necessary because
        # on_publish was getting called before publish ended
        # forgive mid if qos = 0
        if qos == 0:
            self.forgive_mid = True

        # try to publish
        result = self.client.publish(topic, payload, qos, retain)
        if result.rc:
            raise MQTTException('Could not publish to topic (rc = {})'.format(result.rc),
                                result.rc)

        if qos != 0:
            # add to dictionary of published
            self.published[result.mid] = (topic, payload, qos, retain)
        else:

            # reset forgive_mid
            self.forgive_mid = False

            # on_published already called?
            if result.mid in self.published:
                if self.published.pop(result.mid) is not None:
                    raise MQTTException('Cannot make sense of mid', result.mid)
            else:
                # add to dictionary of published
                self.published[result.mid] = (topic, payload, qos, retain)

        # debug?
        if self.debug:
            print(("> Just published '{}[mid={}]:{}'" +
                   "(qos={},retain={})").format(topic,
                                                result.mid,
                                                payload,
                                                qos,
                                                retain))

    def on_publish(self, client, userdata, mid):

        # debug?
        if self.debug:
            print("> Published mid={}".format(mid))

        if mid in self.published:
            # TODO: check granted_qos?
            # remove from list of subscribed
            del self.published[mid]

        else:
            self.published[mid] = None
            if not self.forgive_mid:
                raise MQTTException('Unknown publish mid', mid)

    def subscribe(self, topic, qos = 0):

        # try to subscribe
        result, mid = self.client.subscribe(topic, qos)
        if result:
            raise MQTTException('Could not subscribe to topic',
                                result)

        # debug?
        if self.debug:
            print("> Just subscribed to '{}'[mid={}][qos={}]".format(topic,
                                                                     mid,
                                                                     qos))

        # otherwise add to dictionary of subscribed
        self.subscribed[mid] = (topic, qos)

        #print('topic = {}, mid = {}'.format(topic, mid))

    def on_subscribe(self, client, userdata, mid, granted_qos):

        # debug?
        if self.debug:
            print("> Subscribed mid={}, qos={}".format(mid, granted_qos))

        if mid in self.subscribed:
            # TODO: check granted_qos?
            # remove from list of subscribed
            del self.subscribed[mid]

        else:
            raise MQTTException('Unknown subscribe mid', mid)

    def on_disconnect(self, client, userdata, rc):
        self.connected = False
        # print('>> disconnecting reason {}'.format(rc))

    # disconnect
    def disconnect(self):
        self.client.disconnect()

    # loop
    def loop(self, *args, **kwargs):
        self.client.loop(*args, **kwargs)

    # loop_start
    def loop_start(self):
        self.client.loop_start()

    # loop_stop
    def loop_stop(self, *args, **kwargs):
        self.client.loop_stop(*args, **kwargs)

    # loop forever
    def loop_forever(self):
        self.client.loop_forever()

    # loop forever
    def loop(self):
        self.client.loop()

    def loop_start(self):
        self.client.loop_start()

    # wait for disconnect
    def wait(self, MAX_TRIES = 10):
        self.disconnect()
        k = 0
        while self.connected and k < MAX_TRIES:
            k += 1
            time.sleep(1)

        if self.connected:
            raise MQTTException('Could not disconnect')
<commit_msg>Add more time to mqtt.test.client<commit_after>import time
import paho.mqtt.client as mqtt

class MQTTException(Exception):

    def __init__(self, message, value = None):

        super().__init__(message)
        self.value = value

class BaseClient():

    # initialize client
    def __init__(self,
                 broker,
                 stdout,
                 style,
                 verbosity = 1,
                 **kwargs):

        # initialize client
        self.stdout = stdout
        self.style = style
        self.broker = broker
        self.verbosity = verbosity

        self.debug = kwargs.pop('debug', False)
        self.forgive_mid = False

        if self.broker['CLIENT_ID']:
            self.client = mqtt.Client(self.broker['CLIENT_ID'],
                                      self.broker['CLEAN_SESSION'])
        else:
            self.client = mqtt.Client()
        self.client.on_connect = self.on_connect

        self.subscribed = {}
        self.published = {}

        self.client.on_publish = self.on_publish
        self.client.on_subscribe = self.on_subscribe
        self.client.on_disconnect = self.on_disconnect

        # default message handler
        self.client.on_message = self.on_message

        if self.broker['USERNAME'] and self.broker['PASSWORD']:
            self.client.username_pw_set(self.broker['USERNAME'],
                                        self.broker['PASSWORD'])

        self.connected = False

        self.client.connect(self.broker['HOST'],
                            self.broker['PORT'],
                            self.broker['KEEPALIVE'])

    def on_connect(self, client, userdata, flags, rc):

        if rc:
            raise MQTTException('Could not connect to brocker (rc = {})'.format(rc),
                                rc)

        self.connected = True

        # success!
        if self.verbosity > 0:
            self.stdout.write(self.style.SUCCESS(">> Connected to the MQTT brocker '{}:{}'".format(self.broker['HOST'], self.broker['PORT'])))

        return True

    def on_message(self, client, userdata, msg):
        pass

    def publish(self, topic, payload = None, qos = 0, retain = False):

        # NOTE: The whole forgive mid thing is necessary because
        # on_publish was getting called before publish ended
        # forgive mid if qos = 0
        if qos == 0:
            self.forgive_mid = True

        # try to publish
        result = self.client.publish(topic, payload, qos, retain)
        if result.rc:
            raise MQTTException('Could not publish to topic (rc = {})'.format(result.rc),
                                result.rc)

        if qos != 0:
            # add to dictionary of published
            self.published[result.mid] = (topic, payload, qos, retain)
        else:

            # reset forgive_mid
            self.forgive_mid = False

            # on_published already called?
            if result.mid in self.published:
                if self.published.pop(result.mid) is not None:
                    raise MQTTException('Cannot make sense of mid', result.mid)
            else:
                # add to dictionary of published
                self.published[result.mid] = (topic, payload, qos, retain)

        # debug?
        if self.debug:
            print(("> Just published '{}[mid={}]:{}'" +
                   "(qos={},retain={})").format(topic,
                                                result.mid,
                                                payload,
                                                qos,
                                                retain))

    def on_publish(self, client, userdata, mid):

        # debug?
        if self.debug:
            print("> Published mid={}".format(mid))

        if mid in self.published:
            # TODO: check granted_qos?
            # remove from list of subscribed
            del self.published[mid]

        else:
            self.published[mid] = None
            if not self.forgive_mid:
                raise MQTTException('Unknown publish mid', mid)

    def subscribe(self, topic, qos = 0):

        # try to subscribe
        result, mid = self.client.subscribe(topic, qos)
        if result:
            raise MQTTException('Could not subscribe to topic',
                                result)

        # debug?
        if self.debug:
            print("> Just subscribed to '{}'[mid={}][qos={}]".format(topic,
                                                                     mid,
                                                                     qos))

        # otherwise add to dictionary of subscribed
        self.subscribed[mid] = (topic, qos)

        #print('topic = {}, mid = {}'.format(topic, mid))

    def on_subscribe(self, client, userdata, mid, granted_qos):

        # debug?
        if self.debug:
            print("> Subscribed mid={}, qos={}".format(mid, granted_qos))

        if mid in self.subscribed:
            # TODO: check granted_qos?
            # remove from list of subscribed
            del self.subscribed[mid]

        else:
            raise MQTTException('Unknown subscribe mid', mid)

    def on_disconnect(self, client, userdata, rc):
        print('>> disconnecting reason {}'.format(rc))
        self.connected = False

    # disconnect
    def disconnect(self):
        self.client.disconnect()

    # loop
    def loop(self, *args, **kwargs):
        self.client.loop(*args, **kwargs)

    # loop_start
    def loop_start(self):
        self.client.loop_start()

    # loop_stop
    def loop_stop(self, *args, **kwargs):
        self.client.loop_stop(*args, **kwargs)

    # loop forever
    def loop_forever(self):
        self.client.loop_forever()

    # loop forever
    def loop(self):
        self.client.loop()

    def loop_start(self):
        self.client.loop_start()

    # wait for disconnect
    def wait(self, MAX_TRIES = 10):
        self.disconnect()
        k = 0
        while self.connected and k < MAX_TRIES:
            k += 1
            time.sleep(1)

        if self.connected:
            raise MQTTException('Could not disconnect')
<|endoftext|>


<commit_before>from ogusa.macro_output import dump_diff_output
import matplotlib.pyplot as plt
import numpy as np
import pickle
import pytest

REG_BASELINE = '../regression/REG_OUTPUT_BASELINE'
REG_REFORM = '../regression/REG_OUTPUT_REFORM_{id}'
REF_IDXS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#SWAP TO NEW DIRECTORY -- for test development only!!!!
BASELINE = REG_BASELINE
REFORM = REG_REFORM

@pytest.fixture(scope="module", params=REF_IDXS)
def macro_outputs(request):
    (pct_changes,
        baseline_macros,
        policy_macros) = dump_diff_output(BASELINE,
                                          REFORM.format(id=request.param))
    (reg_pct_changes,
        reg_baseline_macros,
        reg_policy_macros) = dump_diff_output(REG_BASELINE,
                                              REG_REFORM.format(id=request.param))

    return {"new":{
                   "pct_changes": pct_changes,
                   "baseline_macros": baseline_macros,
                   "policy_macros": policy_macros
                  },
            "reg": {
                    "pct_changes": reg_pct_changes,
                    "baseline_macros": reg_baseline_macros,
                    "policy_macros": reg_policy_macros
                    },
            }

OUTPUT_VARS = ["Y", "C", "I", "L", "w", "r", "Revenue"]
@pytest.mark.parametrize("output_var_idx", np.arange(len(OUTPUT_VARS)))
def test_macro_output(macro_outputs, output_var_idx):
    """
    Compare macro output

    baseline_dir: directory for baseline input to compare to regression results
    reform_dir: directory for reform input to compare to regression results
    """

    # output_vars = ["Y", "C", "I", "L", "w", "r", "Revenue"]

    # for i in range(len(output_vars)):
    assert np.allclose(
        macro_outputs["new"]["pct_changes"][output_var_idx, :],
        macro_outputs["reg"]["pct_changes"][output_var_idx, :],
        atol=0.0, rtol=0.001
    )

# def get_tpi_vars(path):
#     with open(path, 'rb') as f:
#         return pickle.loads(path)
#
# def comp_TPI_vars(baseline_dir, output_dir, ref_idx=0):
#     """
#     Compare TPI_vars
#     """
#     tpi = get_tpi_vars(path=REG )

def plot_reforms(r1_ix, r2_ix=None, r3_ix=None):
    plot_vars = ["Y", "C", "I", "L", "w", "r", "Revenue"]
    plt.figure(figsize=(3, 3))
    for i in range(0, len(plot_vars)):
        t = list(range(12))
        t = [n + 2016 for n in t]
        plt.subplot(331 + i)
        plt.plot(t, pct_changes[r1_ix][i,:],'-b', label='reform {}'.format(r1_ix))
        if r2_ix is not None:
            plt.plot(t, pct_changes[r2_ix][i,:], '-r', label='reform {}'.format(r2_ix))
        if r3_ix is not None:
            plt.plot(t, pct_changes[r3_ix][i,:], '-g', label='reform {}'.format(r3_ix))
        plt.title("PCT Changes {0} from 2016 to steady state".format(plot_vars[i]))
        plt.legend()
    plt.show()
    plt.figure()

# if __name__ == '__main__':
#     pct_changes, baseline_macros, policy_macros = get_macros()
#
#     plot_reforms(9)
<commit_msg>Add test for tpi output<commit_after>from ogusa.macro_output import dump_diff_output
import matplotlib.pyplot as plt
import numpy as np
import pickle
import pytest

REG_BASELINE = '../regression/REG_OUTPUT_BASELINE'
REG_REFORM = '../regression/REG_OUTPUT_REFORM_{ref_idx}'
REF_IDXS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#SWAP TO NEW DIRECTORY -- for test development only!!!!
BASELINE = REG_BASELINE
REFORM = REG_REFORM

@pytest.fixture(scope="module", params=REF_IDXS)
def macro_outputs(request):
    (pct_changes,
        baseline_macros,
        policy_macros) = dump_diff_output(BASELINE,
                                          REFORM.format(ref_idx=request.param))
    (reg_pct_changes,
        reg_baseline_macros,
        reg_policy_macros) = dump_diff_output(REG_BASELINE,
                                              REG_REFORM.format(ref_idx=request.param))

    return {"new":{
                   "pct_changes": pct_changes,
                   "baseline_macros": baseline_macros,
                   "policy_macros": policy_macros
                  },
            "reg": {
                    "pct_changes": reg_pct_changes,
                    "baseline_macros": reg_baseline_macros,
                    "policy_macros": reg_policy_macros
                    },
            }

OUTPUT_VARS = ["Y", "C", "I", "L", "w", "r", "Revenue"]
@pytest.mark.parametrize("output_var_idx", np.arange(len(OUTPUT_VARS)))
def test_macro_output(macro_outputs, output_var_idx):
    """
    Compare macro output

    baseline_dir: directory for baseline input to compare to regression results
    reform_dir: directory for reform input to compare to regression results
    """
    assert np.allclose(
        macro_outputs["new"]["pct_changes"][output_var_idx, :],
        macro_outputs["reg"]["pct_changes"][output_var_idx, :],
        atol=0.0, rtol=0.001
    )

@pytest.fixture(scope="module", params=REF_IDXS + ["baseline"])
def tpi_output(request):
    def get_tpi_output(path):
        with open(path + "/TPI/TPI_vars.pkl", 'rb') as f:
            return pickle.load(f)

    ref_idx = request.param
    if ref_idx == "baseline":
        return (get_tpi_output(REG_BASELINE), get_tpi_output(BASELINE))
    else:
        return (get_tpi_output(path=REG_REFORM.format(ref_idx=request.param)),
                get_tpi_output(path=REFORM.format(ref_idx=request.param)))

TPI_VARS = ['C', 'D', 'G', 'REVENUE', 'I', 'K', 'tax_path', 'L',
            'eul_laborleisure', 'T_H', 'r', 'n_mat', 'BQ', 'w', 'Y',
            'eul_savings', 'c_path', 'b_mat']

@pytest.mark.parametrize("tpi_var", TPI_VARS)
def test_tpi_vars(tpi_output, tpi_var):
    """
    Compare TPI_vars
    """
    reg = tpi_output[0][tpi_var]
    new = tpi_output[1][tpi_var]
    assert np.allclose(reg, new, atol=0.0, rtol=0.001)
<|endoftext|>


<commit_before># Copyright 2012 Daniel B. Allan
# dallan@pha.jhu.edu, daniel.b.allan@gmail.com
# http://pha.jhu.edu/~dallan
# http://www.danallan.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses>.

import logging
import matplotlib
import os
import warnings

# Configure logging for all modules in this package.
FORMAT = "%(name)s.%(funcName)s:  %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT)

# Choose matplotlib backend before matplotlib.pyplot is imported by the modules.
# If the environmental variable 'ssh' is set, use the ssh-safe backend, Agg.
# Otherwise, use the backend GTKAgg.
with warnings.catch_warnings(): # Catch warning on reload(mr).
    try:
        os.environ['ssh']
        matplotlib.use('Agg')
    except KeyError:
        matplotlib.use('GTKAgg')

from mr.api import *
<commit_msg>Remove matplotlib.use<commit_after># Copyright 2012 Daniel B. Allan
# dallan@pha.jhu.edu, daniel.b.allan@gmail.com
# http://pha.jhu.edu/~dallan
# http://www.danallan.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses>.

import logging
import matplotlib
import os
import warnings

# Configure logging for all modules in this package.
FORMAT = "%(name)s.%(funcName)s:  %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT)

from mr.api import *
<|endoftext|>


<commit_before>'''Cocos tilemap editor!

Usage: editor.py <level.xml>

The level must contain at least one <rectmap> and one <tileset> (either
directly or via <requires>).

PALETTE:
- Click LMB in the palette to select the active tile.
- Use LMB dragging on the palette to drag it around the window.

MAP:
- Click LMB in the map to set the map to the active tile.
- Click RMB in the map to clear the map cell.
- Use the scroll-wheel to zoom in and out.
- Use LMB dragging to pan around the map. Alternatively use the arrow keys
  to pan around.

Hit "d" to turn some debugging information on (cell location, pixel location,
cell properties).

Hit control-s to save the map and quit.

Hit control-q, or escape, or the window close button to quit without saving.

'''

import pyglet
from pyglet.gl import *
import cocos
from cocos import tiles, actions
from cocos.director import director

class TileEditorLayer(tiles.ScrollableLayer):
    is_event_handler = True

    def __init__(self, manager, level_to_edit, selector, filename):
        super(TileEditorLayer, self).__init__()
        self.manager = manager
        self.level_to_edit = level_to_edit
        self.filename = filename
        self.highlight = None
        self.selector = selector
        self.tileset = selector.tileset

    def on_key_press(self, key, modifier):
        if modifier & pyglet.window.key.MOD_ACCEL:
            if key == pyglet.window.key.S:
                self.level_to_edit.save_xml(self.filename)
                director.pop()
            elif key == pyglet.window.key.Q:
                director.pop()
        if key == pyglet.window.key.D:
            m = self.selector.map_layer
            m.set_debug(not m.debug)

    _desired_scale = 1
    def on_mouse_scroll(self, x, y, dx, dy):
        if dy < 0:
            if self._desired_scale < .2: return True
            self._desired_scale -= .1
        elif dy > 0:
            if self._desired_scale > 2: return True
            self._desired_scale += .1
        if dy:
            self.manager.do(actions.ScaleTo(self._desired_scale, .1))
            return True

    def on_text_motion(self, motion):
        fx, fy = self.manager.fx, self.manager.fy
        if motion == pyglet.window.key.MOTION_UP:
            self.manager.set_focus(fx, fy+64/self._desired_scale)
        elif motion == pyglet.window.key.MOTION_DOWN:
            self.manager.set_focus(fx, fy-64/self._desired_scale)
        elif motion == pyglet.window.key.MOTION_LEFT:
            self.manager.set_focus(fx-64/self._desired_scale, fy)
        elif motion == pyglet.window.key.MOTION_RIGHT:
            self.manager.set_focus(fx+64/self._desired_scale, fy)
        else:
            return False
        return True

    _dragging = False
    def on_mouse_press(self, x, y, buttons, modifiers):
        self._drag_start = (x, y)
        self._dragging = False

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if not buttons & pyglet.window.mouse.LEFT:
            return False
        if not self._dragging:
            _x, _y = self._drag_start
            if abs(x - _x) + abs(y - _y) < 6:
                return False
        self._dragging = True
        self.manager.set_focus(self.manager.fx-dx/self._desired_scale,
            self.manager.fy-dy/self._desired_scale)

    def on_mouse_release(self, x, y, buttons, modifiers):
        if self._dragging:
            self._dragging = False
            return False
        m = self.selector.map_layer

        # get the cell and cell coordinate
        x, y = self.manager.pixel_from_screen(x, y)
        cell = m.get_at_pixel(x, y)
        if not cell:
            # click not in map
            return

        # now add the cell
        if buttons & pyglet.window.mouse.LEFT:
            cell.tile = self.selector.tileset[self.selector.current.tile_id]
            self.selector.map_layer.set_dirty()
        elif buttons & pyglet.window.mouse.RIGHT:
            cell.tile = None
            self.selector.map_layer.set_dirty()
        return True

    def on_mouse_motion(self, x, y, dx, dy):
        m = self.selector.map_layer
        cell = m.get_at_pixel(*self.manager.pixel_from_screen(x, y))
        if not cell:
            self.highlight = None
            return True
        x = cell.x + m.origin_x
        y = cell.y + m.origin_y
        self.highlight = (x, y, x+m.tw, y+m.th)
        return True

    def draw(self):
        if self.highlight is None:
            return
        glPushMatrix()
        self.transform()
        glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glColor4f(1, 1, 0, .3)
        glRectf(*self.highlight)
        glPopAttrib()
        glPopMatrix()

class TileSetLayer(cocos.layer.Layer):
    is_event_handler = True

    TILE_SIZE = 32
    def __init__(self, level_to_edit):
        super(TileSetLayer, self).__init__()
        self.level_to_edit = level_to_edit
        self.map_layer = level_to_edit.find(tiles.MapLayer).next()[1]
        self.tileset = level_to_edit.findall(tiles.TileSet).next()[1]
        self.batch = pyglet.graphics.Batch()

        # labels
        ly = self.TILE_SIZE * 8 + 8
        self.tiles_label = pyglet.text.Label('Tiles', batch=self.batch, y=ly)
        self.active_tab = self.tiles_label
        w = self.tiles_label.content_width + 8
        h = self.tiles_label.content_height
        self.layers_label = pyglet.text.Label('Layers', batch=self.batch, y=ly,
            color=(200, 200, 200, 255))
        self.layers_label.x = w
        h = max(h, self.layers_label.content_height)
        w += self.layers_label.content_width + 8
        self.tilesets_label = pyglet.text.Label('Tilesets', batch=self.batch,
            y=ly, color=(200, 200, 200, 255))
        self.tilesets_label.x = w
        h = max(h, self.tilesets_label.content_height)
        w += self.tilesets_label.content_width

        self._width = (int(w) / self.TILE_SIZE) * self.TILE_SIZE + 8
        if int(w) % self.TILE_SIZE: self._width += self.TILE_SIZE
        self._height = h + 16 + self.TILE_SIZE * 8

        # set up the background
        bg = pyglet.image.SolidColorImagePattern((0, 0, 0, 200))
        bg = pyglet.image.create(self._width, self._height, pattern=bg)

        # set up the tiles
        self.active_batch = self.tiles_batch = pyglet.graphics.Batch()
        self.bg = pyglet.sprite.Sprite(bg, group=pyglet.graphics.OrderedGroup(0),
            batch=self.active_batch)
        self.tile_sprites = []
        x = y = 4
        for n, k in enumerate(self.tileset):
            s = pyglet.sprite.Sprite(self.tileset[k].image, y=y, x=x,
                batch=self.tiles_batch)
            if not n:
                self.current = s
            s.tile_id = k
            self.tile_sprites.append(s)
            s.scale = self.TILE_SIZE / float(s.width)
            if not n % 8:
                y = 4; x += self.TILE_SIZE
            else:
                y += self.TILE_SIZE

        # set up the layers buttons
        self.layers_batch = pyglet.graphics.Batch()
        self.layer_labels = []
        self.layer_visible = []
        y = 4
        for k,v in level_to_edit.find(tiles.MapLayer):
            l = pyglet.text.Label(k, batch=self.layers_batch, y=y,
                    color=(255,255,255,255))
            v.map_layer = l
            if v is self.map_layer:
                l.color = (255, 255, 200, 255)
            y += l.content_height + 2
            self.layer_labels.append(l)

        # set up the tilesets buttons
        self.tilesets_batch = pyglet.graphics.Batch()
        self.layer_labels = []
        y = 4
        for id, ts in self.level_to_edit.findall(tiles.TileSet):
            if id is None: id = '[no id]'
            l = pyglet.text.Label(id, batch=self.tilesets_batch,
                    color=(255,255,255,255), y=y, x=4)
            l._tileset = ts
            y += l.content_height + 2
            self.layer_labels.append(l)

        self.highlight = (4, 4)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if not buttons & pyglet.window.mouse.LEFT:
            return False
        if self._drag_start is None:
            return False
        if not self._dragging:
            _x, _y = self._drag_start
            if abs(x - _x) + abs(y - _y) < 6:
                return False
        self._dragging = True
        x, y = self.position
        self.position = (x+dx, y+dy)
        return True

    def on_mouse_release(self, x, y, button, modifiers):
        if self._dragging:
            self._dragging = False
            self._drag_start = None
            return True

        lx, ly = self.position

        if self.active_tab is self.tiles_label:
            for s in self.tile_sprites:
                sx = s.x + lx
                sy = s.y + ly
                if x < sx or x > sx + s.width: continue
                if y < sy or y > sy + s.height: continue
                self.current = s
                self.highlight = (s.x, s.y)
                return True
        #elif self.active_tab is self.layers_label:
            #XXX handle clicks in there...

        _x = self.tiles_label.x+lx
        _y = self.tiles_label.y+ly
        if (x > _x and x < _x + self.tiles_label.content_width and
                y > _y and y < _y + self.tiles_label.content_height):
            self.active_tab.color = (200, 200, 200, 255)
            self.active_tab = self.tiles_label
            self.active_tab.color = (255, 255, 255, 255)
            self.active_batch = self.tiles_batch
            return True

        _x = self.layers_label.x+lx
        _y = self.layers_label.y+ly
        if (x > _x and x < _x + self.layers_label.content_width and
                y > _y and y < _y + self.layers_label.content_height):
            self.active_tab.color = (200, 200, 200, 255)
            self.active_tab = self.layers_label
            self.active_tab.color = (255, 255, 255, 255)
            self.active_batch = self.layers_batch
            return True

        _x = self.tilesets_label.x+lx
        _y = self.tilesets_label.y+ly
        if (x > _x and x < _x + self.tilesets_label.content_width and
                y > _y and y < _y + self.tilesets_label.content_height):
            self.active_tab.color = (200, 200, 200, 255)
            self.active_tab = self.tilesets_label
            self.active_tab.color = (255, 255, 255, 255)
            self.active_batch = self.tilesets_batch
            return True

        sx = self.bg.x + lx
        sy = self.bg.y + ly
        if x < sx or x > sx + self.bg.width: return False
        if y < sy or y > sy + self.bg.height: return False

        #self._dragging = True
        return True

    _dragging = False
    def on_mouse_press(self, x, y, buttons, modifiers):
        lx, ly = self.position
        _x = self.bg.x+lx
        _y = self.bg.y+ly
        if (x > _x and x < _x + self.bg.width and
                y > _y and y < _y + self.bg.height):
            self._drag_start = (x, y)
        else:
            self._drag_start = None
        self._dragging = False

    def draw(self):
        self.transform()
        self.active_batch.draw()
        #self.tilesets_batch.draw()

        if self.active_batch is self.tiles_batch:
            glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT)
            glEnable(GL_BLEND)
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
            glColor4f(1, 1, 1, .3)
            x, y = self.highlight
            glRectf(x, y, x+self.TILE_SIZE, y+self.TILE_SIZE)
            glPopAttrib()

class EditorScene(cocos.scene.Scene):

    def __init__(self, edit_level_xml):
        super(EditorScene, self).__init__()

        self.manager = tiles.ScrollingManager()
        #if bg_level_xml:
            #level = tiles.load(bg_level_xml)[bg_level_id]
            #self.manager.append(level)
            #level.opacity = 100
            #self.add(level, z=0)

        level_to_edit = tiles.load(edit_level_xml)

        mz = 0
        for id, layer in level_to_edit.find(tiles.MapLayer):
            self.manager.add(layer, z=layer.origin_z)
            mz = max(layer.origin_z, mz)
        self.add(self.manager)

        s = TileSetLayer(level_to_edit)
        self.add(s, z=mz+2)

        e = TileEditorLayer(self.manager, level_to_edit, s, edit_level_xml)
        self.manager.add(e, z=mz+1)

        self.manager.set_focus(0, 0)

    def edit_complete(self, layer):
        pyglet.app.exit()

if __name__ == '__main__':
    import sys

    import pyglet
    import cocos
    from cocos import tiles

    from cocos.director import director

    try:
        edit_level_xml = sys.argv[1]
    except:
        print 'Usage: %s <level.xml>'%sys.argv[0]
        sys.exit(0)

    #director.init(width=700, height=440)
    #director.init(fullscreen=True)
    director.init(width=1024, height=768)
    director.show_FPS = True

    pyglet.gl.glClearColor(1, 1, 1, 1)

    director.run(EditorScene(edit_level_xml))

<commit_msg>fixes to bring this up to date<commit_after>'''Cocos tilemap editor!

Usage: editor.py <level.xml>

The level must contain at least one <rectmap> and one <tileset> (either
directly or via <requires>).

PALETTE:
- Click LMB in the palette to select the active tile.
- Use LMB dragging on the palette to drag it around the window.

MAP:
- Click LMB in the map to set the map to the active tile.
- Click RMB in the map to clear the map cell.
- Use the scroll-wheel to zoom in and out.
- Use LMB dragging to pan around the map. Alternatively use the arrow keys
  to pan around.

Hit "d" to turn some debugging information on (cell location, pixel location,
cell properties).

Hit control-s to save the map and quit.

Hit control-q, or escape, or the window close button to quit without saving.

'''

import pyglet
from pyglet.gl import *
import cocos
from cocos.director import director

class TileEditorLayer(cocos.layer.ScrollableLayer):
    is_event_handler = True

    def __init__(self, manager, level_to_edit, selector, filename):
        super(TileEditorLayer, self).__init__()
        self.manager = manager
        self.level_to_edit = level_to_edit
        self.filename = filename
        self.highlight = None
        self.selector = selector
        self.tileset = selector.tileset

    def on_key_press(self, key, modifier):
        if modifier & pyglet.window.key.MOD_ACCEL:
            if key == pyglet.window.key.S:
                self.level_to_edit.save_xml(self.filename)
                director.pop()
            elif key == pyglet.window.key.Q:
                director.pop()
        if key == pyglet.window.key.D:
            m = self.selector.map_layer
            m.set_debug(not m.debug)

    _desired_scale = 1
    def on_mouse_scroll(self, x, y, dx, dy):
        if dy < 0:
            if self._desired_scale < .2: return True
            self._desired_scale -= .1
        elif dy > 0:
            if self._desired_scale > 2: return True
            self._desired_scale += .1
        if dy:
            self.manager.do(cocos.actions.ScaleTo(self._desired_scale, .1))
            return True

    def on_text_motion(self, motion):
        fx, fy = self.manager.fx, self.manager.fy
        if motion == pyglet.window.key.MOTION_UP:
            self.manager.set_focus(fx, fy+64/self._desired_scale)
        elif motion == pyglet.window.key.MOTION_DOWN:
            self.manager.set_focus(fx, fy-64/self._desired_scale)
        elif motion == pyglet.window.key.MOTION_LEFT:
            self.manager.set_focus(fx-64/self._desired_scale, fy)
        elif motion == pyglet.window.key.MOTION_RIGHT:
            self.manager.set_focus(fx+64/self._desired_scale, fy)
        else:
            return False
        return True

    _dragging = False
    def on_mouse_press(self, x, y, buttons, modifiers):
        self._drag_start = (x, y)
        self._dragging = False

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if not buttons & pyglet.window.mouse.LEFT:
            return False
        if not self._dragging:
            _x, _y = self._drag_start
            if abs(x - _x) + abs(y - _y) < 6:
                return False
        self._dragging = True
        self.manager.set_focus(self.manager.fx-dx/self._desired_scale,
            self.manager.fy-dy/self._desired_scale)

    def on_mouse_release(self, x, y, buttons, modifiers):
        if self._dragging:
            self._dragging = False
            return False
        m = self.selector.map_layer

        # get the cell and cell coordinate
        x, y = self.manager.pixel_from_screen(x, y)
        cell = m.get_at_pixel(x, y)
        if not cell:
            # click not in map
            return

        # now add the cell
        if buttons & pyglet.window.mouse.LEFT:
            cell.tile = self.selector.tileset[self.selector.current.tile_id]
            self.selector.map_layer.set_dirty()
        elif buttons & pyglet.window.mouse.RIGHT:
            cell.tile = None
            self.selector.map_layer.set_dirty()
        return True

    def on_mouse_motion(self, x, y, dx, dy):
        m = self.selector.map_layer
        cell = m.get_at_pixel(*self.manager.pixel_from_screen(x, y))
        if not cell:
            self.highlight = None
            return True
        x = cell.x + m.origin_x
        y = cell.y + m.origin_y
        self.highlight = (x, y, x+m.tw, y+m.th)
        return True

    def draw(self):
        if self.highlight is None:
            return
        glPushMatrix()
        self.transform()
        glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glColor4f(1, 1, 0, .3)
        glRectf(*self.highlight)
        glPopAttrib()
        glPopMatrix()

class TileSetLayer(cocos.layer.Layer):
    is_event_handler = True

    TILE_SIZE = 32
    def __init__(self, level_to_edit):
        super(TileSetLayer, self).__init__()
        self.level_to_edit = level_to_edit
        self.map_layer = level_to_edit.find(cocos.tiles.MapLayer).next()[1]
        self.tileset = level_to_edit.findall(cocos.tiles.TileSet).next()[1]
        self.batch = pyglet.graphics.Batch()

        # labels
        ly = self.TILE_SIZE * 8 + 8
        self.tiles_label = pyglet.text.Label('Tiles', batch=self.batch, y=ly)
        self.active_tab = self.tiles_label
        w = self.tiles_label.content_width + 8
        h = self.tiles_label.content_height
        self.layers_label = pyglet.text.Label('Layers', batch=self.batch, y=ly,
            color=(200, 200, 200, 255))
        self.layers_label.x = w
        h = max(h, self.layers_label.content_height)
        w += self.layers_label.content_width + 8
        self.tilesets_label = pyglet.text.Label('Tilesets', batch=self.batch,
            y=ly, color=(200, 200, 200, 255))
        self.tilesets_label.x = w
        h = max(h, self.tilesets_label.content_height)
        w += self.tilesets_label.content_width

        self._width = (int(w) / self.TILE_SIZE) * self.TILE_SIZE + 8
        if int(w) % self.TILE_SIZE: self._width += self.TILE_SIZE
        self._height = h + 16 + self.TILE_SIZE * 8

        # set up the background
        bg = pyglet.image.SolidColorImagePattern((0, 0, 0, 200))
        bg = pyglet.image.create(self._width, self._height, pattern=bg)

        # set up the tiles
        self.active_batch = self.tiles_batch = pyglet.graphics.Batch()
        self.bg = pyglet.sprite.Sprite(bg, group=pyglet.graphics.OrderedGroup(0),
            batch=self.active_batch)
        self.tile_sprites = []
        x = y = 4
        for n, k in enumerate(self.tileset):
            s = pyglet.sprite.Sprite(self.tileset[k].image, y=y, x=x,
                batch=self.tiles_batch)
            if not n:
                self.current = s
            s.tile_id = k
            self.tile_sprites.append(s)
            s.scale = self.TILE_SIZE / float(s.width)
            if not n % 8:
                y = 4; x += self.TILE_SIZE
            else:
                y += self.TILE_SIZE

        # set up the layers buttons
        self.layers_batch = pyglet.graphics.Batch()
        self.layer_labels = []
        self.layer_visible = []
        y = 4
        for k,v in level_to_edit.find(cocos.tiles.MapLayer):
            l = pyglet.text.Label(k, batch=self.layers_batch, y=y,
                    color=(255,255,255,255))
            v.map_layer = l
            if v is self.map_layer:
                l.color = (255, 255, 200, 255)
            y += l.content_height + 2
            self.layer_labels.append(l)

        # set up the tilesets buttons
        self.tilesets_batch = pyglet.graphics.Batch()
        self.layer_labels = []
        y = 4
        for id, ts in self.level_to_edit.findall(cocos.tiles.TileSet):
            if id is None: id = '[no id]'
            l = pyglet.text.Label(id, batch=self.tilesets_batch,
                    color=(255,255,255,255), y=y, x=4)
            l._tileset = ts
            y += l.content_height + 2
            self.layer_labels.append(l)

        self.highlight = (4, 4)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if not buttons & pyglet.window.mouse.LEFT:
            return False
        if self._drag_start is None:
            return False
        if not self._dragging:
            _x, _y = self._drag_start
            if abs(x - _x) + abs(y - _y) < 6:
                return False
        self._dragging = True
        x, y = self.position
        self.position = (x+dx, y+dy)
        return True

    def on_mouse_release(self, x, y, button, modifiers):
        if self._dragging:
            self._dragging = False
            self._drag_start = None
            return True

        lx, ly = self.position

        if self.active_tab is self.tiles_label:
            for s in self.tile_sprites:
                sx = s.x + lx
                sy = s.y + ly
                if x < sx or x > sx + s.width: continue
                if y < sy or y > sy + s.height: continue
                self.current = s
                self.highlight = (s.x, s.y)
                return True
        #elif self.active_tab is self.layers_label:
            #XXX handle clicks in there...

        _x = self.tiles_label.x+lx
        _y = self.tiles_label.y+ly
        if (x > _x and x < _x + self.tiles_label.content_width and
                y > _y and y < _y + self.tiles_label.content_height):
            self.active_tab.color = (200, 200, 200, 255)
            self.active_tab = self.tiles_label
            self.active_tab.color = (255, 255, 255, 255)
            self.active_batch = self.tiles_batch
            return True

        _x = self.layers_label.x+lx
        _y = self.layers_label.y+ly
        if (x > _x and x < _x + self.layers_label.content_width and
                y > _y and y < _y + self.layers_label.content_height):
            self.active_tab.color = (200, 200, 200, 255)
            self.active_tab = self.layers_label
            self.active_tab.color = (255, 255, 255, 255)
            self.active_batch = self.layers_batch
            return True

        _x = self.tilesets_label.x+lx
        _y = self.tilesets_label.y+ly
        if (x > _x and x < _x + self.tilesets_label.content_width and
                y > _y and y < _y + self.tilesets_label.content_height):
            self.active_tab.color = (200, 200, 200, 255)
            self.active_tab = self.tilesets_label
            self.active_tab.color = (255, 255, 255, 255)
            self.active_batch = self.tilesets_batch
            return True

        sx = self.bg.x + lx
        sy = self.bg.y + ly
        if x < sx or x > sx + self.bg.width: return False
        if y < sy or y > sy + self.bg.height: return False

        #self._dragging = True
        return True

    _dragging = False
    def on_mouse_press(self, x, y, buttons, modifiers):
        lx, ly = self.position
        _x = self.bg.x+lx
        _y = self.bg.y+ly
        if (x > _x and x < _x + self.bg.width and
                y > _y and y < _y + self.bg.height):
            self._drag_start = (x, y)
        else:
            self._drag_start = None
        self._dragging = False

    def draw(self):
        self.transform()
        self.active_batch.draw()
        #self.tilesets_batch.draw()

        if self.active_batch is self.tiles_batch:
            glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT)
            glEnable(GL_BLEND)
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
            glColor4f(1, 1, 1, .3)
            x, y = self.highlight
            glRectf(x, y, x+self.TILE_SIZE, y+self.TILE_SIZE)
            glPopAttrib()

class EditorScene(cocos.scene.Scene):

    def __init__(self, edit_level_xml):
        super(EditorScene, self).__init__()

        self.manager = cocos.layer.ScrollingManager()
        #if bg_level_xml:
            #level = cocos.tiles.load(bg_level_xml)[bg_level_id]
            #self.manager.append(level)
            #level.opacity = 100
            #self.add(level, z=0)

        level_to_edit = cocos.tiles.load(edit_level_xml)

        mz = 0
        for id, layer in level_to_edit.find(cocos.tiles.MapLayer):
            self.manager.add(layer, z=layer.origin_z)
            mz = max(layer.origin_z, mz)
        self.add(self.manager)

        s = TileSetLayer(level_to_edit)
        self.add(s, z=mz+2)

        e = TileEditorLayer(self.manager, level_to_edit, s, edit_level_xml)
        self.manager.add(e, z=mz+1)

        self.manager.set_focus(0, 0)

    def edit_complete(self, layer):
        pyglet.app.exit()

if __name__ == '__main__':
    import sys

    try:
        edit_level_xml = sys.argv[1]
    except:
        print 'Usage: %s <level.xml>'%sys.argv[0]
        sys.exit(0)

    director.init(width=1024, height=768)
    #director.show_FPS = True

    pyglet.gl.glClearColor(1, 1, 1, 1)

    director.run(EditorScene(edit_level_xml))

<|endoftext|>


<commit_before>#!/usr/bin/env python

from glob import glob
import os, sys
import subprocess
import select

def run_all_fits():
    poller = select.poll()
    subprocs = {} # map stdout pipe's file descriptor to the Popen object
    ids = glob('*/')
    for id in ids:
        os.chdir(id)
        feedmes = glob('fit*galfit')
        # output starting models
        for f in feedmes:
            s = f.replace('fit', 'start', 1)
            sfn = s.replace('.galfit', '.fits')
            cmd = 'nice galfit -o1 -f %s %s > %s.out; if [ $? -eq 0 ]; then echo %s: success; else echo %s: failure; fi'%(sfn,f,s,s,s)
            subproc = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            subprocs[subproc.stdout.fileno()] = subproc
            poller.register(subproc.stdout, select.POLLHUP)
        # do proper fits
        for f in feedmes:
            cmd = 'nice galfit %s > %s.out; if [ $? -eq 0 ]; then echo %s: success; else echo %s: failure; fi'%(f,f,f,f)
            subproc = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            subprocs[subproc.stdout.fileno()] = subproc
            poller.register(subproc.stdout, select.POLLHUP)
        os.chdir('..')
    #loop that polls until completion
    while True:
        for fd, flags in poller.poll(5000): # never more than five seconds without a UI update
            done_proc = subprocs[fd]
            del subprocs[fd]
            poller.unregister(fd)
            print '\r\033[K'+done_proc.communicate()[0],
        print '.',
        sys.stdout.flush()
        #don't forget to break when all are done
        if len(subprocs) == 0:
            print '\r\033[KAll complete'
            break

if __name__ =='__main__':
    run_all_fits()
<commit_msg>Add code to convert feedmes to use sigma images<commit_after>#!/usr/bin/env python

from glob import glob
import os, sys
import subprocess
import select

def run_all_fits():
    poller = select.poll()
    subprocs = {} # map stdout pipe's file descriptor to the Popen object
    ids = glob('*/')
    for id in ids:
        os.chdir(id)
        feedmes = glob('fit*galfit')
        # output starting models
        for f in feedmes:
            s = f.replace('fit', 'start', 1)
            sfn = s.replace('.galfit', '.fits')
            cmd = 'nice galfit -o1 -f %s %s > %s.out; if [ $? -eq 0 ]; then echo %s: success; else echo %s: failure; fi'%(sfn,f,s,s,s)
            subproc = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            subprocs[subproc.stdout.fileno()] = subproc
            poller.register(subproc.stdout, select.POLLHUP)
        # do proper fits
        for f in feedmes:
            ## code to convert feedmes to use sigma image
            # text = file(f).readlines()
            # fout = file(f, 'w')
            # for l in text:
            #     ls = l.split()
            #     if len(ls) > 0 and ls[0] == 'A)':
            #         cline = l[:l.find('#')].replace('A)', 'C)').replace('.fits', '_sigma.fits')
            #     if len(ls) > 0 and ls[0] == 'C)':
            #         fout.write(cline+'\n')
            #     else:
            #         fout.write(l)
            # fout.close()
            cmd = 'nice galfit %s > %s.out; if [ $? -eq 0 ]; then echo %s: success; else echo %s: failure; fi'%(f,f,f,f)
            subproc = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            subprocs[subproc.stdout.fileno()] = subproc
            poller.register(subproc.stdout, select.POLLHUP)
        os.chdir('..')
    #loop that polls until completion
    while True:
        for fd, flags in poller.poll(5000): # never more than five seconds without a UI update
            done_proc = subprocs[fd]
            del subprocs[fd]
            poller.unregister(fd)
            print '\r\033[K'+done_proc.communicate()[0],
        print '.',
        sys.stdout.flush()
        #don't forget to break when all are done
        if len(subprocs) == 0:
            print '\r\033[KAll complete'
            break

if __name__ =='__main__':
    run_all_fits()
<|endoftext|>


<commit_before>import urllib
import argparse
import re
from bs4 import BeautifulSoup
import time
from numpy import array
DEFAULT_MSGS = "html/messages.htm"
DEFAULT_NAME = "Benjamin"
def main():
	parser = argparse.ArgumentParser()
	parser.add_argument('-f', '--file', dest='messages_file', default=DEFAULT_MSGS, type=str, help='Input the file you want to parse messages from')
	parser.add_argument('-n', '--name', dest='name', default=DEFAULT_NAME, type=str, help='Input your person of interest')

	values = parser.parse_args()
	print values.messages_file
	read_html(values.messages_file, values.name)

def read_html(filename, person):
	file_data = urllib.urlopen(filename).read()
	soup = BeautifulSoup(file_data, 'html.parser')

	for thread in soup.find_all('div', class_='thread'):
		msgs = thread.find_all('p')
		msgs = [m.get_text().encode("ascii", "ignore") for m in msgs]

		# holds the name and timestamp information
		msg_meta = thread.find_all('div', class_='message')

		# filter to only messages by our person of interest
		meta_filtered_idx = [idx for (idx,p) in enumerate(msg_meta)
			if (person in p.span.get_text().encode("ascii","ignore"))]
		msgs_filtered = list(array(msgs)[meta_filtered_idx])

		# also the timestamps mapping to the msgs
		just_timestamps = [str(ts.find('span', class_="meta").get_text())
			for ts in msg_meta if ts.find('span', class_="meta")]
		timestamps_filtered = list(array(just_timestamps)[meta_filtered_idx])
		print timestamps_filtered[1:10]
		break

if __name__ == '__main__':
	main()
<commit_msg>mapped all date times to the messages sent at that time<commit_after>import urllib
import argparse
import re
from bs4 import BeautifulSoup
import time
from numpy import array
from dateutil.parser import parse
from datetime import datetime

DEFAULT_MSGS = "html/messages.htm"
DEFAULT_NAME = "Benjamin"
def main():
	parser = argparse.ArgumentParser()
	parser.add_argument('-f', '--file', dest='messages_file', default=DEFAULT_MSGS, type=str, help='Input the file you want to parse messages from')
	parser.add_argument('-n', '--name', dest='name', default=DEFAULT_NAME, type=str, help='Input your person of interest')

	values = parser.parse_args()
	print values.messages_file
	read_html(values.messages_file, values.name)

def read_html(filename, person):
	file_data = urllib.urlopen(filename).read()
	soup = BeautifulSoup(file_data, 'html.parser')
	date_to_msgs = {}
	for thread in soup.find_all('div', class_='thread'):
		msgs = thread.find_all('p')
		msgs = [m.get_text().encode("ascii", "ignore") for m in msgs]

		# holds the name and timestamp information
		msg_meta = thread.find_all('div', class_='message')

		# filter to only messages by our person of interest
		meta_filtered_idx = [idx for (idx,p) in enumerate(msg_meta)
			if (person in p.span.get_text().encode("ascii","ignore"))]
		msgs_filtered = list(array(msgs)[meta_filtered_idx])

		# also the timestamps mapping to the msgs
		just_timestamps = [str(ts.find('span', class_="meta").get_text())
			for ts in msg_meta if ts.find('span', class_="meta")]
		timestamps_filtered = list(array(just_timestamps)[meta_filtered_idx])
		for idx,timestamp in enumerate(timestamps_filtered):
			ts = parse(timestamp) # date object
			if ts not in date_to_msgs:
				date_to_msgs[ts] = [msgs_filtered[idx]]
			else:
				date_to_msgs[ts].append(msgs_filtered[idx])

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