<commit_before># -*- coding: utf-8 -*-
from openerp import api, fields, models
from openerp.tools.translate import _
from openerp.exceptions import ValidationError

class CrmMakeSale(models.TransientModel):
    _name = "br.crm.make.sale"
    _inherit = "crm.make.sale"

    update_quotation = fields.Boolean('Update existing quotation')

    @api.multi
    def make_orderline(self):
        context = self.env.context
        case_id = context and context.get('active_ids', []) or []
        case_id = case_id and case_id[0] or False
        res = super(CrmMakeSale, self).makeOrder()
        if self.update_quotation:
            saleorder = self.env['sale.order'].search([
                ('origin', '=', _('Opportunity: %s') % str(case_id))])
            saleorder = saleorder and saleorder[0] or False
            if saleorder:
                res.update({'res_id': saleorder.id})
                if saleorder.order_line:
                    saleorder.order_line.unlink()

        order_id = res.get('res_id', False)
        if order_id:
            order_lines = self.prepare_sale_order_line(case_id, order_id)
            self.create_sale_order_line(order_lines)
        return res

    def prepare_sale_order_line(self, case_id, order_id):
        lines = []
        case = self.env['crm.lead'].browse(case_id)
        order = self.env['sale.order'].browse(order_id)
        linked_brs = case.project_id and case.project_id.br_ids or []
        if not linked_brs:
            raise ValidationError(
                _('Error!'),
                _("""There is no available business requirement to
                    make sale order!"""))
        for br in linked_brs:
            if br.state in ('drop', 'cancel'):
                continue
            for br_line in br.deliverable_lines:
                taxes = br_line.product_id.taxes_id
                fp = order.partner_id.property_account_position
                if fp:
                    taxes = fp.map_tax(taxes)
                taxes = taxes.filtered(
                    lambda x: x.company_id == br.company_id)
                vals = {
                    'order_id': order_id,
                    'product_id': br_line.product_id.id,
                    'name': br_line.name,
                    'product_uom_qty': br_line.qty,
                    'product_uos_qty': br_line.qty,
                    'product_uom': br_line.uom_id.id,
                    'product_uos': br_line.uom_id.id,
                    'price_unit': br_line.unit_price,
                    'tax_id': [(6, 0, taxes.ids)],
                }
                lines.append(vals)
        return lines

    def create_sale_order_line(self, order_lines):
        saleorder_line_obj = self.env['sale.order.line']
        for line in order_lines:
            saleorder_line_obj.create(line)
<commit_msg>Fix: init() takes exactly 2 arguments (3 given) (#83)<commit_after># -*- coding: utf-8 -*-
from openerp import api, fields, models
from openerp.tools.translate import _
from openerp.exceptions import ValidationError

class CrmMakeSale(models.TransientModel):
    _name = "br.crm.make.sale"
    _inherit = "crm.make.sale"

    update_quotation = fields.Boolean('Update existing quotation')

    @api.multi
    def make_orderline(self):
        context = self.env.context
        case_id = context and context.get('active_ids', []) or []
        case_id = case_id and case_id[0] or False
        res = super(CrmMakeSale, self).makeOrder()
        if self.update_quotation:
            saleorder = self.env['sale.order'].search([
                ('origin', '=', _('Opportunity: %s') % str(case_id))])
            saleorder = saleorder and saleorder[0] or False
            if saleorder:
                res.update({'res_id': saleorder.id})
                if saleorder.order_line:
                    saleorder.order_line.unlink()

        order_id = res.get('res_id', False)
        if order_id:
            order_lines = self.prepare_sale_order_line(case_id, order_id)
            self.create_sale_order_line(order_lines)
        return res

    def prepare_sale_order_line(self, case_id, order_id):
        lines = []
        case = self.env['crm.lead'].browse(case_id)
        order = self.env['sale.order'].browse(order_id)
        linked_brs = case.project_id and case.project_id.br_ids or []
        if not linked_brs:
            raise ValidationError(
                _("""There is no available business requirement to
                    make sale order!"""))
        for br in linked_brs:
            if br.state in ('drop', 'cancel'):
                continue
            for br_line in br.deliverable_lines:
                taxes = br_line.product_id.taxes_id
                fp = order.partner_id.property_account_position
                if fp:
                    taxes = fp.map_tax(taxes)
                taxes = taxes.filtered(
                    lambda x: x.company_id == br.company_id)
                vals = {
                    'order_id': order_id,
                    'product_id': br_line.product_id.id,
                    'name': br_line.name,
                    'product_uom_qty': br_line.qty,
                    'product_uos_qty': br_line.qty,
                    'product_uom': br_line.uom_id.id,
                    'product_uos': br_line.uom_id.id,
                    'price_unit': br_line.unit_price,
                    'tax_id': [(6, 0, taxes.ids)],
                }
                lines.append(vals)
        return lines

    def create_sale_order_line(self, order_lines):
        saleorder_line_obj = self.env['sale.order.line']
        for line in order_lines:
            saleorder_line_obj.create(line)
<|endoftext|>


<commit_before>from gym import logger
import numpy as np

from gym import error
from gym.utils import closer

env_closer = closer.Closer()

# Env-related abstractions

class Env(object):
    """The main OpenAI Gym class. It encapsulates an environment with
    arbitrary behind-the-scenes dynamics. An environment can be
    partially or fully observed.

    The main API methods that users of this class need to know are:

        step
        reset
        render
        close
        seed

    And set the following attributes:

        action_space: The Space object corresponding to valid actions
        observation_space: The Space object corresponding to valid observations
        reward_range: A tuple corresponding to the min and max possible rewards

    Note: a default reward range set to [-inf,+inf] already exists. Set it if you want a narrower range.

    The methods are accessed publicly as "step", "reset", etc.. The
    non-underscored versions are wrapper methods to which we may add
    functionality over time.
    """

    # Set this in SOME subclasses
    metadata = {'render.modes': []}
    reward_range = (-np.inf, np.inf)
    spec = None

    # Set these in ALL subclasses
    action_space = None
    observation_space = None

    def step(self, action):
        """Run one timestep of the environment's dynamics. When end of
        episode is reached, you are responsible for calling `reset()`
        to reset this environment's state.

        Accepts an action and returns a tuple (observation, reward, done, info).

        Args:
            action (object): an action provided by the environment

        Returns:
            observation (object): agent's observation of the current environment
            reward (float) : amount of reward returned after previous action
            done (boolean): whether the episode has ended, in which case further step() calls will return undefined results
            info (dict): contains auxiliary diagnostic information (helpful for debugging, and sometimes learning)
        """
        raise NotImplementedError

    def reset(self):
        """Resets the state of the environment and returns an initial observation.

        Returns: observation (object): the initial observation of the
            space.
        """
        raise NotImplementedError

    def render(self, mode='human'):
        """Renders the environment.

        The set of supported modes varies per environment. (And some
        environments do not support rendering at all.) By convention,
        if mode is:

        - human: render to the current display or terminal and
          return nothing. Usually for human consumption.
        - rgb_array: Return an numpy.ndarray with shape (x, y, 3),
          representing RGB values for an x-by-y pixel image, suitable
          for turning into a video.
        - ansi: Return a string (str) or StringIO.StringIO containing a
          terminal-style text representation. The text can include newlines
          and ANSI escape sequences (e.g. for colors).

        Note:
            Make sure that your class's metadata 'render.modes' key includes
              the list of supported modes. It's recommended to call super()
              in implementations to use the functionality of this method.

        Args:
            mode (str): the mode to render with
            close (bool): close all open renderings

        Example:

        class MyEnv(Env):
            metadata = {'render.modes': ['human', 'rgb_array']}

            def render(self, mode='human'):
                if mode == 'rgb_array':
                    return np.array(...) # return RGB frame suitable for video
                elif mode is 'human':
                    ... # pop up a window and render
                else:
                    super(MyEnv, self).render(mode=mode) # just raise an exception
        """
        raise NotImplementedError

    def close(self):
        """Override _close in your subclass to perform any necessary cleanup.

        Environments will automatically close() themselves when
        garbage collected or when the program exits.
        """
        return

    def seed(self, seed=None):
        """Sets the seed for this env's random number generator(s).

        Note:
            Some environments use multiple pseudorandom number generators.
            We want to capture all such seeds used in order to ensure that
            there aren't accidental correlations between multiple generators.

        Returns:
            list<bigint>: Returns the list of seeds used in this env's random
              number generators. The first value in the list should be the
              "main" seed, or the value which a reproducer should pass to
              'seed'. Often, the main seed equals the provided 'seed', but
              this won't be true if seed=None, for example.
        """
        logger.warn("Could not seed environment %s", self)
        return

    @property
    def unwrapped(self):
        """Completely unwrap this env.

        Returns:
            gym.Env: The base non-wrapped gym.Env instance
        """
        return self

    def __str__(self):
        if self.spec is None:
            return '<{} instance>'.format(type(self).__name__)
        else:
            return '<{}<{}>>'.format(type(self).__name__, self.spec.id)

# Space-related abstractions

class Space(object):
    """Defines the observation and action spaces, so you can write generic
    code that applies to any Env. For example, you can choose a random
    action.
    """
    def __init__(self, shape, dtype):
        self.shape = None if shape is None else tuple(shape)
        self.dtype = None if dtype is None else np.dtype(dtype)

    def sample(self):
        """
        Uniformly randomly sample a random element of this space
        """
        raise NotImplementedError

    def contains(self, x):
        """
        Return boolean specifying if x is a valid
        member of this space
        """
        raise NotImplementedError

    def to_jsonable(self, sample_n):
        """Convert a batch of samples from this space to a JSONable data type."""
        # By default, assume identity is JSONable
        return sample_n

    def from_jsonable(self, sample_n):
        """Convert a JSONable data type to a batch of samples from this space."""
        # By default, assume identity is JSONable
        return sample_n

    def compatible(self, space):
        """
        Return boolean specifying if space is compatible with this Space
        (equal shape structure, ignoring bounds).  None matches any Space.
        """
        # allow None to match with any space
        if space is None:
            return True

        # compare classes
        if type(self) != type(space):
            return False

        # TODO - compare dtypes?

        # compare shapes
        return self.shape == space.shape

warn_once = True

def deprecated_warn_once(text):
    global warn_once
    if not warn_once: return
    warn_once = False
    logger.warn(text)

class Wrapper(Env):
    env = None

    def __init__(self, env):
        self.env = env
        self.action_space = self.env.action_space
        self.observation_space = self.env.observation_space
        self.reward_range = self.env.reward_range
        self.metadata = self.env.metadata
        self._warn_double_wrap()

    @classmethod
    def class_name(cls):
        return cls.__name__

    def _warn_double_wrap(self):
        env = self.env
        while True:
            if isinstance(env, Wrapper):
                if env.class_name() == self.class_name():
                    raise error.DoubleWrapperError("Attempted to double wrap with Wrapper: {}".format(self.__class__.__name__))
                env = env.env
            else:
                break

    def step(self, action):
        if hasattr(self, "_step"):
            deprecated_warn_once("%s doesn't implement 'step' method, but it implements deprecated '_step' method." % type(self))
            self.step = self._step
            return self.step(action)
        else:
            deprecated_warn_once("%s doesn't implement 'step' method, " % type(self) +
                "which is required for wrappers derived directly from Wrapper. Deprecated default implementation is used.")
            return self.env.step(action)

    def reset(self, **kwargs):
        if hasattr(self, "_reset"):
            deprecated_warn_once("%s doesn't implement 'reset' method, but it implements deprecated '_reset' method." % type(self))
            self.reset = self._reset
            return self._reset(**kwargs)
        else:
            deprecated_warn_once("%s doesn't implement 'reset' method, " % type(self) +
                "which is required for wrappers derived directly from Wrapper. Deprecated default implementation is used.")
            return self.env.reset(**kwargs)

    def render(self, mode='human'):
        return self.env.render(mode)

    def close(self):
        if self.env:
            return self.env.close()

    def seed(self, seed=None):
        return self.env.seed(seed)

    def __str__(self):
        return '<{}{}>'.format(type(self).__name__, self.env)

    def __repr__(self):
        return str(self)

    @property
    def unwrapped(self):
        return self.env.unwrapped

    @property
    def spec(self):
        return self.env.spec

class ObservationWrapper(Wrapper):
    def step(self, action):
        observation, reward, done, info = self.env.step(action)
        return self.observation(observation), reward, done, info

    def reset(self, **kwargs):
        observation = self.env.reset(**kwargs)
        return self.observation(observation)

    def observation(self, observation):
        deprecated_warn_once("%s doesn't implement 'observation' method. Maybe it implements deprecated '_observation' method." % type(self))
        return self._observation(observation)

class RewardWrapper(Wrapper):
    def reset(self):
        return self.env.reset()

    def step(self, action):
        observation, reward, done, info = self.env.step(action)
        return observation, self.reward(reward), done, info

    def reward(self, reward):
        deprecated_warn_once("%s doesn't implement 'reward' method. Maybe it implements deprecated '_reward' method." % type(self))
        return self._reward(reward)

class ActionWrapper(Wrapper):
    def step(self, action):
        action = self.action(action)
        return self.env.step(action)

    def reset(self):
        return self.env.reset()

    def action(self, action):
        deprecated_warn_once("%s doesn't implement 'action' method. Maybe it implements deprecated '_action' method." % type(self))
        return self._action(action)

    def reverse_action(self, action):
        deprecated_warn_once("%s doesn't implement 'reverse_action' method. Maybe it implements deprecated '_reverse_action' method." % type(self))
        return self._reverse_action(action)
<commit_msg>Glenn space compatibility (#872)<commit_after>from gym import logger
import numpy as np

from gym import error
from gym.utils import closer

env_closer = closer.Closer()

# Env-related abstractions

class Env(object):
    """The main OpenAI Gym class. It encapsulates an environment with
    arbitrary behind-the-scenes dynamics. An environment can be
    partially or fully observed.

    The main API methods that users of this class need to know are:

        step
        reset
        render
        close
        seed

    And set the following attributes:

        action_space: The Space object corresponding to valid actions
        observation_space: The Space object corresponding to valid observations
        reward_range: A tuple corresponding to the min and max possible rewards

    Note: a default reward range set to [-inf,+inf] already exists. Set it if you want a narrower range.

    The methods are accessed publicly as "step", "reset", etc.. The
    non-underscored versions are wrapper methods to which we may add
    functionality over time.
    """

    # Set this in SOME subclasses
    metadata = {'render.modes': []}
    reward_range = (-np.inf, np.inf)
    spec = None

    # Set these in ALL subclasses
    action_space = None
    observation_space = None

    def step(self, action):
        """Run one timestep of the environment's dynamics. When end of
        episode is reached, you are responsible for calling `reset()`
        to reset this environment's state.

        Accepts an action and returns a tuple (observation, reward, done, info).

        Args:
            action (object): an action provided by the environment

        Returns:
            observation (object): agent's observation of the current environment
            reward (float) : amount of reward returned after previous action
            done (boolean): whether the episode has ended, in which case further step() calls will return undefined results
            info (dict): contains auxiliary diagnostic information (helpful for debugging, and sometimes learning)
        """
        raise NotImplementedError

    def reset(self):
        """Resets the state of the environment and returns an initial observation.

        Returns: observation (object): the initial observation of the
            space.
        """
        raise NotImplementedError

    def render(self, mode='human'):
        """Renders the environment.

        The set of supported modes varies per environment. (And some
        environments do not support rendering at all.) By convention,
        if mode is:

        - human: render to the current display or terminal and
          return nothing. Usually for human consumption.
        - rgb_array: Return an numpy.ndarray with shape (x, y, 3),
          representing RGB values for an x-by-y pixel image, suitable
          for turning into a video.
        - ansi: Return a string (str) or StringIO.StringIO containing a
          terminal-style text representation. The text can include newlines
          and ANSI escape sequences (e.g. for colors).

        Note:
            Make sure that your class's metadata 'render.modes' key includes
              the list of supported modes. It's recommended to call super()
              in implementations to use the functionality of this method.

        Args:
            mode (str): the mode to render with
            close (bool): close all open renderings

        Example:

        class MyEnv(Env):
            metadata = {'render.modes': ['human', 'rgb_array']}

            def render(self, mode='human'):
                if mode == 'rgb_array':
                    return np.array(...) # return RGB frame suitable for video
                elif mode is 'human':
                    ... # pop up a window and render
                else:
                    super(MyEnv, self).render(mode=mode) # just raise an exception
        """
        raise NotImplementedError

    def close(self):
        """Override _close in your subclass to perform any necessary cleanup.

        Environments will automatically close() themselves when
        garbage collected or when the program exits.
        """
        return

    def seed(self, seed=None):
        """Sets the seed for this env's random number generator(s).

        Note:
            Some environments use multiple pseudorandom number generators.
            We want to capture all such seeds used in order to ensure that
            there aren't accidental correlations between multiple generators.

        Returns:
            list<bigint>: Returns the list of seeds used in this env's random
              number generators. The first value in the list should be the
              "main" seed, or the value which a reproducer should pass to
              'seed'. Often, the main seed equals the provided 'seed', but
              this won't be true if seed=None, for example.
        """
        logger.warn("Could not seed environment %s", self)
        return

    @property
    def unwrapped(self):
        """Completely unwrap this env.

        Returns:
            gym.Env: The base non-wrapped gym.Env instance
        """
        return self

    def __str__(self):
        if self.spec is None:
            return '<{} instance>'.format(type(self).__name__)
        else:
            return '<{}<{}>>'.format(type(self).__name__, self.spec.id)

# Space-related abstractions

class Space(object):
    """Defines the observation and action spaces, so you can write generic
    code that applies to any Env. For example, you can choose a random
    action.
    """
    def __init__(self, shape, dtype):
        self.shape = None if shape is None else tuple(shape)
        self.dtype = None if dtype is None else np.dtype(dtype)

    def sample(self):
        """
        Uniformly randomly sample a random element of this space
        """
        raise NotImplementedError

    def contains(self, x):
        """
        Return boolean specifying if x is a valid
        member of this space
        """
        raise NotImplementedError

    def to_jsonable(self, sample_n):
        """Convert a batch of samples from this space to a JSONable data type."""
        # By default, assume identity is JSONable
        return sample_n

    def from_jsonable(self, sample_n):
        """Convert a JSONable data type to a batch of samples from this space."""
        # By default, assume identity is JSONable
        return sample_n

    def compatible(self, space):
        """
        Return boolean specifying if space is compatible with this Space
        (equal shape structure, ignoring bounds).  None matches any Space.
        """
        # compare classes
        if type(self) != type(space):
            return False

        # TODO - compare dtypes?

        # compare shapes
        return self.shape == space.shape

warn_once = True

def deprecated_warn_once(text):
    global warn_once
    if not warn_once: return
    warn_once = False
    logger.warn(text)

class Wrapper(Env):
    env = None

    def __init__(self, env):
        self.env = env
        self.action_space = self.env.action_space
        self.observation_space = self.env.observation_space
        self.reward_range = self.env.reward_range
        self.metadata = self.env.metadata
        self._warn_double_wrap()

    @classmethod
    def class_name(cls):
        return cls.__name__

    def _warn_double_wrap(self):
        env = self.env
        while True:
            if isinstance(env, Wrapper):
                if env.class_name() == self.class_name():
                    raise error.DoubleWrapperError("Attempted to double wrap with Wrapper: {}".format(self.__class__.__name__))
                env = env.env
            else:
                break

    def step(self, action):
        if hasattr(self, "_step"):
            deprecated_warn_once("%s doesn't implement 'step' method, but it implements deprecated '_step' method." % type(self))
            self.step = self._step
            return self.step(action)
        else:
            deprecated_warn_once("%s doesn't implement 'step' method, " % type(self) +
                "which is required for wrappers derived directly from Wrapper. Deprecated default implementation is used.")
            return self.env.step(action)

    def reset(self, **kwargs):
        if hasattr(self, "_reset"):
            deprecated_warn_once("%s doesn't implement 'reset' method, but it implements deprecated '_reset' method." % type(self))
            self.reset = self._reset
            return self._reset(**kwargs)
        else:
            deprecated_warn_once("%s doesn't implement 'reset' method, " % type(self) +
                "which is required for wrappers derived directly from Wrapper. Deprecated default implementation is used.")
            return self.env.reset(**kwargs)

    def render(self, mode='human'):
        return self.env.render(mode)

    def close(self):
        if self.env:
            return self.env.close()

    def seed(self, seed=None):
        return self.env.seed(seed)

    def __str__(self):
        return '<{}{}>'.format(type(self).__name__, self.env)

    def __repr__(self):
        return str(self)

    @property
    def unwrapped(self):
        return self.env.unwrapped

    @property
    def spec(self):
        return self.env.spec

class ObservationWrapper(Wrapper):
    def step(self, action):
        observation, reward, done, info = self.env.step(action)
        return self.observation(observation), reward, done, info

    def reset(self, **kwargs):
        observation = self.env.reset(**kwargs)
        return self.observation(observation)

    def observation(self, observation):
        deprecated_warn_once("%s doesn't implement 'observation' method. Maybe it implements deprecated '_observation' method." % type(self))
        return self._observation(observation)

class RewardWrapper(Wrapper):
    def reset(self):
        return self.env.reset()

    def step(self, action):
        observation, reward, done, info = self.env.step(action)
        return observation, self.reward(reward), done, info

    def reward(self, reward):
        deprecated_warn_once("%s doesn't implement 'reward' method. Maybe it implements deprecated '_reward' method." % type(self))
        return self._reward(reward)

class ActionWrapper(Wrapper):
    def step(self, action):
        action = self.action(action)
        return self.env.step(action)

    def reset(self):
        return self.env.reset()

    def action(self, action):
        deprecated_warn_once("%s doesn't implement 'action' method. Maybe it implements deprecated '_action' method." % type(self))
        return self._action(action)

    def reverse_action(self, action):
        deprecated_warn_once("%s doesn't implement 'reverse_action' method. Maybe it implements deprecated '_reverse_action' method." % type(self))
        return self._reverse_action(action)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import division

import os
import csv
import sys
import math
import argparse
import threading

def show_version():
    print("python is {0}".format(sys.version), file=sys.stdout)
    import numpy as np
    print("numpy is {0}".format(np.__version__), file=sys.stdout)
    import sklearn
    print("sklearn is {0}".format(sklearn.__version__), file=sys.stdout)
    import scipy
    print("scipy is {0}".format(scipy.__version__), file=sys.stdout)

try:
    from quick_server import create_server, msg, setup_restart
    from quick_cache import QuickCache

    import explainer
except ImportError:
    show_version()
    raise

def get_server(addr, port, explainer_obj, cache):
    server = create_server((addr, port))

    if heroku:
        server.no_command_loop = True
        server.bind_path('/', '.')
        prefix = ''
    else:
        server.bind_path('/', '..')
        prefix = '/' + os.path.basename(os.path.normpath(server.base_path))

    server.directory_listing = True
    server.add_default_white_list()
    server.link_empty_favicon_fallback()

    server.suppress_noise = True
    server.report_slow_requests = True

    server.link_worker_js(prefix + '/js/worker.js')
    server.cache = cache

    def canonic_ixs(ixs):
        return sorted(frozenset(convert_ixs(ixs)))

    def convert_ixs(ixs):
        if ixs is None:
            return []
        return [ int(ix) for ix in ixs ]

    def get_thresholds(args):
        return (float(args["l"]), float(args["r"]))

    def optional_bool(key, args, default):
        res = args[key] if key in args else default
        if res is None:
            return default
        return bool(res)

    ### explainer ###

    @server.json_get(prefix + '/explainer_roc_curve', 0)
    def json_explainer_roc_curve(req, args):
        args = args["query"]
        token = args["token"] if "token" in args and args["token"] else None
        pred_ixs = optional_bool("pred_ixs", args, False)
        res = explainer_obj.get_roc_curve()
        res["token"] = server.create_token() if token is None else token
        if pred_ixs:
            res["pred_ixs"] = explainer_obj.get_pred_ixs()
        return res

    def token_obj(args):
        token = args["token"]
        obj = server.get_token_obj(token)
        if "ixss" not in obj:
            obj["ixss"] = [ canonic_ixs(explainer_obj.get_all_ixs()) ]
            obj["msgs"] = [ "all: " + str(len(obj["ixss"][-1])) ]
        return obj

    token_lock = threading.Lock()
    def get_ixs(args):
        with token_lock:
            return token_obj(args)["ixss"][-1]

    @server.json_post(prefix + '/explainer_ixs_get', 0)
    def json_explainer_ixs_get(req, args):
        with token_lock:
            args = args["post"]
            obj = token_obj(args)
            return [ msg for msg in obj["msgs"] ]

    @server.json_post(prefix + '/explainer_ixs_put', 0)
    def json_explainer_ixs_put(req, args):
        with token_lock:
            args = args["post"]
            if "ixs" in args:
                new_ixs = canonic_ixs(args["ixs"])
                pre_text = args["msg"] + ": " if "msg" in args and args["msg"] else ""
                new_text = pre_text + str(len(new_ixs))
            else:
                new_ixs = None
            if "pos" in args:
                new_pos = int(args["pos"])
            else:
                new_pos = None
            obj = token_obj(args)
            if new_pos is not None:
                obj["ixss"] = obj["ixss"][:(new_pos + 1)]
                obj["msgs"] = obj["msgs"][:(new_pos + 1)]
            if new_ixs is not None:
                ixss = obj["ixss"]
                found = None
                if len(new_ixs) == 0:
                    found = len(ixss)
                else:
                    for (pos, ixs) in enumerate(ixss):
                        if ixs == new_ixs:
                            found = pos + 1
                            break
                if found is not None:
                    obj["ixss"] = obj["ixss"][:found]
                    obj["msgs"] = obj["msgs"][:found]
                else:
                    obj["ixss"].append(new_ixs)
                    obj["msgs"].append(new_text)
            return [ msg for msg in obj["msgs"] ]

    @server.json_post(prefix + '/explainer_page_get', 0)
    def json_explainer_page_get(req, args):
        with token_lock:
            args = args["post"]
            page = args["page"]
            obj = token_obj(args)
            if page not in obj:
                obj[page] = {}
            return obj[page]

    @server.json_post(prefix + '/explainer_page_put', 0)
    def json_explainer_page_put(req, args):
        with token_lock:
            args = args["post"]
            page = args["page"]
            obj = token_obj(args)
            if page not in obj:
                obj[page] = {}
            put = args["put"]
            for (k, v) in put.items():
                obj[page][k] = v
            return obj[page]

    @server.json_post(prefix + '/explainer_page_clear', 0)
    def json_explainer_page_clear(req, args):
        with token_lock:
            args = args["post"]
            page = args["page"]
            obj = token_obj(args)
            obj[page] = {}
            return obj[page]

    @server.json_post(prefix + '/explainer_expls_stats', 0)
    def json_explainer_expls_stats(req, args):
        args = args["post"]
        ixs = get_ixs(args)
        score = get_thresholds(args)
        return {
            "expls": explainer_obj.get_expl_stats(ixs, score),
            "totals": explainer_obj.get_stats(ixs, score),
            "all": explainer_obj.get_stats(explainer_obj.get_all_ixs(), score),
        }

    @server.json_post(prefix + '/explainer_granular', 0)
    def json_explainer_granular(req, args):
        args = args["post"]
        score = get_thresholds(args)
        ixs = get_ixs(args)
        expl = args["expl"]
        partial = optional_bool("partial", args, False)
        compact = optional_bool("ignore_irrelevant_features", args, False)
        groups, features, feature_importances \
            = explainer_obj.get_granular_expl(ixs, score, expl, partial, compact)
        return {
            "groups": groups,
            "features": features,
            "importances": feature_importances,
        }

    ### commands ###

    def complete_cache_clear(args, text):
        if args:
            return []
        return [ section for section in cache.list_sections() if section.startswith(text) ]

    @server.cmd(complete=complete_cache_clear)
    def cache_clear(args):
        if len(args) > 1:
          msg("too many extra arguments! expected one got {0}", ' '.join(args))
          return
        msg("clear {0}cache{1}{2}", "" if args else "all ", " " if args else "s", args[0] if args else "")
        cache.clean_cache(args[0] if args else None)

    return server, prefix

heroku = False
if __name__ == '__main__':
    if '--heroku' not in sys.argv[1:]:
        setup_restart()

    if '-v' in sys.argv[1:]:
        show_version()
        sys.exit(1)
    parser = argparse.ArgumentParser(description='Class Signature Server')
    parser.add_argument('-v', action='store_true', help="print library versions and exit")
    parser.add_argument('--sample', type=float, default=1.0, help="samples data points for explainer")
    parser.add_argument('--heroku', action='store_true', help="start in heroku mode")
    parser.add_argument('--quota', default=10240, help="set cache quota")
    parser.add_argument('--ram-quota', default=2048, help="set RAM cache quota")
    parser.add_argument('-a', type=str, default="localhost", help="specifies the server address")
    parser.add_argument('-p', type=int, default=8080, help="specifies the server port")
    parser.add_argument('input', type=str, help="file containing a CSV table with categorical values")
    parser.add_argument('explainer', type=str, help="file with explainer info")
    args = parser.parse_args()

    addr = args.a
    port = args.p
    heroku = args.heroku

    if heroku:
        os.chdir(os.path.dirname(os.path.abspath(__file__)))

    cache_quota = args.quota
    ram_quota = args.ram_quota
    explainer_file = args.explainer
    sample = args.sample

    cache_temp = "tmp"
    if os.path.exists("cache_path.txt"):
        with open("cache_path.txt") as cp:
            cache_temp = cp.read().strip()

    cid = args.input + ":" + explainer_file
    cache = QuickCache(None, cid, quota=cache_quota, ram_quota=ram_quota, temp=cache_temp, warnings=msg)

    explainer_obj = explainer.Explainer(explainer_file, args.input, sample, cache, msg)
    server, prefix = get_server(addr, port, explainer_obj, cache)
    msg("{0}", " ".join(sys.argv))
    msg("starting server at http://{0}:{1}{2}/", addr if addr else 'localhost', port, prefix)
    try:
        server.serve_forever()
    finally:
        msg("shutting down..")
        msg("{0}", " ".join(sys.argv))
        server.server_close()
<commit_msg>change path<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import division

import os
import csv
import sys
import math
import argparse
import threading

def show_version():
    print("python is {0}".format(sys.version), file=sys.stdout)
    import numpy as np
    print("numpy is {0}".format(np.__version__), file=sys.stdout)
    import sklearn
    print("sklearn is {0}".format(sklearn.__version__), file=sys.stdout)
    import scipy
    print("scipy is {0}".format(scipy.__version__), file=sys.stdout)

try:
    from quick_server import create_server, msg, setup_restart
    from quick_cache import QuickCache

    import explainer
except ImportError:
    show_version()
    raise

def get_server(addr, port, explainer_obj, cache):
    server = create_server((addr, port))

    if heroku:
        server.no_command_loop = True
        server.bind_path('/', '.')
        prefix = '/projects/expl/'
    else:
        server.bind_path('/', '..')
        prefix = '/' + os.path.basename(os.path.normpath(server.base_path))

    server.directory_listing = True
    server.add_default_white_list()
    server.link_empty_favicon_fallback()

    server.suppress_noise = True
    server.report_slow_requests = True

    server.link_worker_js(prefix + '/js/worker.js')
    server.cache = cache

    def canonic_ixs(ixs):
        return sorted(frozenset(convert_ixs(ixs)))

    def convert_ixs(ixs):
        if ixs is None:
            return []
        return [ int(ix) for ix in ixs ]

    def get_thresholds(args):
        return (float(args["l"]), float(args["r"]))

    def optional_bool(key, args, default):
        res = args[key] if key in args else default
        if res is None:
            return default
        return bool(res)

    ### explainer ###

    @server.json_get(prefix + '/explainer_roc_curve', 0)
    def json_explainer_roc_curve(req, args):
        args = args["query"]
        token = args["token"] if "token" in args and args["token"] else None
        pred_ixs = optional_bool("pred_ixs", args, False)
        res = explainer_obj.get_roc_curve()
        res["token"] = server.create_token() if token is None else token
        if pred_ixs:
            res["pred_ixs"] = explainer_obj.get_pred_ixs()
        return res

    def token_obj(args):
        token = args["token"]
        obj = server.get_token_obj(token)
        if "ixss" not in obj:
            obj["ixss"] = [ canonic_ixs(explainer_obj.get_all_ixs()) ]
            obj["msgs"] = [ "all: " + str(len(obj["ixss"][-1])) ]
        return obj

    token_lock = threading.Lock()
    def get_ixs(args):
        with token_lock:
            return token_obj(args)["ixss"][-1]

    @server.json_post(prefix + '/explainer_ixs_get', 0)
    def json_explainer_ixs_get(req, args):
        with token_lock:
            args = args["post"]
            obj = token_obj(args)
            return [ msg for msg in obj["msgs"] ]

    @server.json_post(prefix + '/explainer_ixs_put', 0)
    def json_explainer_ixs_put(req, args):
        with token_lock:
            args = args["post"]
            if "ixs" in args:
                new_ixs = canonic_ixs(args["ixs"])
                pre_text = args["msg"] + ": " if "msg" in args and args["msg"] else ""
                new_text = pre_text + str(len(new_ixs))
            else:
                new_ixs = None
            if "pos" in args:
                new_pos = int(args["pos"])
            else:
                new_pos = None
            obj = token_obj(args)
            if new_pos is not None:
                obj["ixss"] = obj["ixss"][:(new_pos + 1)]
                obj["msgs"] = obj["msgs"][:(new_pos + 1)]
            if new_ixs is not None:
                ixss = obj["ixss"]
                found = None
                if len(new_ixs) == 0:
                    found = len(ixss)
                else:
                    for (pos, ixs) in enumerate(ixss):
                        if ixs == new_ixs:
                            found = pos + 1
                            break
                if found is not None:
                    obj["ixss"] = obj["ixss"][:found]
                    obj["msgs"] = obj["msgs"][:found]
                else:
                    obj["ixss"].append(new_ixs)
                    obj["msgs"].append(new_text)
            return [ msg for msg in obj["msgs"] ]

    @server.json_post(prefix + '/explainer_page_get', 0)
    def json_explainer_page_get(req, args):
        with token_lock:
            args = args["post"]
            page = args["page"]
            obj = token_obj(args)
            if page not in obj:
                obj[page] = {}
            return obj[page]

    @server.json_post(prefix + '/explainer_page_put', 0)
    def json_explainer_page_put(req, args):
        with token_lock:
            args = args["post"]
            page = args["page"]
            obj = token_obj(args)
            if page not in obj:
                obj[page] = {}
            put = args["put"]
            for (k, v) in put.items():
                obj[page][k] = v
            return obj[page]

    @server.json_post(prefix + '/explainer_page_clear', 0)
    def json_explainer_page_clear(req, args):
        with token_lock:
            args = args["post"]
            page = args["page"]
            obj = token_obj(args)
            obj[page] = {}
            return obj[page]

    @server.json_post(prefix + '/explainer_expls_stats', 0)
    def json_explainer_expls_stats(req, args):
        args = args["post"]
        ixs = get_ixs(args)
        score = get_thresholds(args)
        return {
            "expls": explainer_obj.get_expl_stats(ixs, score),
            "totals": explainer_obj.get_stats(ixs, score),
            "all": explainer_obj.get_stats(explainer_obj.get_all_ixs(), score),
        }

    @server.json_post(prefix + '/explainer_granular', 0)
    def json_explainer_granular(req, args):
        args = args["post"]
        score = get_thresholds(args)
        ixs = get_ixs(args)
        expl = args["expl"]
        partial = optional_bool("partial", args, False)
        compact = optional_bool("ignore_irrelevant_features", args, False)
        groups, features, feature_importances \
            = explainer_obj.get_granular_expl(ixs, score, expl, partial, compact)
        return {
            "groups": groups,
            "features": features,
            "importances": feature_importances,
        }

    ### commands ###

    def complete_cache_clear(args, text):
        if args:
            return []
        return [ section for section in cache.list_sections() if section.startswith(text) ]

    @server.cmd(complete=complete_cache_clear)
    def cache_clear(args):
        if len(args) > 1:
          msg("too many extra arguments! expected one got {0}", ' '.join(args))
          return
        msg("clear {0}cache{1}{2}", "" if args else "all ", " " if args else "s", args[0] if args else "")
        cache.clean_cache(args[0] if args else None)

    return server, prefix

heroku = False
if __name__ == '__main__':
    if '--heroku' not in sys.argv[1:]:
        setup_restart()

    if '-v' in sys.argv[1:]:
        show_version()
        sys.exit(1)
    parser = argparse.ArgumentParser(description='Class Signature Server')
    parser.add_argument('-v', action='store_true', help="print library versions and exit")
    parser.add_argument('--sample', type=float, default=1.0, help="samples data points for explainer")
    parser.add_argument('--heroku', action='store_true', help="start in heroku mode")
    parser.add_argument('--quota', default=10240, help="set cache quota")
    parser.add_argument('--ram-quota', default=2048, help="set RAM cache quota")
    parser.add_argument('-a', type=str, default="localhost", help="specifies the server address")
    parser.add_argument('-p', type=int, default=8080, help="specifies the server port")
    parser.add_argument('input', type=str, help="file containing a CSV table with categorical values")
    parser.add_argument('explainer', type=str, help="file with explainer info")
    args = parser.parse_args()

    addr = args.a
    port = args.p
    heroku = args.heroku

    if heroku:
        os.chdir(os.path.dirname(os.path.abspath(__file__)))

    cache_quota = args.quota
    ram_quota = args.ram_quota
    explainer_file = args.explainer
    sample = args.sample

    cache_temp = "tmp"
    if os.path.exists("cache_path.txt"):
        with open("cache_path.txt") as cp:
            cache_temp = cp.read().strip()

    cid = args.input + ":" + explainer_file
    cache = QuickCache(None, cid, quota=cache_quota, ram_quota=ram_quota, temp=cache_temp, warnings=msg)

    explainer_obj = explainer.Explainer(explainer_file, args.input, sample, cache, msg)
    server, prefix = get_server(addr, port, explainer_obj, cache)
    msg("{0}", " ".join(sys.argv))
    msg("starting server at http://{0}:{1}{2}/", addr if addr else 'localhost', port, prefix)
    try:
        server.serve_forever()
    finally:
        msg("shutting down..")
        msg("{0}", " ".join(sys.argv))
        server.server_close()
<|endoftext|>


<commit_before>#!/usr/bin/env python
from flask import Flask, jsonify, request
from quora import Quora, Activity

app = Flask(__name__)

# log to stderr
import logging
from logging import StreamHandler
file_handler = StreamHandler()
app.logger.setLevel(logging.DEBUG)
app.logger.addHandler(file_handler)

####################################################################
# Routes
####################################################################

@app.route('/', methods=['GET'])
def index_route():
    return jsonify({
        'author': 'Christopher Su',
        'author_url': 'http://christopher.su',
        'base_url': 'http://quora-api.herokuapp.com',
        'project': 'Quora API',
        'project_url': 'https://github.com/csu/quora-api',
        'project_documentation': 'http://christopher.su/quora-api/',
        'project_issues': 'https://github.com/csu/quora-api/issues',
        'endpoints': {
            'user': '/users/{user}',
            'user_activity': '/users/{user}/activity',
            'user_activity_answers': '/users/{user}/activity/answers',
            'user_activity_questions': '/users/{user}/activity/questions',
            'user_activity_want_answers': '/users/{user}/activity/want_answers',
            'user_activity_votes': '/users/{user}/activity/votes',
            'question': '/questions/{question}',
            'answer': '/answers/{answer_short_link}',
            'answer_with_user': ['/answers/{question}/{user}', '/answers/{question}/answer/{user}']
        }
    })

####################################################################
# Users
####################################################################

@app.route('/users/<user>', methods=['GET'])
def user_stats_route(user):
    return jsonify(Quora.get_user_stats(user))

####################################################################
# Activity
####################################################################

@app.route('/users/<user>/activity', methods=['GET'])
def user_activity_route(user):
    return jsonify(Quora.get_user_activity(user))

@app.route('/users/<user>/activity/answers', methods=['GET'])
def user_answers_route(user):
    return jsonify({'items': Quora.get_activity(user).answers})

@app.route('/users/<user>/activity/user_follows', methods=['GET'])
def user_user_follows_route(user):
    return jsonify({'items': Quora.get_activity(user).user_follows})

@app.route('/users/<user>/activity/want_answers', methods=['GET'])
def user_want_answers_route(user):
    return jsonify({'items': Quora.get_activity(user).want_answers})

@app.route('/users/<user>/activity/upvotes', methods=['GET'])
def user_upvotes_route(user):
    return jsonify({'items': Quora.get_activity(user).upvotes})

@app.route('/users/<user>/activity/review_requests', methods=['GET'])
def user_review_requests_route(user):
    return jsonify({'items': Quora.get_activity(user).review_requests})

####################################################################
# Questions
####################################################################
@app.route('/questions/<question>', methods=['GET'])
def question_stats_route(question):
    return jsonify(Quora.get_question_stats(question))

####################################################################
# Answers
####################################################################
@app.route('/answers/<question>/<user>', methods=['GET'])
def answer_stats_specific_user_route(question, user):
    return jsonify(Quora.get_one_answer(question, user=user))

@app.route('/answers/<question>/answer/<user>', methods=['GET'])
def answer_stats_specific_user_alternate_route(question, user):
    return jsonify(Quora.get_one_answer(question, user=user))

@app.route('/answers/<answer_short_link>', methods=['GET'])
def answer_stats_short_link_route(answer_short_link):
    return jsonify(Quora.get_one_answer(answer_short_link))

####################################################################
# Start Flask
####################################################################
if __name__ == '__main__':
    app.run(debug=True)
<commit_msg>clean<commit_after>#!/usr/bin/env python
from flask import Flask, jsonify, request
from quora import Quora, Activity
import logging
from logging import StreamHandler

file_handler = StreamHandler()
app.logger.setLevel(logging.DEBUG)
app.logger.addHandler(file_handler)

app = Flask(__name__)

####################################################################
# Routes
####################################################################

@app.route('/', methods=['GET'])
def index_route():
    return jsonify({
        'author': 'Christopher Su',
        'author_url': 'http://christopher.su',
        'base_url': 'http://quora-api.herokuapp.com',
        'project': 'Quora API',
        'project_url': 'https://github.com/csu/quora-api',
        'project_documentation': 'http://christopher.su/quora-api/',
        'project_issues': 'https://github.com/csu/quora-api/issues',
        'endpoints': {
            'user': '/users/{user}',
            'user_activity': '/users/{user}/activity',
            'user_activity_answers': '/users/{user}/activity/answers',
            'user_activity_questions': '/users/{user}/activity/questions',
            'user_activity_want_answers': '/users/{user}/activity/want_answers',
            'user_activity_votes': '/users/{user}/activity/votes',
            'question': '/questions/{question}',
            'answer': '/answers/{answer_short_link}',
            'answer_with_user': ['/answers/{question}/{user}', '/answers/{question}/answer/{user}']
        }
    })

####################################################################
# Users
####################################################################

@app.route('/users/<user>', methods=['GET'])
def user_stats_route(user):
    return jsonify(Quora.get_user_stats(user))

####################################################################
# Activity
####################################################################

@app.route('/users/<user>/activity', methods=['GET'])
def user_activity_route(user):
    return jsonify(Quora.get_user_activity(user))

@app.route('/users/<user>/activity/answers', methods=['GET'])
def user_answers_route(user):
    return jsonify({'items': Quora.get_activity(user).answers})

@app.route('/users/<user>/activity/user_follows', methods=['GET'])
def user_user_follows_route(user):
    return jsonify({'items': Quora.get_activity(user).user_follows})

@app.route('/users/<user>/activity/want_answers', methods=['GET'])
def user_want_answers_route(user):
    return jsonify({'items': Quora.get_activity(user).want_answers})

@app.route('/users/<user>/activity/upvotes', methods=['GET'])
def user_upvotes_route(user):
    return jsonify({'items': Quora.get_activity(user).upvotes})

@app.route('/users/<user>/activity/review_requests', methods=['GET'])
def user_review_requests_route(user):
    return jsonify({'items': Quora.get_activity(user).review_requests})

####################################################################
# Questions
####################################################################
@app.route('/questions/<question>', methods=['GET'])
def question_stats_route(question):
    return jsonify(Quora.get_question_stats(question))

####################################################################
# Answers
####################################################################
@app.route('/answers/<question>/<user>', methods=['GET'])
def answer_stats_specific_user_route(question, user):
    return jsonify(Quora.get_one_answer(question, user=user))

@app.route('/answers/<question>/answer/<user>', methods=['GET'])
def answer_stats_specific_user_alternate_route(question, user):
    return jsonify(Quora.get_one_answer(question, user=user))

@app.route('/answers/<answer_short_link>', methods=['GET'])
def answer_stats_short_link_route(answer_short_link):
    return jsonify(Quora.get_one_answer(answer_short_link))

####################################################################
# Start Flask
####################################################################
if __name__ == '__main__':
    app.run(debug=True)
<|endoftext|>


<commit_before>import requests
import json

from flask import Flask
from flask import request
from flask import abort

app = Flask("ReactDigitsServer", static_url_path="", static_folder="dist")
app.add_url_rule("/", "root", lambda: app.send_static_file("index.html"))
app.add_url_rule("/dist/*", "dist", lambda: app.send_static_file("dist/dist.js"))

@app.route("/user/verify", methods=["POST"])
def verify_user():
    data = json.loads(request.data)

    url = data["apiUrl"]
    auth = data["authHeader"]

    response = requests.get(url, headers={"Authorization": auth})

    if response.status_code != 200:
        return abort(response.status_code)

    return Response(response.content, mimetype='application/json')

app.run(debug=True)
<commit_msg>import Response & update static folder location to public<commit_after>import requests
import json

from flask import Flask
from flask import Response
from flask import request
from flask import abort

app = Flask("ReactDigitsServer", static_url_path="", static_folder="public")
app.add_url_rule("/", "root", lambda: app.send_static_file("index.html"))
app.add_url_rule("/dist/*", "dist", lambda: app.send_static_file("dist/dist.js"))

@app.route("/user/verify", methods=["POST"])
def verify_user():
    data = json.loads(request.data)

    url = data["apiUrl"]
    auth = data["authHeader"]

    response = requests.get(url, headers={"Authorization": auth})

    if response.status_code != 200:
        return abort(response.status_code)

    return Response(response.content, mimetype='application/json')

app.run(debug=True)
<|endoftext|>


<commit_before>from django.conf import settings
from django.utils.translation import get_language

import json
import os

def check_for_target_url_duplication_and_generate_error_message(
    self, partner=False, stream=False
):
    """
    Filter for partners/streams (PROXY and BUNDLE) where the
    target_url is the same as self. On filtering, if we have
    a non-zero number of matches, we generate the appropriate
    error message to be shown to the staff.

    :param self:
    :param partner:
    :param stream:
    :return:
    """
    from TWLight.resources.models import Partner, Stream

    duplicate_target_url_partners = Partner.objects.filter(
        authorization_method__in=[Partner.PROXY, Partner.BUNDLE],
        target_url=self.target_url,
    ).values_list("company_name", flat=True)
    # Exclude self from the filtered partner list, if the operation
    # is performed on Partners.
    if partner:
        duplicate_target_url_partners = duplicate_target_url_partners.exclude(
            pk=self.pk
        )

    duplicate_target_url_streams = Stream.objects.filter(
        authorization_method__in=[Partner.PROXY, Partner.BUNDLE],
        target_url=self.target_url,
    ).values_list("name", flat=True)
    # Exclude self from the filtered stream list, if the operation
    # is performed on Streams.
    if stream:
        duplicate_target_url_streams = duplicate_target_url_streams.exclude(pk=self.pk)

    partner_duplicates_count = duplicate_target_url_partners.count()
    stream_duplicates_count = duplicate_target_url_streams.count()

    if partner_duplicates_count != 0 or stream_duplicates_count != 0:
        validation_error_msg = (
            "No two or more partners/streams can have the same target url. "
            "The following partner(s)/stream(s) have the same target url: "
        )
        validation_error_msg_partners = "None"
        validation_error_msg_streams = "None"
        if partner_duplicates_count > 1:
            validation_error_msg_partners = ", ".join(duplicate_target_url_partners)
        elif partner_duplicates_count == 1:
            validation_error_msg_partners = duplicate_target_url_partners[0]
        if stream_duplicates_count > 1:
            validation_error_msg_streams = ", ".join(duplicate_target_url_streams)
        elif stream_duplicates_count == 1:
            validation_error_msg_streams = duplicate_target_url_streams[0]

        return (
            validation_error_msg
            + " Partner(s): "
            + validation_error_msg_partners
            + ". Stream(s): "
            + validation_error_msg_streams
            + "."
        )

    return None

def get_partner_description_json_schema():
    """
    JSON Schema for partner description translations
    """
    from TWLight.resources.models import Partner

    no_of_partners = Partner.objects.count()
    no_of_possible_descriptions = (
        no_of_partners * 2
    ) + 1  # The extra item is the metadata key

    JSON_SCHEMA_PARTNER_DESCRIPTION = {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "maxItems": no_of_possible_descriptions,
    }

    return JSON_SCHEMA_PARTNER_DESCRIPTION

def get_partner_description(
    language_code: str, partner_short_description_key: str, partner_description_key: str
):
    """
    Function that gets a partner's short description and description in the language
    set by the user. If the descriptions don't exist in that language, the default
    will be returned (English)

    Parameters
    ----------
    language_code: str
        The language code the user has selected on TWL's settings
    partner_short_description_key: str
        The partner short description key that should be found in a json file
    partner_description_key: str
        The partner description key that should be found in a json file
    Returns
    -------
    dict
    """
    descriptions = {}
    # Getting the default file in case the description does not exist in
    # the language file
    partner_default_descriptions_dict = _read_translation_file(
        "en", "partner_descriptions"
    )
    partner_descriptions_dict = _read_translation_file(
        language_code, "partner_descriptions"
    )

    descriptions["short_description"] = _get_any_description(
        partner_default_descriptions_dict,
        partner_descriptions_dict,
        partner_short_description_key,
    )

    descriptions["description"] = _get_any_description(
        partner_default_descriptions_dict,
        partner_descriptions_dict,
        partner_description_key,
    )

    return descriptions

def get_tag_names(language_code: str, tag_field: dict):
    """
    Function that gets a partner's tag in the user's preferred language.
    If the tags don't exist in that language, the default
    will be returned (English)

    Parameters
    ----------
    language_code: str
        The language code the user has selected on TWL's settings
    tag_field: dict
        The new_tags JSONField that contains the tag's names
    Returns
    -------
    dict
    """
    tag_names = {}
    tag_names_default = _read_translation_file("en", "tag_names")
    tag_names_lang = _read_translation_file(language_code, "tag_names")

    if tag_field:
        for tag in tag_field["tags"]:
            if tag in tag_names_lang:
                tag_names[tag] = tag_names_lang[tag]
            else:
                tag_names[tag] = tag_names_default[tag]

    return tag_names

def get_tag_choices():
    """
    Function that gets all the tags, preferably translated to the user's preferred
    language, otherwise the default language

    Parameters
    ----------

    Returns
    -------
    tuple
    """
    language_code = get_language()
    tag_choices = []
    tag_names_default = _read_translation_file("en", "tag_names")
    tag_names_lang = _read_translation_file(language_code, "tag_names")

    for tag_key, tag_value in tag_names_default.items():
        lang_keys = tag_names_lang.keys()
        if tag_key in lang_keys:
            tag_tuple = (tag_key, tag_names_lang[tag_key])
        else:
            tag_tuple = (tag_key, tag_value)

        tag_choices.append(tag_tuple)

    TAG_CHOICES = tuple(tag_choices)

    return TAG_CHOICES

def _read_translation_file(language_code: str, filename: str):
    """
    Reads a partner description file and returns a dictionary, if the file exists

    ----------
    language_code: str
        The language code the user has selected in their settings
    filename: str
        The name of the translation file you want to open (partner descriptions or tags)

    Returns
    -------
    dict
    """
    twlight_home = settings.TWLIGHT_HOME
    filepath = "{twlight_home}/locale/{language_code}/{filename}.json".format(
        twlight_home=twlight_home, language_code=language_code, filename=filename
    )
    if os.path.isfile(filepath):
        with open(filepath, "r") as translation_file:
            translation_dict = json.load(translation_file)

            # Remove the "@metadata" key from the dictionary
            if "@metadata" in translation_dict:
                translation_dict.pop("@metadata")
            return translation_dict
    else:
        return {}

def _get_any_description(
    partner_default_descriptions_dict: dict,
    partner_descriptions_dict: dict,
    partner_key: str,
):
    """
    Returns either the default partner description or the partner description in the
    user's language of choice

    Parameters
    ----------
    partner_default_descriptions_dict : dict
        The default descriptions dictionary.
    partner_descriptions_dict : dict
        The descriptions dictionary with descriptions in the user's preferred language
    partner_key: str
        The description key we are looking for

    Returns
    -------
    str or None
    """
    if partner_key in partner_descriptions_dict.keys():
        return partner_descriptions_dict[partner_key]
    elif partner_key in partner_default_descriptions_dict.keys():
        return partner_default_descriptions_dict[partner_key]
    else:
        return None

def get_tags_json_schema():
    """
    JSON Schema for tag names
    """
    tags_json = _read_translation_file("en", "tag_names")
    tag_keys = list(tags_json.keys())
    number_of_tags = len(tag_keys)
    JSON_SCHEMA_TAGS = {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
            "tags": {
                "$id": "#/properties/tags",
                "type": "array",
                "items": {
                    "$id": "#/properties/tags/items",
                    "enum": tag_keys,
                    "type": "string",
                    "examples": ["biology_tag", "military_tag"],
                },
                "maxItems": number_of_tags,
            }
        },
        "additionalProperties": False,
        "required": ["tags"],
    }

    return JSON_SCHEMA_TAGS
<commit_msg>add language_code argument to get_tag_choices method<commit_after>from django.conf import settings

import json
import os

def check_for_target_url_duplication_and_generate_error_message(
    self, partner=False, stream=False
):
    """
    Filter for partners/streams (PROXY and BUNDLE) where the
    target_url is the same as self. On filtering, if we have
    a non-zero number of matches, we generate the appropriate
    error message to be shown to the staff.

    :param self:
    :param partner:
    :param stream:
    :return:
    """
    from TWLight.resources.models import Partner, Stream

    duplicate_target_url_partners = Partner.objects.filter(
        authorization_method__in=[Partner.PROXY, Partner.BUNDLE],
        target_url=self.target_url,
    ).values_list("company_name", flat=True)
    # Exclude self from the filtered partner list, if the operation
    # is performed on Partners.
    if partner:
        duplicate_target_url_partners = duplicate_target_url_partners.exclude(
            pk=self.pk
        )

    duplicate_target_url_streams = Stream.objects.filter(
        authorization_method__in=[Partner.PROXY, Partner.BUNDLE],
        target_url=self.target_url,
    ).values_list("name", flat=True)
    # Exclude self from the filtered stream list, if the operation
    # is performed on Streams.
    if stream:
        duplicate_target_url_streams = duplicate_target_url_streams.exclude(pk=self.pk)

    partner_duplicates_count = duplicate_target_url_partners.count()
    stream_duplicates_count = duplicate_target_url_streams.count()

    if partner_duplicates_count != 0 or stream_duplicates_count != 0:
        validation_error_msg = (
            "No two or more partners/streams can have the same target url. "
            "The following partner(s)/stream(s) have the same target url: "
        )
        validation_error_msg_partners = "None"
        validation_error_msg_streams = "None"
        if partner_duplicates_count > 1:
            validation_error_msg_partners = ", ".join(duplicate_target_url_partners)
        elif partner_duplicates_count == 1:
            validation_error_msg_partners = duplicate_target_url_partners[0]
        if stream_duplicates_count > 1:
            validation_error_msg_streams = ", ".join(duplicate_target_url_streams)
        elif stream_duplicates_count == 1:
            validation_error_msg_streams = duplicate_target_url_streams[0]

        return (
            validation_error_msg
            + " Partner(s): "
            + validation_error_msg_partners
            + ". Stream(s): "
            + validation_error_msg_streams
            + "."
        )

    return None

def get_partner_description_json_schema():
    """
    JSON Schema for partner description translations
    """
    from TWLight.resources.models import Partner

    no_of_partners = Partner.objects.count()
    no_of_possible_descriptions = (
        no_of_partners * 2
    ) + 1  # The extra item is the metadata key

    JSON_SCHEMA_PARTNER_DESCRIPTION = {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "maxItems": no_of_possible_descriptions,
    }

    return JSON_SCHEMA_PARTNER_DESCRIPTION

def get_partner_description(
    language_code: str, partner_short_description_key: str, partner_description_key: str
):
    """
    Function that gets a partner's short description and description in the language
    set by the user. If the descriptions don't exist in that language, the default
    will be returned (English)

    Parameters
    ----------
    language_code: str
        The language code the user has selected on TWL's settings
    partner_short_description_key: str
        The partner short description key that should be found in a json file
    partner_description_key: str
        The partner description key that should be found in a json file
    Returns
    -------
    dict
    """
    descriptions = {}
    # Getting the default file in case the description does not exist in
    # the language file
    partner_default_descriptions_dict = _read_translation_file(
        "en", "partner_descriptions"
    )
    partner_descriptions_dict = _read_translation_file(
        language_code, "partner_descriptions"
    )

    descriptions["short_description"] = _get_any_description(
        partner_default_descriptions_dict,
        partner_descriptions_dict,
        partner_short_description_key,
    )

    descriptions["description"] = _get_any_description(
        partner_default_descriptions_dict,
        partner_descriptions_dict,
        partner_description_key,
    )

    return descriptions

def get_tag_names(language_code: str, tag_field: dict):
    """
    Function that gets a partner's tag in the user's preferred language.
    If the tags don't exist in that language, the default
    will be returned (English)

    Parameters
    ----------
    language_code: str
        The language code the user has selected on TWL's settings
    tag_field: dict
        The new_tags JSONField that contains the tag's names
    Returns
    -------
    dict
    """
    tag_names = {}
    tag_names_default = _read_translation_file("en", "tag_names")
    tag_names_lang = _read_translation_file(language_code, "tag_names")

    if tag_field:
        for tag in tag_field["tags"]:
            if tag in tag_names_lang:
                tag_names[tag] = tag_names_lang[tag]
            else:
                tag_names[tag] = tag_names_default[tag]

    return tag_names

def get_tag_choices(language_code: str="en"):
    """
    Function that gets all the tags, preferably translated to the user's preferred
    language, otherwise the default language

    Parameters
    ----------
    language_code: str
        The language code the user has selected on TWL's settings

    Returns
    -------
    tuple
    """
    tag_choices = []
    tag_names_default = _read_translation_file("en", "tag_names")
    tag_names_lang = _read_translation_file(language_code, "tag_names")

    for tag_key, tag_value in tag_names_default.items():
        lang_keys = tag_names_lang.keys()
        if tag_key in lang_keys:
            tag_tuple = (tag_key, tag_names_lang[tag_key])
        else:
            tag_tuple = (tag_key, tag_value)

        tag_choices.append(tag_tuple)

    TAG_CHOICES = tuple(tag_choices)

    return TAG_CHOICES

def _read_translation_file(language_code: str, filename: str):
    """
    Reads a partner description file and returns a dictionary, if the file exists

    ----------
    language_code: str
        The language code the user has selected in their settings
    filename: str
        The name of the translation file you want to open (partner descriptions or tags)

    Returns
    -------
    dict
    """
    twlight_home = settings.TWLIGHT_HOME
    filepath = "{twlight_home}/locale/{language_code}/{filename}.json".format(
        twlight_home=twlight_home, language_code=language_code, filename=filename
    )
    if os.path.isfile(filepath):
        with open(filepath, "r") as translation_file:
            translation_dict = json.load(translation_file)

            # Remove the "@metadata" key from the dictionary
            if "@metadata" in translation_dict:
                translation_dict.pop("@metadata")
            return translation_dict
    else:
        return {}

def _get_any_description(
    partner_default_descriptions_dict: dict,
    partner_descriptions_dict: dict,
    partner_key: str,
):
    """
    Returns either the default partner description or the partner description in the
    user's language of choice

    Parameters
    ----------
    partner_default_descriptions_dict : dict
        The default descriptions dictionary.
    partner_descriptions_dict : dict
        The descriptions dictionary with descriptions in the user's preferred language
    partner_key: str
        The description key we are looking for

    Returns
    -------
    str or None
    """
    if partner_key in partner_descriptions_dict.keys():
        return partner_descriptions_dict[partner_key]
    elif partner_key in partner_default_descriptions_dict.keys():
        return partner_default_descriptions_dict[partner_key]
    else:
        return None

def get_tags_json_schema():
    """
    JSON Schema for tag names
    """
    tags_json = _read_translation_file("en", "tag_names")
    tag_keys = list(tags_json.keys())
    number_of_tags = len(tag_keys)
    JSON_SCHEMA_TAGS = {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
            "tags": {
                "$id": "#/properties/tags",
                "type": "array",
                "items": {
                    "$id": "#/properties/tags/items",
                    "enum": tag_keys,
                    "type": "string",
                    "examples": ["biology_tag", "military_tag"],
                },
                "maxItems": number_of_tags,
            }
        },
        "additionalProperties": False,
        "required": ["tags"],
    }

    return JSON_SCHEMA_TAGS
<|endoftext|>


<commit_before>from flask import Flask, render_template
app = Flask(__name__)
app.debug = True

@app.route('/')
def index():
    return render_template("labs.html")

@app.route('/login')
def login():
    return render_template("login.html")

@app.route('/about')
def about():
    return render_template("about.html")

@app.after_request
def cors(response):
	response.headers['Access-Control-Allow-Origin'] = '*'
	return response

if __name__ == '__main__':
    app.run()
<commit_msg>Added forgotten configuration<commit_after>from flask import Flask, render_template
app = Flask(__name__)
app.debug = True

@app.route('/')
def index():
    return render_template("labs.html")

@app.route('/login')
def login():
    return render_template("login.html")

@app.route('/about')
def about():
    return render_template("about.html")

@app.after_request
def cors(response):
	response.headers['Access-Control-Allow-Origin'] = '*'
	return response

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
<|endoftext|>


<commit_before>import numpy as np
from astropy.cosmology import Planck13 as cosmo

#default parameters
h = cosmo.h
Om_M = cosmo.Om0
Om_L = 1. - Om_M

def bias(mass_halo, z_halo, h = h, Om_M = Om_M, Om_L = Om_L):
    """Return halo bias, from Seljak & Warren 2004."""
    M_nl_0 = (8.73/h) * 10.**12.         #nonlinear mass today [M_sun]
    M_nl = M_nl_0 * (Om_M + Om_L/((1.+z_halo)**3.))  #scaled to z_lens
    x = mass_halo/M_nl
    b = 0.53 + 0.39*(x**0.45) + 0.13/(40.*x + 1.) + (5.e-4)*(x**1.5)
    return b
<commit_msg>extend halobias docstring<commit_after>import numpy as np
from astropy.cosmology import Planck13 as cosmo

#default parameters
h = cosmo.h
Om_M = cosmo.Om0
Om_L = 1. - Om_M

def bias(mass_halo, z_halo, h = h, Om_M = Om_M, Om_L = Om_L):
    """Calculate halo bias, from Seljak & Warren 2004.

    Parameters
    ----------
    mass_halo : ndarray or float
        Halo mass to calculate bias for.
    z_halo : ndarray or float
        Halo z, same type and size as mass_halo.
    h : float, optional
        Hubble parameter, defaults to astropy.cosmology.Planck13.h
    Om_M : float, optional
        Fractional matter density, defaults to
        astropy.cosmology.Planck13.Om0
    Om_L : float, optional
        Fractional dark energy density, defaults to 1-Om_M.

    Returns
    ----------
    ndarray or float
        Returns the halo bias, of same type and size as input mass_halo and
        z_halo. Calculated according to Seljak & Warren 2004.
    """
    M_nl_0 = (8.73/h) * 10.**12.         #nonlinear mass today [M_sun]
    M_nl = M_nl_0 * (Om_M + Om_L/((1.+z_halo)**3.))  #scaled to z_lens
    x = mass_halo/M_nl
    b = 0.53 + 0.39*(x**0.45) + 0.13/(40.*x + 1.) + (5.e-4)*(x**1.5)
    return b
<|endoftext|>


<commit_before>"""server.py

The server script listens for client connections, logging performance data to server.log.  An arbitrary \
unused port is selected if not specified.

Usage:

python server.py [option]

Options and arguments:
-p         : server port to listen on
-c         : maximum concurrent client connections
--shutdown : attempt to shutdown a local server at the specified port
"""

from __future__ import print_function

import sys
import getopt
import os
import time
import socket
import threading
import SocketServer
import traceback

class RepeatingTimer(threading._Timer):
    def run(self):
        while True:
            self.finished.wait(self.interval)
            if (self.finished.is_set()): break
            self.function(*self.args, **self.kwargs)

class Server(SocketServer.ThreadingTCPServer):
    """Server(server_address, log = "server.log")

    Server is a SocketServer.ThreadingTCPServer.  Server implements the context
    manager interface and expects the __enter__() method to be called before
    starting the server with serve_forever().  The __exit__() method is also
    expected to be called after server_close() to release resources and cleanup.

    Aside from logging all client messages, Server will keep track of clients
    that send a START message, noting also the last time each client sent an
    ALIVE message.  After all tracked clients send a STOP message, or fail to
    send an ALIVE message within 10 seconds, Server will shut itself down.  The
    clients attribute contains lost clients after shut down.

    DATA messages are tracked, and each client's combined performance data is
    available in the data attribute.
    """

    def __init__(self, server_address, log = "server.log"):
        SocketServer.ThreadingTCPServer.__init__(self, server_address, Handler)
        self.log = log
        self.clients = {}
        self.data = {}
        self.lock = threading.Lock()
        self.datalock = threading.Lock()
        self.loglock = threading.Lock()
        self.heartbeattimer = RepeatingTimer(10.0, self.heartbeat)

    def logger(self, message):
        try:
            with self.loglock:
                message = ": ".join((time.strftime("%Y-%m-%d %H:%M:%S"), message))
                self.logfile.write(message)
                self.logfile.write("\n")

        except IOError:
            print(message)

    def heartbeat(self):
        with self.lock:
            t = time.time()
            # filter the clients that have not had an ALIVE message recently
            lost = {client for client, last in self.clients.iteritems() if ((t - last) > 10.0)}
            # if the filtered set is not all of the clients, don't shut down
            if (len(lost) < len(self.clients)): lost = set()

        # if all the clients are lost, we can shut down
        if (lost):
            self.shutdown()
            for client, pid in lost:
                self.logger(": ".join((client, pid, "LOST")))

    def __enter__(self):
        self.logfile = open(self.log, "a")
        self.heartbeattimer.start()
        return self

    def __exit__(self, type, value, traceback):
        self.server_close()
        self.heartbeattimer.cancel()
        self.heartbeattimer.join()
        self.logfile.close()
        return False

class Handler(SocketServer.StreamRequestHandler):
    def handle(self):
        server = self.server
        client = self.client_address[0]
        message = self.rfile.readline().strip()
        server.logger(": ".join((client, message)))
        tokens = [token.strip() for token in message.split(':')]
        client = (client, tokens[0])
        cmd = tokens[1] if (len(tokens) > 1) else None
        if ((cmd == "DATA") and (len(tokens) > 2)):
            # try to convert the payload to Python objects
            try:
                name, err, size, t, mbps = eval(tokens[2], {}, {})
                if (err is not None): raise ValueError(err)

            except:
                pass

            else:
                with server.datalock:
                    try:
                        data = server.data[client]

                    except KeyError:
                        pass

                    else:
                        # accumulate the data for this client
                        server.data[client] = (data[0] + 1, data[1], data[2] + size, data[3] + t)

        elif (cmd == "ALIVE"):
            with server.lock:
                if (client in server.clients):
                    server.clients[client] = time.time()

        elif ((cmd == "START") and (len(tokens) > 2)):
            # try to convert the payload to Python objects
            try:
                chunksize, maxsize = eval(tokens[2], {}, {})

            except:
                pass

            else:
                # start tracking this client
                with server.lock:
                    server.clients[client] = time.time()

                with server.datalock:
                    server.data[client] = (0, chunksize, 0, 0.0)

        elif (cmd == "STOP"):
            # stop tracking this client, shutdown if all clients are done
            with server.lock:
                server.clients.pop(client, None)
                shutdown = not server.clients

            if (shutdown): server.shutdown()

        elif (cmd == "SHUTDOWN"):
            server.shutdown()

def shutdown(server_address):
    """shutdown(server_address)

    Send a SHUTDOWN message to the given server.
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.connect(server_address)
        sock.sendall(": ".join((str(os.getpid()), "SHUTDOWN")))

    finally:
        sock.close()

    return 0

def main(argv):
    host = "localhost"
    port = 0
    stop = False

    try:
        opts, args = getopt.getopt(argv[1:], "hp:c:", ["help", "shutdown"])

        for o, a in opts:
            if (o == "-p"):
                port = int(a)

            elif (o == "-c"):
                Server.request_queue_size = int(a)

            elif (o == "--shutdown"):
                stop = True

            elif (o in ("-h", "--help")):
                print(main.__doc__)
                return 2

            else:
                raise getopt.GetoptError("option {} not recognized".format(o), o)

    except (getopt.GetoptError, ValueError, TypeError) as e:
        print(main.__doc__)
        for line in traceback.format_exception_only(type(e), e): print(line, end = '', file = sys.stderr)
        return 2

    if (stop):
        return shutdown((host, port))

    with Server((host, port)) as server:
        print("{} listening on port {}".format(*server.server_address))
        print("Up to {} concurrent client connections supported".format(server.request_queue_size))
        sys.stdout.flush()    # make sure this gets output in case, I don't know, a test or something needs it
        server.serve_forever()
        if (server.clients):
            print("{:<22}{:<17}".format(
                "Lost",
                "Last Seen",
            ))
            for (client, pid), last in server.clients.iteritems():
                print("{:<22}{:<17}".format(
                    ":".join((client, pid)),
                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last)),
                ))

        print("{:<22}{:<6}{:<12}{:<14}{:<10}{:<10}".format(
            "Data",
            "Files",
            "Chunk",
            "Written",
            "Time",
            "MBps",
        ))
        if (server.data):
            for (client, pid), (files, chunksize, bytes, t) in server.data.iteritems():
                print("{:<22}{:<6}{:<12}{:<14}{:<10.3f}{:<10.3f}".format(
                    ":".join((client, pid)),
                    files,
                    chunksize,
                    bytes,
                    t,
                    0.0 if (t == 0.0) else ((bytes / t) / 1024**2),
                ))

        else:
            print("No data collected")

    return 0

main.__doc__ = __doc__

if (__name__ == "__main__"):
    sys.exit(main(sys.argv))
<commit_msg>don't split message payload<commit_after>"""server.py

The server script listens for client connections, logging performance data to server.log.  An arbitrary \
unused port is selected if not specified.

Usage:

python server.py [option]

Options and arguments:
-p         : server port to listen on
-c         : maximum concurrent client connections
--shutdown : attempt to shutdown a local server at the specified port
"""

from __future__ import print_function

import sys
import getopt
import os
import time
import socket
import threading
import SocketServer
import traceback

class RepeatingTimer(threading._Timer):
    def run(self):
        while True:
            self.finished.wait(self.interval)
            if (self.finished.is_set()): break
            self.function(*self.args, **self.kwargs)

class Server(SocketServer.ThreadingTCPServer):
    """Server(server_address, log = "server.log")

    Server is a SocketServer.ThreadingTCPServer.  Server implements the context
    manager interface and expects the __enter__() method to be called before
    starting the server with serve_forever().  The __exit__() method is also
    expected to be called after server_close() to release resources and cleanup.

    Aside from logging all client messages, Server will keep track of clients
    that send a START message, noting also the last time each client sent an
    ALIVE message.  After all tracked clients send a STOP message, or fail to
    send an ALIVE message within 10 seconds, Server will shut itself down.  The
    clients attribute contains lost clients after shut down.

    DATA messages are tracked, and each client's combined performance data is
    available in the data attribute.
    """

    def __init__(self, server_address, log = "server.log"):
        SocketServer.ThreadingTCPServer.__init__(self, server_address, Handler)
        self.log = log
        self.clients = {}
        self.data = {}
        self.lock = threading.Lock()
        self.datalock = threading.Lock()
        self.loglock = threading.Lock()
        self.heartbeattimer = RepeatingTimer(10.0, self.heartbeat)

    def logger(self, message):
        try:
            with self.loglock:
                message = ": ".join((time.strftime("%Y-%m-%d %H:%M:%S"), message))
                self.logfile.write(message)
                self.logfile.write("\n")

        except IOError:
            print(message)

    def heartbeat(self):
        with self.lock:
            t = time.time()
            # filter the clients that have not had an ALIVE message recently
            lost = {client for client, last in self.clients.iteritems() if ((t - last) > 10.0)}
            # if the filtered set is not all of the clients, don't shut down
            if (len(lost) < len(self.clients)): lost = set()

        # if all the clients are lost, we can shut down
        if (lost):
            self.shutdown()
            for client, pid in lost:
                self.logger(": ".join((client, pid, "LOST")))

    def __enter__(self):
        self.logfile = open(self.log, "a")
        self.heartbeattimer.start()
        return self

    def __exit__(self, type, value, traceback):
        self.server_close()
        self.heartbeattimer.cancel()
        self.heartbeattimer.join()
        self.logfile.close()
        return False

class Handler(SocketServer.StreamRequestHandler):
    def handle(self):
        server = self.server
        client = self.client_address[0]
        message = self.rfile.readline().strip()
        server.logger(": ".join((client, message)))
        tokens = [token.strip() for token in message.split(':', 2)]
        client = (client, tokens[0])
        cmd = tokens[1] if (len(tokens) > 1) else None
        if ((cmd == "DATA") and (len(tokens) > 2)):
            # try to convert the payload to Python objects
            try:
                name, err, size, t, mbps = eval(tokens[2], {}, {})
                if (err is not None): raise ValueError(err)

            except:
                pass

            else:
                with server.datalock:
                    try:
                        data = server.data[client]

                    except KeyError:
                        pass

                    else:
                        # accumulate the data for this client
                        server.data[client] = (data[0] + 1, data[1], data[2] + size, data[3] + t)

        elif (cmd == "ALIVE"):
            with server.lock:
                if (client in server.clients):
                    server.clients[client] = time.time()

        elif ((cmd == "START") and (len(tokens) > 2)):
            # try to convert the payload to Python objects
            try:
                chunksize, maxsize = eval(tokens[2], {}, {})

            except:
                pass

            else:
                # start tracking this client
                with server.lock:
                    server.clients[client] = time.time()

                with server.datalock:
                    server.data[client] = (0, chunksize, 0, 0.0)

        elif (cmd == "STOP"):
            # stop tracking this client, shutdown if all clients are done
            with server.lock:
                server.clients.pop(client, None)
                shutdown = not server.clients

            if (shutdown): server.shutdown()

        elif (cmd == "SHUTDOWN"):
            server.shutdown()

def shutdown(server_address):
    """shutdown(server_address)

    Send a SHUTDOWN message to the given server.
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.connect(server_address)
        sock.sendall(": ".join((str(os.getpid()), "SHUTDOWN")))

    finally:
        sock.close()

    return 0

def main(argv):
    host = "localhost"
    port = 0
    stop = False

    try:
        opts, args = getopt.getopt(argv[1:], "hp:c:", ["help", "shutdown"])

        for o, a in opts:
            if (o == "-p"):
                port = int(a)

            elif (o == "-c"):
                Server.request_queue_size = int(a)

            elif (o == "--shutdown"):
                stop = True

            elif (o in ("-h", "--help")):
                print(main.__doc__)
                return 2

            else:
                raise getopt.GetoptError("option {} not recognized".format(o), o)

    except (getopt.GetoptError, ValueError, TypeError) as e:
        print(main.__doc__)
        for line in traceback.format_exception_only(type(e), e): print(line, end = '', file = sys.stderr)
        return 2

    if (stop):
        return shutdown((host, port))

    with Server((host, port)) as server:
        print("{} listening on port {}".format(*server.server_address))
        print("Up to {} concurrent client connections supported".format(server.request_queue_size))
        sys.stdout.flush()    # make sure this gets output in case, I don't know, a test or something needs it
        server.serve_forever()
        if (server.clients):
            print("{:<22}{:<17}".format(
                "Lost",
                "Last Seen",
            ))
            for (client, pid), last in server.clients.iteritems():
                print("{:<22}{:<17}".format(
                    ":".join((client, pid)),
                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last)),
                ))

        print("{:<22}{:<6}{:<12}{:<14}{:<10}{:<10}".format(
            "Data",
            "Files",
            "Chunk",
            "Written",
            "Time",
            "MBps",
        ))
        if (server.data):
            for (client, pid), (files, chunksize, bytes, t) in server.data.iteritems():
                print("{:<22}{:<6}{:<12}{:<14}{:<10.3f}{:<10.3f}".format(
                    ":".join((client, pid)),
                    files,
                    chunksize,
                    bytes,
                    t,
                    0.0 if (t == 0.0) else ((bytes / t) / 1024**2),
                ))

        else:
            print("No data collected")

    return 0

main.__doc__ = __doc__

if (__name__ == "__main__"):
    sys.exit(main(sys.argv))
<|endoftext|>