<commit_before># -*- coding: utf-8 -*-
"""
============================================================================
Base class for structure data atom (:mod:`sknano.core.atoms._atom`)
============================================================================

.. currentmodule:: sknano.core.atoms._atom

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals

__docformat__ = 'restructuredtext en'

from functools import total_ordering

import numbers

# from sknano.core import ClassSignature
from sknano.core.refdata import atomic_masses, atomic_mass_symbol_map, \
    atomic_numbers, atomic_number_symbol_map, element_symbols, element_names

__all__ = ['Atom']

@total_ordering
class Atom:
    """Base class for abstract representation of structure atom.

    Parameters
    ----------
    element : {str, int}, optional
        A string representation of the element symbol or an integer specifying
        an element atomic number :math:`\\boldsymbol{Z}`.

    """
    # _fields = ['element']

    def __init__(self, *args, element=None, mass=None, Z=None, **kwargs):
        args = list(args)

        if 'm' in kwargs and mass is None:
            mass = kwargs['m']
            del kwargs['m']

        if len(args) == 0 and (mass is not None or Z is not None):
            if mass is not None:
                args.append(mass)
            else:
                args.append(Z)

        if len(args) == 1:
            element = args.pop(0)

        self.mass = mass
        self.element = element
        self.fmtstr = "{element!r}, mass={mass!r}"

        super().__init__(*args, **kwargs)

    def __str__(self):
        """Return a nice string representation of `Atom`."""
        return repr(self)

    def __repr__(self):
        """Return canonical string representation of `Atom`."""
        return "{}({})".format(self.__class__.__name__,
                               self.fmtstr.format(**self.todict()))

    def __eq__(self, other):
        """Test equality of two `Atom` object instances."""
        if self is other:
            return True
        else:
            for attr in self.__dir__():
                if getattr(self, attr) != getattr(other, attr):
                    return False
            return True

    def __lt__(self, other):
        """Test if `self` is *less than* `other`."""
        return self.Z < other.Z

    def __dir__(self):
        return ['element', 'Z', 'mass']

    @property
    def fmtstr(self):
        return self._fmtstr

    @fmtstr.setter
    def fmtstr(self, value):
        self._fmtstr = value

    @property
    def Z(self):
        """Atomic number :math:`Z`.

        Returns
        -------
        int
            Atomic number :math:`Z`.
        """
        return self._Z

    @Z.setter
    def Z(self, value):
        """Set atomic number :math:`Z`.

        Parameters
        ----------
        value : int
            Atomic number :math:`Z`.

        """
        if not (isinstance(value, numbers.Real) and int(value) > 0):
            raise ValueError('Expected a real, positive integer.')
        try:
            Z = int(value)
            idx = Z - 1
            symbol = element_symbols[idx]
            mass = atomic_masses[symbol]
        except KeyError:
            print('unrecognized element number: {}'.format(value))
        else:
            self._Z = atomic_numbers[symbol]
            self._mass = mass
            self._symbol = symbol

    @property
    def element(self):
        """Element symbol.

        Returns
        -------
        str
            Symbol of chemical element.
        """
        return self._symbol

    @element.setter
    def element(self, value):
        """Set element symbol."""
        symbol = None
        if isinstance(value, numbers.Integral) or \
                (isinstance(value, numbers.Number) and
                 abs(value - int(value)) < 1e-6):
            try:
                Z = int(value)
                idx = Z - 1
                symbol = element_symbols[idx]
            except KeyError:
                print('unrecognized element number: {}'.format(value))

        if symbol is None:
            if isinstance(value, str):
                if value in element_symbols:
                    symbol = value
                elif value.capitalize() in element_names:
                    symbol = element_symbols[element_names.index(value)]
            elif isinstance(value, numbers.Number):
                if value in atomic_mass_symbol_map:
                    symbol = atomic_mass_symbol_map[value]
                elif int(value / 2) in atomic_number_symbol_map:
                    symbol = atomic_number_symbol_map[int(value / 2)]

        if symbol is None:
            symbol = 'X'

        try:
            self._Z = atomic_numbers[symbol]
            self._mass = atomic_masses[symbol]
        except KeyError:
            self._Z = 0
            if self.mass is None:
                self._mass = 0

        self._symbol = symbol

    @property
    def symbol(self):
        """Element symbol.

        Returns
        -------
        str
            Element symbol.
        """
        return self._symbol

    @property
    def mass(self):
        """Atomic mass :math:`m_a` in atomic mass units.

        Returns
        -------
        float
            Atomic mass :math:`m_a` in atomic mass units.
        """
        return self._mass

    @mass.setter
    def mass(self, value):
        self._mass = value

    @property
    def m(self):
        return self.mass

    @m.setter
    def m(self, value):
        self.mass = value

    def rezero(self, *args, **kwargs):
        assert not hasattr(super(), 'rezero')

    def rotate(self, **kwargs):
        assert not hasattr(super(), 'rotate')

    def translate(self, *args, **kwargs):
        assert not hasattr(super(), 'translate')

    def todict(self):
        """Return `dict` of `Atom` constructor parameters."""
        return dict(element=self.element, mass=self.mass)
<commit_msg>removing call to super class constructor<commit_after># -*- coding: utf-8 -*-
"""
============================================================================
Base class for structure data atom (:mod:`sknano.core.atoms._atom`)
============================================================================

.. currentmodule:: sknano.core.atoms._atom

"""
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals

__docformat__ = 'restructuredtext en'

from functools import total_ordering

import numbers

# from sknano.core import ClassSignature
from sknano.core.refdata import atomic_masses, atomic_mass_symbol_map, \
    atomic_numbers, atomic_number_symbol_map, element_symbols, element_names

__all__ = ['Atom']

@total_ordering
class Atom:
    """Base class for abstract representation of structure atom.

    Parameters
    ----------
    element : {str, int}, optional
        A string representation of the element symbol or an integer specifying
        an element atomic number :math:`\\boldsymbol{Z}`.

    """
    # _fields = ['element']

    def __init__(self, *args, element=None, mass=None, Z=None, **kwargs):
        args = list(args)

        if 'm' in kwargs and mass is None:
            mass = kwargs['m']
            del kwargs['m']

        if len(args) == 0 and (mass is not None or Z is not None):
            if mass is not None:
                args.append(mass)
            else:
                args.append(Z)

        if len(args) == 1:
            element = args.pop(0)

        self.mass = mass
        self.element = element
        self.fmtstr = "{element!r}, mass={mass!r}"

    def __str__(self):
        """Return a nice string representation of `Atom`."""
        return repr(self)

    def __repr__(self):
        """Return canonical string representation of `Atom`."""
        return "{}({})".format(self.__class__.__name__,
                               self.fmtstr.format(**self.todict()))

    def __eq__(self, other):
        """Test equality of two `Atom` object instances."""
        if self is other:
            return True
        else:
            for attr in self.__dir__():
                if getattr(self, attr) != getattr(other, attr):
                    return False
            return True

    def __lt__(self, other):
        """Test if `self` is *less than* `other`."""
        return self.Z < other.Z

    def __dir__(self):
        return ['element', 'Z', 'mass']

    @property
    def fmtstr(self):
        return self._fmtstr

    @fmtstr.setter
    def fmtstr(self, value):
        self._fmtstr = value

    @property
    def Z(self):
        """Atomic number :math:`Z`.

        Returns
        -------
        int
            Atomic number :math:`Z`.
        """
        return self._Z

    @Z.setter
    def Z(self, value):
        """Set atomic number :math:`Z`.

        Parameters
        ----------
        value : int
            Atomic number :math:`Z`.

        """
        if not (isinstance(value, numbers.Real) and int(value) > 0):
            raise ValueError('Expected a real, positive integer.')
        try:
            Z = int(value)
            idx = Z - 1
            symbol = element_symbols[idx]
            mass = atomic_masses[symbol]
        except KeyError:
            print('unrecognized element number: {}'.format(value))
        else:
            self._Z = atomic_numbers[symbol]
            self._mass = mass
            self._symbol = symbol

    @property
    def element(self):
        """Element symbol.

        Returns
        -------
        str
            Symbol of chemical element.
        """
        return self._symbol

    @element.setter
    def element(self, value):
        """Set element symbol."""
        symbol = None
        if isinstance(value, numbers.Integral) or \
                (isinstance(value, numbers.Number) and
                 abs(value - int(value)) < 1e-6):
            try:
                Z = int(value)
                idx = Z - 1
                symbol = element_symbols[idx]
            except KeyError:
                print('unrecognized element number: {}'.format(value))

        if symbol is None:
            if isinstance(value, str):
                if value in element_symbols:
                    symbol = value
                elif value.capitalize() in element_names:
                    symbol = element_symbols[element_names.index(value)]
            elif isinstance(value, numbers.Number):
                if value in atomic_mass_symbol_map:
                    symbol = atomic_mass_symbol_map[value]
                elif int(value / 2) in atomic_number_symbol_map:
                    symbol = atomic_number_symbol_map[int(value / 2)]

        if symbol is None:
            symbol = 'X'

        try:
            self._Z = atomic_numbers[symbol]
            self._mass = atomic_masses[symbol]
        except KeyError:
            self._Z = 0
            if self.mass is None:
                self._mass = 0

        self._symbol = symbol

    @property
    def symbol(self):
        """Element symbol.

        Returns
        -------
        str
            Element symbol.
        """
        return self._symbol

    @property
    def mass(self):
        """Atomic mass :math:`m_a` in atomic mass units.

        Returns
        -------
        float
            Atomic mass :math:`m_a` in atomic mass units.
        """
        return self._mass

    @mass.setter
    def mass(self, value):
        self._mass = value

    @property
    def m(self):
        return self.mass

    @m.setter
    def m(self, value):
        self.mass = value

    def rezero(self, *args, **kwargs):
        assert not hasattr(super(), 'rezero')

    def rotate(self, **kwargs):
        assert not hasattr(super(), 'rotate')

    def translate(self, *args, **kwargs):
        assert not hasattr(super(), 'translate')

    def todict(self):
        """Return `dict` of `Atom` constructor parameters."""
        return dict(element=self.element, mass=self.mass)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""
tarbell.cli
~~~~~~~~~

This module provides the CLI interface to tarbell.
"""

import os
import sys
from subprocess import call

from clint import args
from clint.arguments import Args
from clint.textui import colored, puts

from legit.cli import cmd_switch, cmd_branches, cmd_sprout

import jinja2
import codecs
import mimetypes

import tempfile
import shutil

from apiclient import errors
from apiclient.http import MediaFileUpload as _MediaFileUpload
from oauth2client.clientsecrets import InvalidClientSecretsError

from .app import TarbellSite
from .oauth import get_drive_api

__version__ = '0.9'

def list_get(l, idx, default=None):
    """Get from a list with an optional default value."""
    try:
        if l[idx]:
            return l[idx]
        else:
            return default
    except IndexError:
        return default

def black(s):
    """Black text."""
    #if settings.allow_black_foreground:
        #return colored.black(s)
    #else:
    return s.encode('utf-8')

class EnsureSite():
    """Context manager to ensure the user is in a Tarbell site environment."""
    def __init__(self, reset=False):
        self.reset = reset

    def __enter__(self):
        return self.ensure_site()

    def __exit__(self, type, value, traceback):
        pass

    def ensure_site(self, path=None):
        if not path:
            path = os.getcwd()

        if path is "/":
            show_error(("The current directory is not part of a Tarbell "
                        "project"))
            sys.exit(1)

        if not os.path.exists(os.path.join(path, '.tarbell')):
            path = os.path.realpath(os.path.join(path, '..'))
            return self.ensure_site(path)
        else:
            os.chdir(path)
            self.ensure_secrets(path)
            return path

    def ensure_secrets(self, path):
        try:
            get_drive_api(path, self.reset)
        except InvalidClientSecretsError:
            show_error(("\nYou don't have the `{0}` file necessary to work "
                        "with Google spreadsheets. Go to {1} to create an "
                        "app and generate an API client authentication file."
                        .format(colored.red("client_secrets.json"),
                                colored.yellow("https://code.google.com/apis/console/"))
                        ))
            sys.exit(1)

# Alias to lowercase
ensure_site = EnsureSite

# --------
# Dispatch
# --------
def main():
    """Primary Tarbell command dispatch."""

    command = Command.lookup(args.get(0))

    if len(args) == 0 or args.contains(('-h', '--help', 'help')):
        display_info()
        sys.exit(1)

    elif args.contains(('-v', '--version')):
        display_version()
        sys.exit(1)

    elif command:
        arg = args.get(0)
        args.remove(arg)

        reset = False
        if args.contains('--reset-creds'):
            reset = True
            args.remove('--reset-creds')

        with ensure_site(reset) as path:
            command.__call__(args, path)

        sys.exit()

    else:
        show_error(colored.red('Error! Unknown command `{0}`.\n'
                               .format(args.get(0))))
        display_info()
        sys.exit(1)

def split_sentences(s):
    """Split sentences for formatting."""
    sentences = []
    for index, sentence in enumerate(s.split('. ')):
        pad = ''
        if index > 0:
            pad = ' ' * 39
        if sentence.endswith('.'):
            sentence = sentence[:-1]
        sentences.append('%s %s.' % (pad, sentence.strip()))
    return "\n".join(sentences)

def display_info():
    """Displays Tarbell info."""

    puts('{0}\n'.format(
        black('Tarbell: Simple web publishing'),
    ))

    puts('Usage: {0}\n'.format(colored.cyan('tarbell <command>')))
    puts('Commands:\n')
    for command in Command.all_commands():
        usage = command.usage or command.name
        help = command.help or ''
        puts('{0:48} {1}\n'.format(
                colored.green(usage),
                split_sentences(help)))

    puts('\nOptions\n')
    puts('{0:48} {1}'.format(
        colored.green("--reset-creds"),
        'Reset Google Drive OAuth2 credentials'
    ))

    puts('\n{0}'.format(
        black(u'A Chicago Tribune News Applications project')
    ))

def display_version():
    """Displays Legit version/release."""

    puts('{0} v{1}'.format(
        colored.yellow('Tarbell'),
        __version__
    ))

def show_error(msg):
    """Displays error message."""
    sys.stdout.flush()
    sys.stderr.write("{0}: {1}".format(colored.red("Error"), msg + '\n'))

def tarbell_generate(args, path):
    """Generate static files."""
    site = TarbellSite(path)
    output_root = list_get(args, 0, False)
    if not output_root:
        tempdir = tempfile.mkdtemp(prefix="{0}-".format(site.project.__name__))
        os.makedirs(os.path.join(tempdir, site.project.__name__))
        output_root = os.path.join(tempdir, site.project.__name__)
    else:
        tempdir = output_root
        output_root = os.path.join(tempdir, site.project.__name__)

    if args.contains('--context'):
        site.project.CONTEXT_SOURCE_FILE = args.value_after('--context')

    site.generate_static_site(output_root)
    puts("\nCreated site in {0}".format(output_root))
    return tempdir

def tarbell_list(args, path):
    """List tarbell projects."""
    cmd_branches(path)

def tarbell_publish(args, path):
    """Publish a site by calling s3cmd"""
    site = TarbellSite(path)
    bucket_name = list_get(args, 0, "staging")
    bucket_uri = site.project.S3_BUCKETS.get(bucket_name, False)

    try:
        if bucket_uri:
            puts("Deploying to {0} ({1})\n".format(
                colored.green(bucket_name), colored.green(bucket_uri)))
            tempdir = tarbell_generate([], path)
            projectdir = os.path.join(tempdir, site.project.__name__)
            call(['s3cmd', 'sync', '--acl-public', '--delete-removed',
                  projectdir, bucket_uri])
        else:
            show_error(("There's no bucket configuration called '{0}' "
                        "in config.py.\n".format(bucket_name)))
    except KeyboardInterrupt:
        show_error("ctrl-c pressed, bailing out!")
    finally:
        # Delete tempdir
        try:
            shutil.rmtree(tempdir)  # delete directory
            puts("\nDeleted {0}".format(tempdir))
        except OSError as exc:
            if exc.errno != 2:  # code 2 - no such file or directory
                raise  # re-raise exception
        except UnboundLocalError:
            pass

def tarbell_newproject(args, path):
    """Create new Tarbell project."""
    project = args.get(0)
    if not project:
        show_error("No project name specified")
        sys.exit(1)

    #cmd_sprout(Args(["master", project]))

    site = TarbellSite(path)
    key = _create_spreadsheet(project, path)
    context = site._get_context_from_gdoc(key)
    context['spreadsheet_key'] = key
    _copy_project_files(project, path, context)

def _copy_project_files(project, path, context):
    proj_dir = os.path.join(path, project)
    try:
        os.mkdir(proj_dir)
    except OSError, e:
        if e.errno == 17:
            print ("ABORTING: Directory %s "
                   "already exists.") % proj_dir
        else:
            print "ABORTING: OSError %s" % e
        return

    # Get and walk project template
    loader = jinja2.FileSystemLoader(os.path.join(path, '_project_template'))
    env = jinja2.Environment(loader=loader)

    for root, dirs, files in os.walk(os.path.join(path, '_project_template')):
        for filename in files:
            # Strip out full filesystem paths
            dirname = root.replace(path, "")\
                          .replace("_project_template", "")

            relpath = "{0}/{1}".format(dirname, filename)
            if relpath.startswith("/"):
                relpath = relpath[1:]

            filepath = os.path.join(root, filename)
            output_path = filepath.replace("_project_template", project)
            output_dir = os.path.dirname(output_path)

            if not os.path.exists(output_dir):
                os.makedirs(output_dir)

            mimetype, encoding = mimetypes.guess_type(filepath)

            puts("Writing {0}".format(colored.yellow(output_path)))
            if mimetype and mimetype.startswith("text/"):
                content = env.get_template(relpath).render(context)
                codecs.open(output_path, "w", encoding="utf-8").write(content)
            else:
                shutil.copy(filepath, output_path)

def _create_spreadsheet(project, path):
    puts("\nGenerating Google spreadsheet")
    email = raw_input((
        "What Google account should have access to this "
        "this spreadsheet? )Use a full email address, such as "
        "your.name@gmail.com or the Google account equivalent.) "))
    media_body = _MediaFileUpload(os.path.join(path,
                                  '_project_template/tarbell_template.xlsx'),
                                  mimetype='application/vnd.ms-excel')

    service = get_drive_api(path)
    body = {
        'title': '%s [Tarbell project]' % project,
        'description': '%s [Tarbell project]' % project,
        'mimeType': 'application/vnd.ms-excel',
    }
    try:
        newfile = service.files()\
            .insert(body=body, media_body=media_body, convert=True).execute()
        _add_user_to_file(newfile['id'], service, user_email=email)
        _add_user_to_file(newfile['id'], service, user_email='anyone',
                          perm_type='anyone', role='reader')
        puts(("Success! View the file at "
              "https://docs.google.com/spreadsheet/ccc?key={0}"
              .format(newfile['id'])))
        return newfile['id']
    except errors.HttpError, error:
        show_error('An error occurred: {0}'.format(error))
        sys.exit(1)

def _add_user_to_file(file_id, service, user_email,
                      perm_type='user', role='reader'):
    """
    Grants the given set of permissions for a given file_id. service is an
    already-credentialed Google Drive service instance.
    """
    new_permission = {
        'value': user_email,
        'type': perm_type,
        'role': role
    }
    try:
        service.permissions()\
            .insert(fileId=file_id, body=new_permission)\
            .execute()
    except errors.HttpError, error:
        print 'An error occurred: %s' % error

def tarbell_serve(args, path):
    """Serve the current Tarbell project."""
    address = list_get(args, 0, "").split(":")
    ip = list_get(address, 0, '127.0.0.1')
    port = list_get(address, 1, 5000)
    site = TarbellSite(path)
    site.app.run(ip, port=int(port))

def tarbell_switch(args, path):
    """Switch to a project"""
    cmd_switch(args)               # legit switch
    tarbell_serve(args[1:], path)  # serve 'em up!

def tarbell_unpublish(args, path):
    """Delete a project."""
    print "@todo unpublish"

class Command(object):
    COMMANDS = {}
    SHORT_MAP = {}

    @classmethod
    def register(klass, command):
        klass.COMMANDS[command.name] = command
        if command.short:
            for short in command.short:
                klass.SHORT_MAP[short] = command

    @classmethod
    def lookup(klass, name):
        if name in klass.SHORT_MAP:
            return klass.SHORT_MAP[name]
        if name in klass.COMMANDS:
            return klass.COMMANDS[name]
        else:
            return None

    @classmethod
    def all_commands(klass):
        return sorted(klass.COMMANDS.values(),
                      key=lambda cmd: cmd.name)

    def __init__(self, name=None, short=None, fn=None, usage=None, help=None):
        self.name = name
        self.short = short
        self.fn = fn
        self.usage = usage
        self.help = help

    def __call__(self, *args, **kw_args):
        return self.fn(*args, **kw_args)

def def_cmd(name=None, short=None, fn=None, usage=None, help=None):
    """Define a command."""
    command = Command(name=name, short=short, fn=fn, usage=usage, help=help)
    Command.register(command)

def_cmd(
    name='generate',
    fn=tarbell_generate,
    usage='generate <output dir (optional)>',
    help=('Generate static files for the current project. If no output '
          'directory is specified, create a temporary directory.'))

def_cmd(
    name='list',
    fn=tarbell_list,
    usage='list',
    help='List all projects.')

def_cmd(
    name='publish',
    fn=tarbell_publish,
    usage='publish <target (default: staging)>',
    help='Publish the current project to <target>.')

def_cmd(
    name='newproject',
    fn=tarbell_newproject,
    usage='newproject <project>',
    help='Create a new project named <project>')

def_cmd(
    name='serve',
    fn=tarbell_serve,
    usage='serve <address (optional)>',
    help=('Run a preview server (typically handled by `switch`). '
          'Supply an optional address for the preview server such as '
          '`127.0.0.2:8000`'))

def_cmd(
    name='switch',
    fn=tarbell_switch,
    usage='switch <project> <address (optional)>',
    help=('Switch to the project named <project> and start a preview server. '
          'Supply an optional address for the preview server such as '
          '`127.0.0.2:8000`'))

def_cmd(
    name='unpublish',
    fn=tarbell_unpublish,
    usage='unpublish <target (default: staging)>',
    help='Remove the current project from <target>.')
<commit_msg>fixed paranthesis<commit_after># -*- coding: utf-8 -*-

"""
tarbell.cli
~~~~~~~~~

This module provides the CLI interface to tarbell.
"""

import os
import sys
from subprocess import call

from clint import args
from clint.arguments import Args
from clint.textui import colored, puts

from legit.cli import cmd_switch, cmd_branches, cmd_sprout

import jinja2
import codecs
import mimetypes

import tempfile
import shutil

from apiclient import errors
from apiclient.http import MediaFileUpload as _MediaFileUpload
from oauth2client.clientsecrets import InvalidClientSecretsError

from .app import TarbellSite
from .oauth import get_drive_api

__version__ = '0.9'

def list_get(l, idx, default=None):
    """Get from a list with an optional default value."""
    try:
        if l[idx]:
            return l[idx]
        else:
            return default
    except IndexError:
        return default

def black(s):
    """Black text."""
    #if settings.allow_black_foreground:
        #return colored.black(s)
    #else:
    return s.encode('utf-8')

class EnsureSite():
    """Context manager to ensure the user is in a Tarbell site environment."""
    def __init__(self, reset=False):
        self.reset = reset

    def __enter__(self):
        return self.ensure_site()

    def __exit__(self, type, value, traceback):
        pass

    def ensure_site(self, path=None):
        if not path:
            path = os.getcwd()

        if path is "/":
            show_error(("The current directory is not part of a Tarbell "
                        "project"))
            sys.exit(1)

        if not os.path.exists(os.path.join(path, '.tarbell')):
            path = os.path.realpath(os.path.join(path, '..'))
            return self.ensure_site(path)
        else:
            os.chdir(path)
            self.ensure_secrets(path)
            return path

    def ensure_secrets(self, path):
        try:
            get_drive_api(path, self.reset)
        except InvalidClientSecretsError:
            show_error(("\nYou don't have the `{0}` file necessary to work "
                        "with Google spreadsheets. Go to {1} to create an "
                        "app and generate an API client authentication file."
                        .format(colored.red("client_secrets.json"),
                                colored.yellow("https://code.google.com/apis/console/"))
                        ))
            sys.exit(1)

# Alias to lowercase
ensure_site = EnsureSite

# --------
# Dispatch
# --------
def main():
    """Primary Tarbell command dispatch."""

    command = Command.lookup(args.get(0))

    if len(args) == 0 or args.contains(('-h', '--help', 'help')):
        display_info()
        sys.exit(1)

    elif args.contains(('-v', '--version')):
        display_version()
        sys.exit(1)

    elif command:
        arg = args.get(0)
        args.remove(arg)

        reset = False
        if args.contains('--reset-creds'):
            reset = True
            args.remove('--reset-creds')

        with ensure_site(reset) as path:
            command.__call__(args, path)

        sys.exit()

    else:
        show_error(colored.red('Error! Unknown command `{0}`.\n'
                               .format(args.get(0))))
        display_info()
        sys.exit(1)

def split_sentences(s):
    """Split sentences for formatting."""
    sentences = []
    for index, sentence in enumerate(s.split('. ')):
        pad = ''
        if index > 0:
            pad = ' ' * 39
        if sentence.endswith('.'):
            sentence = sentence[:-1]
        sentences.append('%s %s.' % (pad, sentence.strip()))
    return "\n".join(sentences)

def display_info():
    """Displays Tarbell info."""

    puts('{0}\n'.format(
        black('Tarbell: Simple web publishing'),
    ))

    puts('Usage: {0}\n'.format(colored.cyan('tarbell <command>')))
    puts('Commands:\n')
    for command in Command.all_commands():
        usage = command.usage or command.name
        help = command.help or ''
        puts('{0:48} {1}\n'.format(
                colored.green(usage),
                split_sentences(help)))

    puts('\nOptions\n')
    puts('{0:48} {1}'.format(
        colored.green("--reset-creds"),
        'Reset Google Drive OAuth2 credentials'
    ))

    puts('\n{0}'.format(
        black(u'A Chicago Tribune News Applications project')
    ))

def display_version():
    """Displays Legit version/release."""

    puts('{0} v{1}'.format(
        colored.yellow('Tarbell'),
        __version__
    ))

def show_error(msg):
    """Displays error message."""
    sys.stdout.flush()
    sys.stderr.write("{0}: {1}".format(colored.red("Error"), msg + '\n'))

def tarbell_generate(args, path):
    """Generate static files."""
    site = TarbellSite(path)
    output_root = list_get(args, 0, False)
    if not output_root:
        tempdir = tempfile.mkdtemp(prefix="{0}-".format(site.project.__name__))
        os.makedirs(os.path.join(tempdir, site.project.__name__))
        output_root = os.path.join(tempdir, site.project.__name__)
    else:
        tempdir = output_root
        output_root = os.path.join(tempdir, site.project.__name__)

    if args.contains('--context'):
        site.project.CONTEXT_SOURCE_FILE = args.value_after('--context')

    site.generate_static_site(output_root)
    puts("\nCreated site in {0}".format(output_root))
    return tempdir

def tarbell_list(args, path):
    """List tarbell projects."""
    cmd_branches(path)

def tarbell_publish(args, path):
    """Publish a site by calling s3cmd"""
    site = TarbellSite(path)
    bucket_name = list_get(args, 0, "staging")
    bucket_uri = site.project.S3_BUCKETS.get(bucket_name, False)

    try:
        if bucket_uri:
            puts("Deploying to {0} ({1})\n".format(
                colored.green(bucket_name), colored.green(bucket_uri)))
            tempdir = tarbell_generate([], path)
            projectdir = os.path.join(tempdir, site.project.__name__)
            call(['s3cmd', 'sync', '--acl-public', '--delete-removed',
                  projectdir, bucket_uri])
        else:
            show_error(("There's no bucket configuration called '{0}' "
                        "in config.py.\n".format(bucket_name)))
    except KeyboardInterrupt:
        show_error("ctrl-c pressed, bailing out!")
    finally:
        # Delete tempdir
        try:
            shutil.rmtree(tempdir)  # delete directory
            puts("\nDeleted {0}".format(tempdir))
        except OSError as exc:
            if exc.errno != 2:  # code 2 - no such file or directory
                raise  # re-raise exception
        except UnboundLocalError:
            pass

def tarbell_newproject(args, path):
    """Create new Tarbell project."""
    project = args.get(0)
    if not project:
        show_error("No project name specified")
        sys.exit(1)

    #cmd_sprout(Args(["master", project]))

    site = TarbellSite(path)
    key = _create_spreadsheet(project, path)
    context = site._get_context_from_gdoc(key)
    context['spreadsheet_key'] = key
    _copy_project_files(project, path, context)

def _copy_project_files(project, path, context):
    proj_dir = os.path.join(path, project)
    try:
        os.mkdir(proj_dir)
    except OSError, e:
        if e.errno == 17:
            print ("ABORTING: Directory %s "
                   "already exists.") % proj_dir
        else:
            print "ABORTING: OSError %s" % e
        return

    # Get and walk project template
    loader = jinja2.FileSystemLoader(os.path.join(path, '_project_template'))
    env = jinja2.Environment(loader=loader)

    for root, dirs, files in os.walk(os.path.join(path, '_project_template')):
        for filename in files:
            # Strip out full filesystem paths
            dirname = root.replace(path, "")\
                          .replace("_project_template", "")

            relpath = "{0}/{1}".format(dirname, filename)
            if relpath.startswith("/"):
                relpath = relpath[1:]

            filepath = os.path.join(root, filename)
            output_path = filepath.replace("_project_template", project)
            output_dir = os.path.dirname(output_path)

            if not os.path.exists(output_dir):
                os.makedirs(output_dir)

            mimetype, encoding = mimetypes.guess_type(filepath)

            puts("Writing {0}".format(colored.yellow(output_path)))
            if mimetype and mimetype.startswith("text/"):
                content = env.get_template(relpath).render(context)
                codecs.open(output_path, "w", encoding="utf-8").write(content)
            else:
                shutil.copy(filepath, output_path)

def _create_spreadsheet(project, path):
    puts("\nGenerating Google spreadsheet")
    email = raw_input((
        "What Google account should have access to this "
        "this spreadsheet? (Use a full email address, such as "
        "your.name@gmail.com or the Google account equivalent.) "))
    media_body = _MediaFileUpload(os.path.join(path,
                                  '_project_template/tarbell_template.xlsx'),
                                  mimetype='application/vnd.ms-excel')

    service = get_drive_api(path)
    body = {
        'title': '%s [Tarbell project]' % project,
        'description': '%s [Tarbell project]' % project,
        'mimeType': 'application/vnd.ms-excel',
    }
    try:
        newfile = service.files()\
            .insert(body=body, media_body=media_body, convert=True).execute()
        _add_user_to_file(newfile['id'], service, user_email=email)
        _add_user_to_file(newfile['id'], service, user_email='anyone',
                          perm_type='anyone', role='reader')
        puts(("Success! View the file at "
              "https://docs.google.com/spreadsheet/ccc?key={0}"
              .format(newfile['id'])))
        return newfile['id']
    except errors.HttpError, error:
        show_error('An error occurred: {0}'.format(error))
        sys.exit(1)

def _add_user_to_file(file_id, service, user_email,
                      perm_type='user', role='reader'):
    """
    Grants the given set of permissions for a given file_id. service is an
    already-credentialed Google Drive service instance.
    """
    new_permission = {
        'value': user_email,
        'type': perm_type,
        'role': role
    }
    try:
        service.permissions()\
            .insert(fileId=file_id, body=new_permission)\
            .execute()
    except errors.HttpError, error:
        print 'An error occurred: %s' % error

def tarbell_serve(args, path):
    """Serve the current Tarbell project."""
    address = list_get(args, 0, "").split(":")
    ip = list_get(address, 0, '127.0.0.1')
    port = list_get(address, 1, 5000)
    site = TarbellSite(path)
    site.app.run(ip, port=int(port))

def tarbell_switch(args, path):
    """Switch to a project"""
    cmd_switch(args)               # legit switch
    tarbell_serve(args[1:], path)  # serve 'em up!

def tarbell_unpublish(args, path):
    """Delete a project."""
    print "@todo unpublish"

class Command(object):
    COMMANDS = {}
    SHORT_MAP = {}

    @classmethod
    def register(klass, command):
        klass.COMMANDS[command.name] = command
        if command.short:
            for short in command.short:
                klass.SHORT_MAP[short] = command

    @classmethod
    def lookup(klass, name):
        if name in klass.SHORT_MAP:
            return klass.SHORT_MAP[name]
        if name in klass.COMMANDS:
            return klass.COMMANDS[name]
        else:
            return None

    @classmethod
    def all_commands(klass):
        return sorted(klass.COMMANDS.values(),
                      key=lambda cmd: cmd.name)

    def __init__(self, name=None, short=None, fn=None, usage=None, help=None):
        self.name = name
        self.short = short
        self.fn = fn
        self.usage = usage
        self.help = help

    def __call__(self, *args, **kw_args):
        return self.fn(*args, **kw_args)

def def_cmd(name=None, short=None, fn=None, usage=None, help=None):
    """Define a command."""
    command = Command(name=name, short=short, fn=fn, usage=usage, help=help)
    Command.register(command)

def_cmd(
    name='generate',
    fn=tarbell_generate,
    usage='generate <output dir (optional)>',
    help=('Generate static files for the current project. If no output '
          'directory is specified, create a temporary directory.'))

def_cmd(
    name='list',
    fn=tarbell_list,
    usage='list',
    help='List all projects.')

def_cmd(
    name='publish',
    fn=tarbell_publish,
    usage='publish <target (default: staging)>',
    help='Publish the current project to <target>.')

def_cmd(
    name='newproject',
    fn=tarbell_newproject,
    usage='newproject <project>',
    help='Create a new project named <project>')

def_cmd(
    name='serve',
    fn=tarbell_serve,
    usage='serve <address (optional)>',
    help=('Run a preview server (typically handled by `switch`). '
          'Supply an optional address for the preview server such as '
          '`127.0.0.2:8000`'))

def_cmd(
    name='switch',
    fn=tarbell_switch,
    usage='switch <project> <address (optional)>',
    help=('Switch to the project named <project> and start a preview server. '
          'Supply an optional address for the preview server such as '
          '`127.0.0.2:8000`'))

def_cmd(
    name='unpublish',
    fn=tarbell_unpublish,
    usage='unpublish <target (default: staging)>',
    help='Remove the current project from <target>.')
<|endoftext|>


<commit_before>import smtplib
import pystache
import os
from email.mime.text import MIMEText
from werkzeug.utils import secure_filename

from KerbalStuff.database import db
from KerbalStuff.objects import User
from KerbalStuff.config import _cfg, _cfgi

def send_confirmation(user):
    smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port"))
    smtp.login(_cfg("smtp-user"), _cfg("smtp-password"))
    with open("emails/confirm-account") as f:
        message = MIMEText(pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.confirmation }))
    message['Subject'] = "Welcome to Kerbal Stuff!"
    message['From'] = "support@kerbalstuff.com"
    message['To'] = user.email
    smtp.sendmail("support@kerbalstuff.com", [ user.email ], message.as_string())
    smtp.quit()

def send_update_notification(mod):
    followers = [u.email for u in mod.followers]
    changelog = mod.versions[-1].changelog
    if changelog:
        changelog = '\n'.join(['    ' + l for l in changelog.split('\n')])

    for follower in followers:
        smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port"))
        smtp.login(_cfg("smtp-user"), _cfg("smtp-password"))
        with open("emails/mod-updated") as f:
            message = MIMEText(pystache.render(f.read(),
                {
                    'mod': mod,
                    'domain': _cfg("domain"),
                    'latest': mod.versions[-1],
                    'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64],
                    'changelog': changelog
                }))
        message['Subject'] = mod.user.username + " has just updated " + mod.name + "!"
        message['From'] = "support@kerbalstuff.com"
        message['To'] = follower
        smtp.sendmail("support@kerbalstuff.com", [ follower ], message.as_string())
        smtp.quit()
<commit_msg>Prioritize registration emails over update notices<commit_after>import smtplib
import pystache
import os
from email.mime.text import MIMEText
from werkzeug.utils import secure_filename

from KerbalStuff.database import db
from KerbalStuff.objects import User
from KerbalStuff.config import _cfg, _cfgi

def send_confirmation(user):
    smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port"))
    smtp.login(_cfg("smtp-user"), _cfg("smtp-password"))
    with open("emails/confirm-account") as f:
        message = MIMEText(pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.confirmation }))
    message['X-MC-Important'] = "true"
    message['Subject'] = "Welcome to Kerbal Stuff!"
    message['From'] = "support@kerbalstuff.com"
    message['To'] = user.email
    smtp.sendmail("support@kerbalstuff.com", [ user.email ], message.as_string())
    smtp.quit()

def send_update_notification(mod):
    followers = [u.email for u in mod.followers]
    changelog = mod.versions[-1].changelog
    if changelog:
        changelog = '\n'.join(['    ' + l for l in changelog.split('\n')])

    for follower in followers:
        smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port"))
        smtp.login(_cfg("smtp-user"), _cfg("smtp-password"))
        with open("emails/mod-updated") as f:
            message = MIMEText(pystache.render(f.read(),
                {
                    'mod': mod,
                    'domain': _cfg("domain"),
                    'latest': mod.versions[-1],
                    'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64],
                    'changelog': changelog
                }))
        message['Subject'] = mod.user.username + " has just updated " + mod.name + "!"
        message['From'] = "support@kerbalstuff.com"
        message['To'] = follower
        smtp.sendmail("support@kerbalstuff.com", [ follower ], message.as_string())
        smtp.quit()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Global configuration file for TG2-specific settings in SkyLines.

This file complements development/deployment.ini.

Please note that **all the argument values are strings**. If you want to
convert them into boolean, for example, you should use the
:func:`paste.deploy.converters.asbool` function, as in::

    from paste.deploy.converters import asbool
    setting = asbool(global_conf.get('the_setting'))

"""

from tg.configuration import AppConfig

import skylines
from skylines import model

# unused here, but needed by TurboGears2
from skylines.lib import app_globals, helpers

base_config = AppConfig()
base_config.renderers = []

base_config.package = skylines

#Enable json in expose
base_config.renderers.append('json')
#Set the default renderer
base_config.default_renderer = 'genshi'
base_config.renderers.append('genshi')
#base_config.renderers.append('mako')
# if you want raw speed and have installed chameleon.genshi
# you should try to use this renderer instead.
# warning: for the moment chameleon does not handle i18n translations
#base_config.renderers.append('chameleon_genshi')
base_config.use_dotted_templatenames = False

#Configure the base SQLALchemy Setup
base_config.use_sqlalchemy = True
base_config.model = skylines.model
base_config.DBSession = skylines.model.DBSession
# Configure the authentication backend

base_config.auth_backend = 'sqlalchemy'
base_config.sa_auth.dbsession = model.DBSession

# what is the class you want to use to search for users in the database
base_config.sa_auth.user_class = model.User
# what is the class you want to use to search for groups in the database
base_config.sa_auth.group_class = model.Group
# what is the class you want to use to search for permissions in the database
base_config.sa_auth.permission_class = model.Permission

# override this if you would like to provide a different who plugin for
# managing login and logout of your application
base_config.sa_auth.form_plugin = None
base_config.sa_auth.translations.user_name = 'email_address'

# override this if you are using a different charset for the login form
base_config.sa_auth.charset = 'utf-8'

# You may optionally define a page where you want users to be redirected to
# on login:
base_config.sa_auth.post_login_url = '/post_login'

# You may optionally define a page where you want users to be redirected to
# on logout:
base_config.sa_auth.post_logout_url = '/post_logout'
<commit_msg>config: Added "jinja" as additional template renderer option<commit_after># -*- coding: utf-8 -*-
"""
Global configuration file for TG2-specific settings in SkyLines.

This file complements development/deployment.ini.

Please note that **all the argument values are strings**. If you want to
convert them into boolean, for example, you should use the
:func:`paste.deploy.converters.asbool` function, as in::

    from paste.deploy.converters import asbool
    setting = asbool(global_conf.get('the_setting'))

"""

from tg.configuration import AppConfig

import skylines
from skylines import model

# unused here, but needed by TurboGears2
from skylines.lib import app_globals, helpers

base_config = AppConfig()
base_config.renderers = []

base_config.package = skylines

#Enable json in expose
base_config.renderers.append('json')
#Set the default renderer
base_config.default_renderer = 'genshi'
base_config.renderers.append('genshi')

base_config.renderers.append('jinja')
base_config.jinja_extensions = ['jinja2.ext.i18n', 'jinja2.ext.with_']

#base_config.renderers.append('mako')
# if you want raw speed and have installed chameleon.genshi
# you should try to use this renderer instead.
# warning: for the moment chameleon does not handle i18n translations
#base_config.renderers.append('chameleon_genshi')
base_config.use_dotted_templatenames = False

#Configure the base SQLALchemy Setup
base_config.use_sqlalchemy = True
base_config.model = skylines.model
base_config.DBSession = skylines.model.DBSession
# Configure the authentication backend

base_config.auth_backend = 'sqlalchemy'
base_config.sa_auth.dbsession = model.DBSession

# what is the class you want to use to search for users in the database
base_config.sa_auth.user_class = model.User
# what is the class you want to use to search for groups in the database
base_config.sa_auth.group_class = model.Group
# what is the class you want to use to search for permissions in the database
base_config.sa_auth.permission_class = model.Permission

# override this if you would like to provide a different who plugin for
# managing login and logout of your application
base_config.sa_auth.form_plugin = None
base_config.sa_auth.translations.user_name = 'email_address'

# override this if you are using a different charset for the login form
base_config.sa_auth.charset = 'utf-8'

# You may optionally define a page where you want users to be redirected to
# on login:
base_config.sa_auth.post_login_url = '/post_login'

# You may optionally define a page where you want users to be redirected to
# on logout:
base_config.sa_auth.post_logout_url = '/post_logout'
<|endoftext|>


<commit_before>import talib
from rqalpha import run
from rqalpha.api import *

# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
    context.s1 = "000001.XSHE"

    # 设置这个策略当中会用到的参数，在策略中可以随时调用，这个策略使用长短均线，我们在这里设定长线和短线的区间，在调试寻找最佳区间的时候只需要在这里进行数值改动
    context.SHORTPERIOD = 20
    context.LONGPERIOD = 120

# 你选择的证券的数据更新将会触发此段逻辑，例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
    # 开始编写你的主要的算法逻辑

    # bar_dict[order_book_id] 可以拿到某个证券的bar信息
    # context.portfolio 可以拿到现在的投资组合状态信息

    # 使用order_shares(id_or_ins, amount)方法进行落单

    # TODO: 开始编写你的算法吧！

    # 因为策略需要用到均线，所以需要读取历史数据
    prices = history_bars(context.s1, context.LONGPERIOD + 1, '1d', 'close')

    # 使用talib计算长短两根均线，均线以array的格式表达
    short_avg = talib.SMA(prices, context.SHORTPERIOD)
    long_avg = talib.SMA(prices, context.LONGPERIOD)

    plot("short avg", short_avg[-1])
    plot("long avg", long_avg[-1])

    # 计算现在portfolio中股票的仓位
    cur_position = context.portfolio.positions[context.s1].quantity
    # 计算现在portfolio中的现金可以购买多少股票
    shares = context.portfolio.cash / bar_dict[context.s1].close

    # 如果短均线从上往下跌破长均线，也就是在目前的bar短线平均值低于长线平均值，而上一个bar的短线平均值高于长线平均值
    if short_avg[-1] - long_avg[-1] < 0 and short_avg[-2] - long_avg[-2] > 0 and cur_position > 0:
        # 进行清仓
        order_target_value(context.s1, 0)

    # 如果短均线从下往上突破长均线，为入场信号
    if short_avg[-1] - long_avg[-1] > 0 and short_avg[-2] - long_avg[-2] < 0:
        # 满仓入股
        order_shares(context.s1, shares)

if __name__ == '__main__':
    from ialgotest.conf.generate_config import gen_conf

    run(gen_conf(__file__))
<commit_msg>Add data access example<commit_after>import talib
from rqalpha import run
from rqalpha.api import *

def init(context):
    context.s1 = "000001.XSHE"
    logger.info(context.run_info)
    logger.info('-- {} --'.format(context.universe))
    # logger.info(all_instruments(type='CS'))
    logger.info(instruments('000001.XSHE'))
    logger.info(instruments(['000001.XSHE', '000002.XSHE']))
    # Get stock list in one industry
    logger.info('Industry: {}'.format(industry('C34')))
    logger.info('Sector: {}'.format(sector('TelecommunicationServices')))
    logger.info('Concept: {}'.format(concept('民营医院', '国企改革')))
    logger.info('Devidend:\n{}'.format(get_dividend('000001.XSHE', start_date='20130104')))
    logger.info('Trade Dates: {}'.format(get_trading_dates(start_date='2016-05-01', end_date='20160505')))
    logger.info('Previous Trade Date: {}'.format(get_previous_trading_date(date='2016-05-02')))
    logger.info('Next Trade Date: {}'.format(get_next_trading_date(date='2016-05-02')))
    logger.info('Yield Curve: {}'.format(get_yield_curve('20130104')))

def handle_bar(context, bar_dict):
    # Get contract pool
    # logger.info(context.universe)

    # Use bar_dict[order_book_id] to get the bar info
    # logger.info(bar_dict[context.s1])

    # Use context.portfolio to get investment portfolio till now
    # logger.info(context.portfolio)
    # logger.info(context.portfolio.cash)
    # logger.info(context.portfolio.positions[context.s1].quantity)

    # Calculate current position in portfolio
    # cur_position = context.portfolio.positions[context.s1].quantity
    # Calculte how many stocks we can buy with all available cash
    # shares = context.portfolio.cash / bar_dict[context.s1].close
    # logger.info(shares)

    # Use history_bars to get history bars as list
    # logger.info(history_bars(context.s1, 5, '1d', 'close'))

    # Get current snapshot
    # logger.info(current_snapshot(context.s1))

    # 使用order_shares(id_or_ins, amount)方法进行落单

    pass

if __name__ == '__main__':
    from ialgotest.conf.generate_config import gen_conf

    run(gen_conf(__file__))
<|endoftext|>


<commit_before>from __future__ import print_function
from __future__ import absolute_import
import numpy as nm
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.base.testing import TestCommon
from sfepy import data_dir

filename_mesh = data_dir + '/meshes/3d/special/cube_cylinder.mesh'

fields = {
    'scalar_field' : ('real', 'scalar', 'Omega', 1),
    'vector_field' : ('real', 'vector', 'Omega', 1),
}

variables = {
    'U1': ('parameter field', 'vector_field', '(set-to-None)'),
    'U2': ('parameter field', 'vector_field', '(set-to-None)'),
    'P1': ('parameter field', 'scalar_field', '(set-to-None)'),
    'P2': ('parameter field', 'scalar_field', '(set-to-None)'),
    'V': ('parameter field', 'vector_field', '(set-to-None)'),
}

regions = {
    'Omega': 'all',
    'Omega1': 'cells of group 1',
    'Omega2': 'cells of group 2',
}

integrals = {
    'i': 2,
}

piezo_g =  nm.array([[0, 0, 0, 0, 10, 0],
                     [0, 0, 0, 0, 0, 10],
                     [-5, -5, 15, 0, 0, 0]])

materials = {
    'mat': ({
        'D': {
            'Omega1': stiffness_from_youngpoisson(3, 100, 0.3),
            'Omega2': stiffness_from_youngpoisson(3, 1, 0.49),
        },
        'K': {'Omega1': nm.eye(3), 'Omega2': nm.eye(3) * 1e-3},
        'c': {'Omega1': 1, 'Omega2': 1000},
        'g': {'Omega1': piezo_g * 1e2, 'Omega2': piezo_g},
    },),
}

equations = {}

test_terms = [
    ('d_sd_lin_elastic', 'dw_lin_elastic', 'mat.D', 'U1', 'U2'),
    ('d_sd_volume_dot', 'dw_volume_dot', None, 'U1', 'U2'),
    ('d_sd_diffusion', 'dw_diffusion', 'mat.K', 'P1', 'P2'),
    ('d_sd_div', 'dw_stokes', None, 'U1', 'P1'),
    ('d_sd_div_grad', 'dw_div_grad', 'mat.c', 'U1', 'U2'),
    ('d_sd_piezo_coupling', 'dw_piezo_coupling', 'mat.g', 'U1', 'P1'),
    ('d_sd_convect', 'de_convect', None, 'U1', 'U2'),
]

def modify_mesh(val, spbox, dv_mode, cp_pos):
    cpoints0 = spbox.get_control_points().copy()
    for pts, dir in dv_mode:
        for pt in pts:
            spbox.move_control_point(cp_pos[pt], nm.array(dir) * val)

    new_coors = spbox.evaluate()
    spbox.set_control_points(cpoints0)

    return new_coors

class Test(TestCommon):

    @staticmethod
    def from_conf(conf, options):
        from sfepy.discrete import Problem

        problem = Problem.from_conf(conf, init_equations=False)
        test = Test(problem=problem, conf=conf, options=options)
        return test

    def test_sensitivity(self):
        from sfepy.discrete import Variables
        from sfepy.mesh.splinebox import SplineBox

        tolerance = 1e-4
        ok = True
        pb = self.problem

        variables = Variables.from_conf(self.conf.variables, pb.fields)

        for var_name in variables.names:
            var = variables[var_name]
            n_dof = var.field.n_nod * var.field.shape[0]
            aux = nm.arange(n_dof, dtype=nm.float64)
            var.set_data(aux)

        mesh = pb.domain.mesh
        bbox = nm.array(mesh.get_bounding_box()).T
        spbox = SplineBox(bbox, mesh.coors)

        dvel_modes = [
            # expand inner cylinder, no volume change
            [([20, 21, 22, 23], (-1, -1, 0)),
             ([24, 25, 26, 27], (-1, 1, 0)),
             ([36, 37, 38, 39], (1, -1, 0)),
             ([40, 41, 42, 43], (1, 1, 0))],
            # volume change
            [(range(16, 32), (0.2, 0, 0)),
             (range(32, 48), (0.4, 0, 0)),
             (range(48, 52), (0.6, 0.2, 0.2)),
             (range(52, 56), (0.8, 0.2, 0.3)),
             (range(56, 60), (1.0, 0.2, 0.4)),
             (range(60, 64), (1.2, 0.2, 0.5))],
        ]

        r4 = range(4)
        cp_pos = {i*16 + j*4 + k: (i, j, k)
            for k in r4 for j in r4 for i in r4}

        # compute design velocities
        dvels = []
        for dv_mode in dvel_modes:
            dvel = 0
            for pts, dir in dv_mode:
                for pt in pts:
                    dvel += spbox.evaluate_derivative(cp_pos[pt], dir)
            dvels.append(dvel)

        for tname_sa, tname, mat, var1, var2 in test_terms:
            args = [] if mat is None else [mat]
            args += [var1, var2]
            term = '%s.i.Omega(%s)' % (tname, ', '.join(args))
            term_sa = '%s.i.Omega(%s)' % (tname_sa, ', '.join(args + ['V']))

            val = pb.evaluate(term, var_dict=variables.as_dict())
            self.report('%s: %s' % (tname, val))

            dt = 1e-6
            for ii, dvel in enumerate(dvels):
                variables['V'].set_data(dvel)
                val_sa = pb.evaluate(term_sa, var_dict=variables.as_dict())
                self.report('%s - mesh_velocity mode %d' % (tname_sa, ii))
                # mesh perturbation +
                new_coors = modify_mesh(dt/2., spbox, dvel_modes[ii], cp_pos)
                pb.set_mesh_coors(new_coors, update_fields=True)
                val1 = pb.evaluate(term, var_dict=variables.as_dict())

                # mesh perturbation -
                new_coors = modify_mesh(-dt/2., spbox, dvel_modes[ii], cp_pos)
                pb.set_mesh_coors(new_coors, update_fields=True)
                val2 = pb.evaluate(term, var_dict=variables.as_dict())

                val_fd = (val1 - val2) / dt
                err = nm.abs(val_sa - val_fd) / nm.linalg.norm(val_sa)
                self.report('sensitivity term:   %s' % val_sa)
                self.report('finite differences: %s' % val_fd)
                self.report('relative error: %s' % err)

                _ok = err < tolerance

                ok = ok and _ok

        return ok
<commit_msg>update tests to check SDLinearTractionTerm<commit_after>from __future__ import print_function
from __future__ import absolute_import
import numpy as nm
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.base.testing import TestCommon
from sfepy import data_dir

filename_mesh = data_dir + '/meshes/3d/special/cube_cylinder.mesh'

fields = {
    'scalar_field' : ('real', 'scalar', 'Omega', 1),
    'vector_field' : ('real', 'vector', 'Omega', 1),
}

variables = {
    'U1': ('parameter field', 'vector_field', '(set-to-None)'),
    'U2': ('parameter field', 'vector_field', '(set-to-None)'),
    'P1': ('parameter field', 'scalar_field', '(set-to-None)'),
    'P2': ('parameter field', 'scalar_field', '(set-to-None)'),
    'V': ('parameter field', 'vector_field', '(set-to-None)'),
}

regions = {
    'Omega': 'all',
    'Omega1': 'cells of group 1',
    'Omega2': 'cells of group 2',
    'Interface': ('r.Omega1 *v r.Omega2', 'facet', 'Omega1'),
}

integrals = {
    'i': 2,
}

piezo_g = nm.array([[0, 0, 0, 0, 10, 0],
                    [0, 0, 0, 0, 0, 10],
                    [-5, -5, 15, 0, 0, 0]])

materials = {
    'mat': ({
        'D': {
            'Omega1': stiffness_from_youngpoisson(3, 100, 0.3),
            'Omega2': stiffness_from_youngpoisson(3, 1, 0.49),
        },
        'K': {'Omega1': nm.eye(3), 'Omega2': nm.eye(3) * 1e-3},
        'c': {'Omega1': 1, 'Omega2': 1000},
        'g': {'Omega1': piezo_g * 1e2, 'Omega2': piezo_g},
        's': {
            'Omega1': nm.array([[1, 2, 3, 0, 0, 0]]).T,
            'Omega2': nm.array([[8, 4, 2, 0, 0, 0]]).T,
        }
    },),
}

equations = {}

test_terms = [
    ('d_sd_lin_elastic', 'dw_lin_elastic', 'Omega', 'mat.D', 'U1', 'U2'),
    ('d_sd_volume_dot', 'dw_volume_dot', 'Omega', None, 'U1', 'U2'),
    ('d_sd_diffusion', 'dw_diffusion', 'Omega', 'mat.K', 'P1', 'P2'),
    ('d_sd_div', 'dw_stokes', 'Omega', None, 'U1', 'P1'),
    ('d_sd_div_grad', 'dw_div_grad', 'Omega', 'mat.c', 'U1', 'U2'),
    ('d_sd_piezo_coupling', 'dw_piezo_coupling', 'Omega', 'mat.g', 'U1', 'P1'),
    ('d_sd_convect', 'de_convect', 'Omega', None, 'U1', 'U2'),
    ('d_sd_surface_ltr', 'dw_surface_ltr', 'Interface', 'mat.s', 'U1', None),
]

def modify_mesh(val, spbox, dv_mode, cp_pos):
    cpoints0 = spbox.get_control_points().copy()
    for pts, dir in dv_mode:
        for pt in pts:
            spbox.move_control_point(cp_pos[pt], nm.array(dir) * val)

    new_coors = spbox.evaluate()
    spbox.set_control_points(cpoints0)

    return new_coors

class Test(TestCommon):

    @staticmethod
    def from_conf(conf, options):
        from sfepy.discrete import Problem

        problem = Problem.from_conf(conf, init_equations=False)
        test = Test(problem=problem, conf=conf, options=options)
        return test

    def test_sensitivity(self):
        from sfepy.discrete import Variables
        from sfepy.mesh.splinebox import SplineBox

        tolerance = 1e-4
        ok = True
        pb = self.problem

        variables = Variables.from_conf(self.conf.variables, pb.fields)

        for var_name in variables.names:
            var = variables[var_name]
            n_dof = var.field.n_nod * var.field.shape[0]
            aux = nm.arange(n_dof, dtype=nm.float64)
            var.set_data(aux)

        mesh = pb.domain.mesh
        bbox = nm.array(mesh.get_bounding_box()).T
        spbox = SplineBox(bbox, mesh.coors)

        dvel_modes = [
            # expand inner cylinder, no volume change
            [([20, 21, 22, 23], (-1, -1, 0)),
             ([24, 25, 26, 27], (-1, 1, 0)),
             ([36, 37, 38, 39], (1, -1, 0)),
             ([40, 41, 42, 43], (1, 1, 0))],
            # volume change
            [(range(16, 32), (0.2, 0, 0)),
             (range(32, 48), (0.4, 0, 0)),
             (range(48, 52), (0.6, 0.2, 0.2)),
             (range(52, 56), (0.8, 0.2, 0.3)),
             (range(56, 60), (1.0, 0.2, 0.4)),
             (range(60, 64), (1.2, 0.2, 0.5))],
        ]

        r4 = range(4)
        cp_pos = {i*16 + j*4 + k: (i, j, k)
            for k in r4 for j in r4 for i in r4}

        # compute design velocities
        dvels = []
        for dv_mode in dvel_modes:
            dvel = 0
            for pts, dir in dv_mode:
                for pt in pts:
                    dvel += spbox.evaluate_derivative(cp_pos[pt], dir)
            dvels.append(dvel)

        for tname_sa, tname, rname, mat, var1, var2 in test_terms:
            args = [] if mat is None else [mat]
            args += [var1] if var2 is None else [var1, var2]
            term = '%s.i.%s(%s)' % (tname, rname, ', '.join(args))
            term_sa = '%s.i.%s(%s)' % (tname_sa, rname, ', '.join(args + ['V']))

            val = pb.evaluate(term, var_dict=variables.as_dict())
            self.report('%s: %s' % (tname, val))

            dt = 1e-6
            for ii, dvel in enumerate(dvels):
                val = pb.evaluate(term, var_dict=variables.as_dict())
                variables['V'].set_data(dvel)
                val_sa = pb.evaluate(term_sa, var_dict=variables.as_dict())
                self.report('%s - mesh_velocity mode %d' % (tname_sa, ii))
                # mesh perturbation +
                new_coors = modify_mesh(dt/2., spbox, dvel_modes[ii], cp_pos)
                pb.set_mesh_coors(new_coors, update_fields=True)
                val1 = pb.evaluate(term, var_dict=variables.as_dict())

                # mesh perturbation -
                new_coors = modify_mesh(-dt/2., spbox, dvel_modes[ii], cp_pos)
                pb.set_mesh_coors(new_coors, update_fields=True)
                val2 = pb.evaluate(term, var_dict=variables.as_dict())

                val_fd = (val1 - val2) / dt
                err = nm.abs(val_sa - val_fd) / nm.linalg.norm(val_sa)
                self.report('term:               %s' % val)
                self.report('sensitivity term:   %s' % val_sa)
                self.report('finite differences: %s' % val_fd)
                self.report('relative error:     %s' % err)

                _ok = err < tolerance

                ok = ok and _ok

        return ok
<|endoftext|>


<commit_before>from hypothesis import given
from ppb_vector import Vector2
from utils import vectors

def test_equal():
  test_vector_1 = Vector2(50, 800)
  test_vector_2 = Vector2(50, 800)

  assert test_vector_1 == test_vector_2

@given(x=vectors(), y=vectors())
def test_not_equal_equivalent(x: Vector2, y: Vector2):
  assert (x != y) == (not x == y)
<commit_msg>tests/equality: Replace test for == with an Hypothesis test<commit_after>from hypothesis import assume, given
from ppb_vector import Vector2
from utils import vectors

@given(x=vectors())
def test_equal_self(x: Vector2):
  assert x == x

@given(x=vectors())
def test_non_zero_equal(x: Vector2):
  assume(x != (0, 0))
  assert x != 1.1 * x

@given(x=vectors(), y=vectors())
def test_not_equal_equivalent(x: Vector2, y: Vector2):
  assert (x != y) == (not x == y)
<|endoftext|>


<commit_before>import logging
import re
from urlparse import urlparse

import flask
from flask import Flask, request, Response, redirect

from slack_overflow.google_search import search

app = Flask(__name__)

############
# Handlers #
############

@app.route('/overflow', methods=['post'])
def overflow():
    '''
    Example:
        /overflow python list comprehension
    '''
    question_regex = re.compile('^/questions/(\d+)/')

    def get_question_nid(match):
        """Returns the Question ID given a match from the URL"""
        if match is None:
            return None
        return int(match.groups()[0])

    # Get objects on the application context pushed on startup
    max_questions = flask._app_ctx_stack.max_questions
    so = flask._app_ctx_stack.so
    # Each page in the google search has ten entries
    pages = max_questions//10 + 1

    text = request.values.get('text')

    resp_qs = ['Stack Overflow Top Questions for "%s"\n' % text]
    # Perform google search
    #  Filter searches for only questions, and "-tagged" removes
    #   /questions/tagged entries for us, which should leave actual
    #   question links for most results
    sr = search(
        "site:stackoverflow.com/questions/* -tagged {}".format(text),
        pages=pages
    )
    # Extract each question nid from results
    so_qnids = []
    for result in sr:
        purl = urlparse(result.link)
        assert purl.netloc == 'stackoverflow.com', \
            "Non-StackOverflow result {}; search is broken!"\
            .format(result.link)
        qnid = get_question_nid(question_regex.match(purl.path))
        if qnid is not None:
            so_qnids.append(qnid)
        else:
            logging.warning("Found invalid URL in search: "
                            "{}".format(result.link))
    # Fetch Questions using SO API
    so_qs = so.questions(so_qnids)
    # Sort Questions by score
    so_qs = sorted(so_qs, key=lambda q: q.score, reverse=True)
    # Build Slack response for each question
    resp_qs.extend(map(get_response_string, so_qs[:max_questions]))

    return Response('\n'.join(resp_qs),
                    content_type='text/plain; charset=utf-8')

@app.route('/')
def hello():
    return redirect('https://github.com/karan/slack-overflow')

###########
# Helpers #
###########

def get_response_string(q):
    q_data = q.json
    check = ' :white_check_mark:' if q.json['is_answered'] else ''
    return "|%d|%s <%s|%s> (%d answers)" % (q_data['score'], check, q.url,
                                            q.title, q_data['answer_count'])
<commit_msg>Remove -tagged filter as it can filter legitimate queries with tagged; make assertion of domain lighter<commit_after>import logging
import re
from urlparse import urlparse

import flask
from flask import Flask, request, Response, redirect

from slack_overflow.google_search import search

app = Flask(__name__)

############
# Handlers #
############

@app.route('/overflow', methods=['post'])
def overflow():
    '''
    Example:
        /overflow python list comprehension
    '''
    question_regex = re.compile('^/questions/(\d+)/')

    def get_question_nid(match):
        """Returns the Question ID given a match from the URL"""
        if match is None:
            return None
        return int(match.groups()[0])

    # Get objects on the application context pushed on startup
    max_questions = flask._app_ctx_stack.max_questions
    so = flask._app_ctx_stack.so
    # Each page in the google search has ten entries
    pages = max_questions//10 + 1

    text = request.values.get('text')

    resp_qs = ['Stack Overflow Top Questions for "%s"\n' % text]
    # Perform google search
    sr = search(
        "site:stackoverflow.com/questions/* {}".format(text),
        pages=pages
    )
    # Extract each question nid from results
    so_qnids = []
    for result in sr:
        purl = urlparse(result.link)
        assert purl.netloc.endswith('stackoverflow.com'), \
            "Non-StackOverflow result {}; search is broken!"\
            .format(result.link)
        qnid = get_question_nid(question_regex.match(purl.path))
        if qnid is not None:
            so_qnids.append(qnid)
        else:
            logging.warning("Found invalid URL in search: "
                            "{}".format(result.link))
    # Fetch Questions using SO API
    so_qs = so.questions(so_qnids)
    # Sort Questions by score
    so_qs = sorted(so_qs, key=lambda q: q.score, reverse=True)
    # Build Slack response for each question
    resp_qs.extend(map(get_response_string, so_qs[:max_questions]))

    return Response('\n'.join(resp_qs),
                    content_type='text/plain; charset=utf-8')

@app.route('/')
def hello():
    return redirect('https://github.com/karan/slack-overflow')

###########
# Helpers #
###########

def get_response_string(q):
    q_data = q.json
    check = ' :white_check_mark:' if q.json['is_answered'] else ''
    return "|%d|%s <%s|%s> (%d answers)" % (q_data['score'], check, q.url,
                                            q.title, q_data['answer_count'])
<|endoftext|>


<commit_before>"""
Tests for functionality in the tornado_session module

"""
import mock
import unittest

# Out of order import to ensure psycopg2cffi is registered
from queries import pool, tornado_session

from psycopg2 import extras
from tornado import concurrent, gen, ioloop, testing

class ResultsTests(unittest.TestCase):

    def setUp(self):
        self.cursor = mock.Mock()
        self.fd = 10
        self.cleanup = mock.Mock()
        self.obj = tornado_session.Results(self.cursor, self.cleanup, self.fd)

    def test_cursor_is_assigned(self):
        self.assertEqual(self.obj.cursor, self.cursor)

    def test_fd_is_assigned(self):
        self.assertEqual(self.obj._fd, self.fd)

    def test_cleanup_is_assigned(self):
        self.assertEqual(self.obj._cleanup, self.cleanup)

    @gen.coroutine
    def test_free_invokes_cleanup(self):
        yield self.obj.free()
        self.cleanup.assert_called_once_with(self.cursor, self.fd)

class SessionInitTests(unittest.TestCase):

    def setUp(self):
        self.obj = tornado_session.TornadoSession()

    def test_creates_empty_callback_dict(self):
        self.assertDictEqual(self.obj._futures, {})

    def test_creates_empty_connections_dict(self):
        self.assertDictEqual(self.obj._connections, {})

    def test_sets_default_cursor_factory(self):
        self.assertEqual(self.obj._cursor_factory, extras.RealDictCursor)

    def test_sets_tornado_ioloop_instance(self):
        self.assertEqual(self.obj._ioloop, ioloop.IOLoop.instance())

    def test_sets_poolmananger_instance(self):
        self.assertEqual(self.obj._pool_manager, pool.PoolManager.instance())

    def test_sets_uri(self):
        self.assertEqual(self.obj._uri, tornado_session.session.DEFAULT_URI)

    def test_creates_pool_in_manager(self):
        self.assertIn(self.obj.pid, self.obj._pool_manager._pools)

    def test_connection_is_none(self):
        self.assertIsNone(self.obj.connection)

    def test_cursor_is_none(self):
        self.assertIsNone(self.obj.cursor)

class SessionConnectTests(testing.AsyncTestCase):

    def setUp(self):
        super(SessionConnectTests, self).setUp()
        self.conn = mock.Mock()
        self.conn.fileno = mock.Mock(return_value=10)
        self.obj = tornado_session.TornadoSession(io_loop=self.io_loop)

        def create_connection(future):
            future.set_result(self.conn)

        self.obj._create_connection = create_connection

    @testing.gen_test
    def test_connect_returns_new_connection(self):
        conn = yield self.obj._connect()
        self.assertEqual(conn, self.conn)

    @testing.gen_test
    def test_connect_returns_pooled_connection(self):
        conn = yield self.obj._connect()
        self.obj._pool_manager.add(self.obj.pid, conn)
        second_result = yield self.obj._connect()
        self.assertEqual(second_result, conn)

    @testing.gen_test
    def test_connect_gets_pooled_connection(self):
        conn = yield self.obj._connect()
        self.obj._pool_manager.add(self.obj.pid, conn)
        with mock.patch.object(self.obj._pool_manager, 'get') as get:
            with mock.patch.object(self.io_loop, 'add_handler'):
                yield self.obj._connect()
                get.assert_called_once_with(self.obj.pid, self.obj)

    @testing.gen_test
    def test_connect_pooled_connection_invokes_add_handler(self):
        conn = yield self.obj._connect()
        self.obj._pool_manager.add(self.obj.pid, conn)
        with mock.patch.object(self.obj._pool_manager, 'get') as get:
            get.return_value = self.conn
            with mock.patch.object(self.io_loop, 'add_handler') as add_handler:
                yield self.obj._connect()
                add_handler.assert_called_once_with(self.conn.fileno(),
                                                    self.obj._on_io_events,
                                                    ioloop.IOLoop.WRITE)

    def test_psycopg2_connect_invokes_psycopg2_connect(self):
        with mock.patch('psycopg2.connect') as connect:
            self.obj._psycopg2_connect({})
            connect.assert_called_once_with({'async': True})

    def test_on_io_events_returns_if_fd_not_present(self):
        with mock.patch.object(self.obj, '_poll_connection') as poll:
            self.obj._on_io_events(1337, ioloop.IOLoop.WRITE)
            poll.assert_not_called()

    def test_on_io_events_calls_poll_connection(self):
        with mock.patch.object(self.obj, '_poll_connection') as poll:
            self.obj._connections[1337] = True
            self.obj._on_io_events(1337, ioloop.IOLoop.WRITE)
            poll.assert_called_once_with(1337)

    def test_exec_cleanup_closes_cursor(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = mock.Mock()
                cursor = mock.Mock()
                cursor.close = mock.Mock()
                self.obj._exec_cleanup(cursor, 14)
                cursor.close.assert_called_once_with()

    def test_exec_cleanup_frees_connection(self):
        with mock.patch.object(self.obj._pool_manager, 'free') as pm_free:
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = conn = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                pm_free.assert_called_once_with(self.obj.pid, conn)

    def test_exec_cleanup_frees_connection(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler') as rh:
                self.obj._connections[14] = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                rh.assert_called_once_with(14)

    def test_exec_removes_connection(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                self.assertNotIn(14, self.obj._connections)

    def test_exec_removes_future(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = mock.Mock()
                self.obj._futures[14] = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                self.assertNotIn(14, self.obj._futures)

    def test_pool_manager_add_failures_are_propagated(self):
        futures = []

        def add_future(future, callback):
            futures.append((future, callback))

        obj = tornado_session.TornadoSession()
        obj._ioloop = mock.Mock()
        obj._ioloop.add_future = add_future

        future = concurrent.Future()
        with mock.patch.object(obj._pool_manager, 'add') as add_method:
            add_method.side_effect = pool.PoolFullError(mock.Mock())
            obj._create_connection(future)
            self.assertEqual(len(futures), 1)

            connected_future, callback = futures.pop()
            connected_future.set_result(True)
            callback(connected_future)
            self.assertIs(future.exception(), add_method.side_effect)

class SessionPublicMethodTests(testing.AsyncTestCase):

    @testing.gen_test
    def test_callproc_invokes_execute(self):
        with mock.patch('queries.tornado_session.TornadoSession._execute') as \
                _execute:
            future = concurrent.Future()
            future.set_result(True)
            _execute.return_value = future
            obj = tornado_session.TornadoSession(io_loop=self.io_loop)
            yield obj.callproc('foo', ['bar'])
            _execute.assert_called_once_with('callproc', 'foo', ['bar'])

    @testing.gen_test
    def test_query_invokes_execute(self):
        with mock.patch('queries.tornado_session.TornadoSession._execute') as \
                _execute:
            future = concurrent.Future()
            future.set_result(True)
            _execute.return_value = future
            obj = tornado_session.TornadoSession(io_loop=self.io_loop)
            yield obj.query('SELECT 1')
            _execute.assert_called_once_with('execute', 'SELECT 1', None)

    @testing.gen_test
    def test_query_error_key_error(self):
        obj = tornado_session.TornadoSession(io_loop=self.io_loop)
        with self.assertRaises(Exception):
            yield obj.query('SELECT * FROM foo WHERE bar=%(baz)s', {})

    @testing.gen_test
    def test_query_error_index_error(self):
        obj = tornado_session.TornadoSession(io_loop=self.io_loop)
        with self.assertRaises(Exception):
            yield obj.query('SELECT * FROM foo WHERE bar=%s', [])
<commit_msg>Fix broken test<commit_after>"""
Tests for functionality in the tornado_session module

"""
import mock
import unittest

# Out of order import to ensure psycopg2cffi is registered
from queries import pool, tornado_session

from psycopg2 import extras
from tornado import concurrent, gen, ioloop, testing

class ResultsTests(unittest.TestCase):

    def setUp(self):
        self.cursor = mock.Mock()
        self.fd = 10
        self.cleanup = mock.Mock()
        self.obj = tornado_session.Results(self.cursor, self.cleanup, self.fd)

    def test_cursor_is_assigned(self):
        self.assertEqual(self.obj.cursor, self.cursor)

    def test_fd_is_assigned(self):
        self.assertEqual(self.obj._fd, self.fd)

    def test_cleanup_is_assigned(self):
        self.assertEqual(self.obj._cleanup, self.cleanup)

    @gen.coroutine
    def test_free_invokes_cleanup(self):
        yield self.obj.free()
        self.cleanup.assert_called_once_with(self.cursor, self.fd)

class SessionInitTests(unittest.TestCase):

    def setUp(self):
        self.obj = tornado_session.TornadoSession()

    def test_creates_empty_callback_dict(self):
        self.assertDictEqual(self.obj._futures, {})

    def test_creates_empty_connections_dict(self):
        self.assertDictEqual(self.obj._connections, {})

    def test_sets_default_cursor_factory(self):
        self.assertEqual(self.obj._cursor_factory, extras.RealDictCursor)

    def test_sets_tornado_ioloop_instance(self):
        self.assertEqual(self.obj._ioloop, ioloop.IOLoop.instance())

    def test_sets_poolmananger_instance(self):
        self.assertEqual(self.obj._pool_manager, pool.PoolManager.instance())

    def test_sets_uri(self):
        self.assertEqual(self.obj._uri, tornado_session.session.DEFAULT_URI)

    def test_creates_pool_in_manager(self):
        self.assertIn(self.obj.pid, self.obj._pool_manager._pools)

    def test_connection_is_none(self):
        self.assertIsNone(self.obj.connection)

    def test_cursor_is_none(self):
        self.assertIsNone(self.obj.cursor)

class SessionConnectTests(testing.AsyncTestCase):

    def setUp(self):
        super(SessionConnectTests, self).setUp()
        self.conn = mock.Mock()
        self.conn.fileno = mock.Mock(return_value=10)
        self.obj = tornado_session.TornadoSession(io_loop=self.io_loop)

        def create_connection(future):
            future.set_result(self.conn)

        self.obj._create_connection = create_connection

    @testing.gen_test
    def test_connect_returns_new_connection(self):
        conn = yield self.obj._connect()
        self.assertEqual(conn, self.conn)

    @testing.gen_test
    def test_connect_returns_pooled_connection(self):
        conn = yield self.obj._connect()
        self.obj._pool_manager.add(self.obj.pid, conn)
        second_result = yield self.obj._connect()
        self.assertEqual(second_result, conn)

    @testing.gen_test
    def test_connect_gets_pooled_connection(self):
        conn = yield self.obj._connect()
        self.obj._pool_manager.add(self.obj.pid, conn)
        with mock.patch.object(self.obj._pool_manager, 'get') as get:
            with mock.patch.object(self.io_loop, 'add_handler'):
                yield self.obj._connect()
                get.assert_called_once_with(self.obj.pid, self.obj)

    @testing.gen_test
    def test_connect_pooled_connection_invokes_add_handler(self):
        conn = yield self.obj._connect()
        self.obj._pool_manager.add(self.obj.pid, conn)
        with mock.patch.object(self.obj._pool_manager, 'get') as get:
            get.return_value = self.conn
            with mock.patch.object(self.io_loop, 'add_handler') as add_handler:
                yield self.obj._connect()
                add_handler.assert_called_once_with(self.conn.fileno(),
                                                    self.obj._on_io_events,
                                                    ioloop.IOLoop.WRITE)

    def test_psycopg2_connect_invokes_psycopg2_connect(self):
        with mock.patch('psycopg2.connect') as connect:
            self.obj._psycopg2_connect({})
            connect.assert_called_once_with(**{'async': True})

    def test_on_io_events_returns_if_fd_not_present(self):
        with mock.patch.object(self.obj, '_poll_connection') as poll:
            self.obj._on_io_events(1337, ioloop.IOLoop.WRITE)
            poll.assert_not_called()

    def test_on_io_events_calls_poll_connection(self):
        with mock.patch.object(self.obj, '_poll_connection') as poll:
            self.obj._connections[1337] = True
            self.obj._on_io_events(1337, ioloop.IOLoop.WRITE)
            poll.assert_called_once_with(1337)

    def test_exec_cleanup_closes_cursor(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = mock.Mock()
                cursor = mock.Mock()
                cursor.close = mock.Mock()
                self.obj._exec_cleanup(cursor, 14)
                cursor.close.assert_called_once_with()

    def test_exec_cleanup_frees_connection(self):
        with mock.patch.object(self.obj._pool_manager, 'free') as pm_free:
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = conn = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                pm_free.assert_called_once_with(self.obj.pid, conn)

    def test_exec_cleanup_frees_connection(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler') as rh:
                self.obj._connections[14] = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                rh.assert_called_once_with(14)

    def test_exec_removes_connection(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                self.assertNotIn(14, self.obj._connections)

    def test_exec_removes_future(self):
        with mock.patch.object(self.obj._pool_manager, 'free'):
            with mock.patch.object(self.obj._ioloop, 'remove_handler'):
                self.obj._connections[14] = mock.Mock()
                self.obj._futures[14] = mock.Mock()
                self.obj._exec_cleanup(mock.Mock(), 14)
                self.assertNotIn(14, self.obj._futures)

    def test_pool_manager_add_failures_are_propagated(self):
        futures = []

        def add_future(future, callback):
            futures.append((future, callback))

        obj = tornado_session.TornadoSession()
        obj._ioloop = mock.Mock()
        obj._ioloop.add_future = add_future

        future = concurrent.Future()
        with mock.patch.object(obj._pool_manager, 'add') as add_method:
            add_method.side_effect = pool.PoolFullError(mock.Mock())
            obj._create_connection(future)
            self.assertEqual(len(futures), 1)

            connected_future, callback = futures.pop()
            connected_future.set_result(True)
            callback(connected_future)
            self.assertIs(future.exception(), add_method.side_effect)

class SessionPublicMethodTests(testing.AsyncTestCase):

    @testing.gen_test
    def test_callproc_invokes_execute(self):
        with mock.patch('queries.tornado_session.TornadoSession._execute') as \
                _execute:
            future = concurrent.Future()
            future.set_result(True)
            _execute.return_value = future
            obj = tornado_session.TornadoSession(io_loop=self.io_loop)
            yield obj.callproc('foo', ['bar'])
            _execute.assert_called_once_with('callproc', 'foo', ['bar'])

    @testing.gen_test
    def test_query_invokes_execute(self):
        with mock.patch('queries.tornado_session.TornadoSession._execute') as \
                _execute:
            future = concurrent.Future()
            future.set_result(True)
            _execute.return_value = future
            obj = tornado_session.TornadoSession(io_loop=self.io_loop)
            yield obj.query('SELECT 1')
            _execute.assert_called_once_with('execute', 'SELECT 1', None)

    @testing.gen_test
    def test_query_error_key_error(self):
        obj = tornado_session.TornadoSession(io_loop=self.io_loop)
        with self.assertRaises(Exception):
            yield obj.query('SELECT * FROM foo WHERE bar=%(baz)s', {})

    @testing.gen_test
    def test_query_error_index_error(self):
        obj = tornado_session.TornadoSession(io_loop=self.io_loop)
        with self.assertRaises(Exception):
            yield obj.query('SELECT * FROM foo WHERE bar=%s', [])
<|endoftext|>


<commit_before># coding=utf-8

from mongoengine import EmbeddedDocument, BinaryField, BooleanField,\
    EmbeddedDocumentField, FloatField, GenericEmbeddedDocumentField, IntField,\
    ListField, StringField
from mongoengine.errors import NotRegistered

from .common import MultipleDatabaseModelDocument

################################################################################
__all__ = ('Image',)

################################################################################
class StartupView(EmbeddedDocument):
    center = ListField(FloatField(), required=False)
    rotation = FloatField(required=False)
    zoom = IntField(required=False)

################################################################################
class Annotation(EmbeddedDocument):
    meta = {
        'abstract': True,
        'allow_inheritance': True,
        }

    display_name = StringField(required=False, db_field='displayname')
    color = StringField(required=False)
    points = ListField(ListField(IntField(), required=True), required=False)

class CircleAnnotation(Annotation):
    type = StringField(required=True, default='circle', choices=('circle',))

    radius = IntField(required=False)

class FreehandAnnotation(Annotation):
    type = StringField(required=True, default='freehand', choices=('freehand',))

    measure_type = IntField(required=False, db_field='measuretype')
    closed = IntField(required=False)
    special_type = StringField(required=False, choices=('rectangle',), db_field='specialtype')

class PointerAnnotation(Annotation):
    type = StringField(required=True, default='pointer', choices=('pointer',))

class LinearmeasureAnnotation(Annotation):
    type = StringField(required=True, default='linearmeasure', choices=('linearmeasure',))

class EmbeddedAnnotationField(GenericEmbeddedDocumentField):
    type_map = {
        'circle': CircleAnnotation,
        'freehand': FreehandAnnotation,
        'pointer': PointerAnnotation,
        'linearmeasure': LinearmeasureAnnotation,
    }

    def __init__(self, *args, **kwargs):
        super(EmbeddedAnnotationField, self).__init__(
            choices=tuple(self.type_map.itervalues()),
            *args, **kwargs)

    def to_python(self, value):
        try:
            value = super(EmbeddedAnnotationField, self).to_python(value)
        except KeyError:
            try:
                doc_cls = self.type_map[value['type']]
                value = doc_cls._from_son(value)
            except KeyError:
                raise NotRegistered()
        return value

class Bookmark(EmbeddedDocument):
    annotation = EmbeddedAnnotationField(required=False)
    center = ListField(IntField(), required=False)
    details = StringField(required=False)
    lens = FloatField(required=False)
    title = StringField(required=False)
    zoom = IntField(required=False)

################################################################################
class Image(MultipleDatabaseModelDocument):
    """
    The model Image record, any methods will go into a mixin
    """
    meta = {
        'collection': 'images',
        # 'allow_inheritance' : True
    }

    filename = StringField(required=False, #TODO: filename with respect to root_path
        verbose_name='Filename', help_text='The filename of uploaded image excluding path')

    label = StringField(required=False, #TODO: make unique
        verbose_name='Label', help_text='The human-readable label for the image')

    origin = ListField(FloatField(), required=False, default=lambda: [0.,0.,0.],
        verbose_name='Origin', help_text='x / y / z world coords (necessary to import NDPA annotations)')

    spacing = ListField(FloatField(), required=False, default=lambda: [1.,1.,1.],
        verbose_name='Spacing', help_text='x / y / z nanometers/pixel or "1.0" if unknown')

    dimensions = ListField(IntField(), required=True,
        verbose_name='Dimensions', help_text='x / y / z dimensions of non-padded region of base layer in pixels. z-dimension is 1 for non-stack images.')

    levels = IntField(required=False, default=0,
        verbose_name='Levels', help_text='Levels in multiresolution pyramid (specific to pyramid2 and pyrmid3 types)')

    components = IntField(required=False, default=3,
        verbose_name='Components', help_text='')

    # New fields

    coordinate_system = StringField(required=False, choices=('Pixel', 'Photo'), default='Pixel', db_field='CoordinateSystem',
        verbose_name='', help_text='')

    tile_size = IntField(required=False, default=256, db_field='TileSize',
        verbose_name='TileSize', help_text='dimensions of each square tile')

    bounds = ListField(IntField(), required=False, default=lambda: [0,0,0,0,0,0],
        verbose_name='', help_text='xMin / xMax / yMin / yMax nanometers or "Units" if unknown')

    extents = ListField(IntField(), required=False,
        verbose_name='Extents (deprecated)', help_text='int (x / y / z start / end pixel coords)')

    metadataready = BooleanField(required=False,
        verbose_name='', help_text='')

    name = StringField(required=False,
        verbose_name='', help_text='')

    thumb = BinaryField(required=False,
        verbose_name='', help_text='')

    type = StringField(required=False, choices=('stack',),
        verbose_name='', help_text='If this is not set, then assume pyramid2. "stack" is a simple array of images named 1.png, 2.png ...')

    copyright = StringField(required=False,
        verbose_name='', help_text='')

    # TODO: this should be an embedded document
    startup_view = EmbeddedDocumentField(StartupView, required=False,
        verbose_name='', help_text='')

    # TODO: this should be an embedded document
    bookmarks = ListField(EmbeddedDocumentField(Bookmark), required=False,
        verbose_name='', help_text='')

    # TODO: set '_cls' field on all documents in database

    def __unicode__(self):
        # TODO: make these fields required or have a better default representation
        return unicode((self.label or '') + (self.copyright or ''))
<commit_msg>Remove 'Image.extents' field<commit_after># coding=utf-8

from mongoengine import EmbeddedDocument, BinaryField, BooleanField,\
    EmbeddedDocumentField, FloatField, GenericEmbeddedDocumentField, IntField,\
    ListField, StringField
from mongoengine.errors import NotRegistered

from .common import MultipleDatabaseModelDocument

################################################################################
__all__ = ('Image',)

################################################################################
class StartupView(EmbeddedDocument):
    center = ListField(FloatField(), required=False)
    rotation = FloatField(required=False)
    zoom = IntField(required=False)

################################################################################
class Annotation(EmbeddedDocument):
    meta = {
        'abstract': True,
        'allow_inheritance': True,
        }

    display_name = StringField(required=False, db_field='displayname')
    color = StringField(required=False)
    points = ListField(ListField(IntField(), required=True), required=False)

class CircleAnnotation(Annotation):
    type = StringField(required=True, default='circle', choices=('circle',))

    radius = IntField(required=False)

class FreehandAnnotation(Annotation):
    type = StringField(required=True, default='freehand', choices=('freehand',))

    measure_type = IntField(required=False, db_field='measuretype')
    closed = IntField(required=False)
    special_type = StringField(required=False, choices=('rectangle',), db_field='specialtype')

class PointerAnnotation(Annotation):
    type = StringField(required=True, default='pointer', choices=('pointer',))

class LinearmeasureAnnotation(Annotation):
    type = StringField(required=True, default='linearmeasure', choices=('linearmeasure',))

class EmbeddedAnnotationField(GenericEmbeddedDocumentField):
    type_map = {
        'circle': CircleAnnotation,
        'freehand': FreehandAnnotation,
        'pointer': PointerAnnotation,
        'linearmeasure': LinearmeasureAnnotation,
    }

    def __init__(self, *args, **kwargs):
        super(EmbeddedAnnotationField, self).__init__(
            choices=tuple(self.type_map.itervalues()),
            *args, **kwargs)

    def to_python(self, value):
        try:
            value = super(EmbeddedAnnotationField, self).to_python(value)
        except KeyError:
            try:
                doc_cls = self.type_map[value['type']]
                value = doc_cls._from_son(value)
            except KeyError:
                raise NotRegistered()
        return value

class Bookmark(EmbeddedDocument):
    annotation = EmbeddedAnnotationField(required=False)
    center = ListField(IntField(), required=False)
    details = StringField(required=False)
    lens = FloatField(required=False)
    title = StringField(required=False)
    zoom = IntField(required=False)

################################################################################
class Image(MultipleDatabaseModelDocument):
    """
    The model Image record, any methods will go into a mixin
    """
    meta = {
        'collection': 'images',
        # 'allow_inheritance' : True
    }

    filename = StringField(required=False, #TODO: filename with respect to root_path
        verbose_name='Filename', help_text='The filename of uploaded image excluding path')

    label = StringField(required=False, #TODO: make unique
        verbose_name='Label', help_text='The human-readable label for the image')

    origin = ListField(FloatField(), required=False, default=lambda: [0.,0.,0.],
        verbose_name='Origin', help_text='x / y / z world coords (necessary to import NDPA annotations)')

    spacing = ListField(FloatField(), required=False, default=lambda: [1.,1.,1.],
        verbose_name='Spacing', help_text='x / y / z nanometers/pixel or "1.0" if unknown')

    dimensions = ListField(IntField(), required=True,
        verbose_name='Dimensions', help_text='x / y / z dimensions of non-padded region of base layer in pixels. z-dimension is 1 for non-stack images.')

    levels = IntField(required=False, default=0,
        verbose_name='Levels', help_text='Levels in multiresolution pyramid (specific to pyramid2 and pyrmid3 types)')

    components = IntField(required=False, default=3,
        verbose_name='Components', help_text='')

    # New fields

    coordinate_system = StringField(required=False, choices=('Pixel', 'Photo'), default='Pixel', db_field='CoordinateSystem',
        verbose_name='', help_text='')

    tile_size = IntField(required=False, default=256, db_field='TileSize',
        verbose_name='TileSize', help_text='dimensions of each square tile')

    bounds = ListField(IntField(), required=False, default=lambda: [0,0,0,0,0,0],
        verbose_name='', help_text='xMin / xMax / yMin / yMax nanometers or "Units" if unknown')

    metadataready = BooleanField(required=False,
        verbose_name='', help_text='')

    name = StringField(required=False,
        verbose_name='', help_text='')

    thumb = BinaryField(required=False,
        verbose_name='', help_text='')

    type = StringField(required=False, choices=('stack',),
        verbose_name='', help_text='If this is not set, then assume pyramid2. "stack" is a simple array of images named 1.png, 2.png ...')

    copyright = StringField(required=False,
        verbose_name='', help_text='')

    # TODO: this should be an embedded document
    startup_view = EmbeddedDocumentField(StartupView, required=False,
        verbose_name='', help_text='')

    # TODO: this should be an embedded document
    bookmarks = ListField(EmbeddedDocumentField(Bookmark), required=False,
        verbose_name='', help_text='')

    # TODO: set '_cls' field on all documents in database

    def __unicode__(self):
        # TODO: make these fields required or have a better default representation
        return unicode((self.label or '') + (self.copyright or ''))
<|endoftext|>