<commit_before># Copyright 2013 Novo Nordisk Foundation Center for Biosustainability, DTU.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import, print_function

import six
from six.moves import range

import re
from collections import OrderedDict
from uuid import uuid1
from time import time
from datetime import datetime
import colorsys
import pip
import platform
from itertools import islice
from functools import partial

import progressbar
from numpy.random import RandomState

import logging
logger = logging.getLogger(__name__)

class ModelFacade(object):

    def __init__(self, id=id, *args, **kwargs):
        self._id = id
        self._model = None

    def _load_model(self):
        raise NotImplementedError("You forgot to implement this method!")

    @property
    def model(self):
        if self._model is None:
            self._model = self._load_model()
        return self._model

    def __getattr__(self, value):
        try:
            return getattr(self.model, value)
        except AttributeError:
            return getattr(super(ModelFacade, self), value, self)

    def __dir__(self):
        return dir(self.model)

    def __setattr__(self, key, value):
        if '_model' in self.__dict__ and not self._model is None:
            setattr(self.model, key, value)
        else:
            self.__dict__[key] = value

class ProblemCache(object):
    def __init__(self, model):
        self.time_machine = None
        self._model = model
        self.variables = {}
        self.constraints = {}
        self.original_objective = model.objective.expression
        self.time_machine = TimeMachine()
        self.transaction_id = None

    def begin_transaction(self):
        self.transaction_id = uuid1()
        self.time_machine(do=int, undo=int, bookmark=self.transaction_id)

    @property
    def model(self):
        return self._model

    def _rebuild_constraint(self, constraint):
        (expression, lb, ub, name) = constraint.expression, constraint.lb, constraint.ub, constraint.name

        def rebuild():
            self.model.solver._remove_constraint(constraint)
            new_constraint = self.model.solver.interface.Constraint(expression, lb=lb, ub=ub, name=name)
            self.constraints[name] = new_constraint
            self.model.solver._add_constraint(new_constraint, sloppy=True)

        return rebuild

    def _append_constraint(self, constraint_id, create, *args, **kwargs):
        self.constraints[constraint_id] = create(self.model, constraint_id, *args, **kwargs)
        self.model.solver._add_constraint(self.constraints[constraint_id])

    def _remove_constraint(self, constraint_id):
        constraint = self.constraints.pop(constraint_id)
        self.model.solver._remove_constraint(constraint)

    def _append_variable(self, variable_id, create, *args, **kwargs):
        self.variables[variable_id] = create(self.model, variable_id, *args, **kwargs)
        self.model.solver._add_variable(self.variables[variable_id])

    def _remove_variable(self, variable_id):
        variable = self.variables.pop(variable_id)
        self.model.solver._remove_variable(variable)

    def _rebuild_variable(self, variable):
        (type, lb, ub, name) = variable.type, variable.lb, variable.ub, variable.name

        def rebuild():
            self.model.solver._remove_variable(variable)
            new_variable = self.model.solver.interface.Variable(name, lb=lb, ub=ub, type=type)
            self.variables[name] = variable
            self.model.solver._add_variable(new_variable, sloppy=True)

        return rebuild

    def add_constraint(self, constraint_id, create, update, *args, **kwargs):
        if constraint_id in self.constraints:
            if update is not None:
                self.time_machine(
                    do=partial(update, self.model, self.constraints[constraint_id], *args, **kwargs),
                    undo=self._rebuild_constraint(self.constraints[constraint_id]))
        else:
            self.time_machine(
                do=partial(self._append_constraint, constraint_id, create, *args, **kwargs),
                undo=partial(self._remove_constraint, constraint_id)
            )

    def add_variable(self, variable_id, create, update, *args, **kwargs):
        if variable_id in self.variables:
            if update is not None:
                self.time_machine(
                    do=partial(update, self.model, self.variables[variable_id], *args, **kwargs),
                    undo=self._rebuild_variable(self.variables[variable_id]))
        else:
            self.time_machine(
                do=partial(self._append_variable, variable_id, create, *args, **kwargs),
                undo=partial(self._remove_variable, variable_id)
            )

    def reset(self):
        self.model.solver._remove_constraints(self.constraints.values())
        self.model.solver._remove_variables(self.variables.values())
        self.model.objective = self.original_objective
        self.variables = {}
        self.constraints = {}
        self.transaction_id = None
        self.time_machine.history.clear()

    def rollback(self):
        if self.transaction_id is None:
            raise RuntimeError("Start transaction must be called before rollback")
        self.time_machine.undo(self.transaction_id)
        self.transaction_id = None

class RandomGenerator():
    def __init__(self, seed=None):
        self._random = RandomState(seed=seed)

    def random(self):
        return self._random.rand()

    def randint(self, a, b=None):
        if b is None:
            b = a
            a = 0
        return self._random.randint(a, b)

    def sample(self, population, k):
        if k == 0:
            return []
        return self._random.choice(population, size=k, replace=True)

    def __getattr__(self, attr):
        return getattr(self._random, attr)

    def __getstate__(self):
        return {'_random': self._random}

    def __setstate__(self, d):
        self._random = d['_random']

class Singleton(object):
    """
    Singleton class to be extended
    """
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

class AutoVivification(dict):

    """Implementation of perl's autovivification feature. Checkout http://stackoverflow.com/a/652284/280182"""

    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

class TimeMachine(object):

    """Travel back and forth in time."""

    def __init__(self):
        super(TimeMachine, self).__init__()
        self.history = OrderedDict()

    def __call__(self, do=None, undo=None, bookmark=None):
        output = do()
        current_time = time()
        if bookmark is None:
            entry_id = uuid1()
        else:
            entry_id = bookmark
        # make sure that entry is added to the end of history
        self.history.pop(entry_id, None)
        self.history[entry_id] = {'unix_epoch':
                                  current_time, 'undo': undo, 'redo': do}
        return entry_id, output

    def __str__(self):
        info = '\n'
        for item in six.iteritems(self.history):
            info += self._history_item_to_str(item)
        return info

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.reset()

    @staticmethod
    def _history_item_to_str(item):
        info = ''
        uuid, entry = item
        info += datetime.fromtimestamp(entry['unix_epoch']).strftime('%Y-%m-%d %H:%M:%S') + '\n'
        undo_entry = entry['undo']
        try:
            elements = undo_entry.func, undo_entry.args, undo_entry.keywords  # partial
            info += 'undo: ' + ' '.join([str(elem) for elem in elements]) + '\n'
        except AttributeError:  # normal python function
            info += 'undo: ' + undo_entry.__name__ + '\n'

        redo_entry = entry['redo']
        try:
            elements = redo_entry.func, redo_entry.args, redo_entry.keywords  # partial
            info += 'redo: ' + ' '.join([str(elem) for elem in elements]) + '\n'
        except AttributeError:
            info += 'redo: ' + redo_entry.__name__ + '\n'
        return info

    def undo(self, bookmark=None):
        if bookmark is None:
            try:
                (uuid, entry) = self.history.popitem()
                entry['undo']()
            except KeyError:  # history is empty
                pass
        elif bookmark in list(self.history.keys()):
            uuid = False
            while uuid is not bookmark:
                (uuid, entry) = self.history.popitem()
                entry['undo']()
        else:
            raise Exception(
                'Provided bookmark %s cannot be found in the time machine.')

    def redo(self):
        raise NotImplementedError

    def reset(self):
        if self.history:  # history is not empty
            self.undo(bookmark=list(self.history.keys())[0])

class Timer(object):
    """Taken from http://stackoverflow.com/a/5849861/280182"""

    def __init__(self, name=None):
        self.name = name

    def __enter__(self):
        self.tstart = time()

    def __exit__(self, type, value, traceback):
        if self.name:
            print('[%s]' % self.name, end=' ')
        print('Elapsed: %s' % (time() - self.tstart))

class IntelliContainer(object):
    def __init__(self, **kwargs):
        self._dict = dict(**kwargs)

    def __getattr__(self, value):
        return self._dict.get(value)

    def __setitem__(self, key, value):
        self._dict[key] = value

    def __iter__(self):
        return six.itervalues(self._dict)

    def __dir__(self):
        return list(self._dict.keys())

class DisplayItemsWidget(progressbar.widgets.Widget):
    """Display an items[pbar.currval]

    Examples
    --------
    import time
    from progressbar import Progressbar, widges
    pbar = ProgressBar(widgets=[DisplayItemsWidget(["asdf"+str(i) for i in range(10)]), widgets.Bar()])
    pbar.maxval = 10
    pbar.start()
    for i in range(10):
        time.sleep(.2)
        pbar.update(i)
    pbar.finish()
    """

    def __init__(self, items):
        self.items = items

    def update(self, pbar):
        try:
            return "%s" % self.items[pbar.currval]
        except IndexError:
            return ""

def partition_(lst, n):
    """Partition a list into n bite size chunks."""
    division = len(lst) / float(n)
    return [lst[int(round(division * i)): int(round(division * (i + 1)))] for i in range(n)]

def partition(ite, n):
    """Partition an iterable into n bite size chunks."""
    try:
        length = len(ite)
    except TypeError:
        ite = list(ite)
        length = len(ite)
    division = length / float(n)
    iterator = iter(ite)
    return [list(islice(iterator, 0, round(division * (i + 1)) - round(division * i))) for i in range(n)]

def flatten(l):
    return [item for sublist in l for item in sublist]

def generate_colors(n):
    hsv_tuples = [(v*1.0/n, 0.5, 0.5) for v in range(n)]
    color_map = {}
    for i in range(n):
        rgb = colorsys.hsv_to_rgb(*hsv_tuples[i])
        color = tuple([rgb[0]*256, rgb[1]*256, rgb[2]*256])
        color_map[i] = '#%02x%02x%02x' % color
    return color_map

def memoize(function, memo={}):
    def wrapper(*args):
        logger.debug("key = %s" % str(args))
        if args in memo:
            logger.debug("Key found")
            return memo[args]
        else:
            logger.debug("Key not found")
            rv = function(*args)
            memo[args] = rv
            return rv
    return wrapper

def get_system_info():
    # pip freeze (adapted from http://stackoverflow.com/a/24322465/280182)
    package_info = list()
    for dist in pip.get_installed_distributions():
        req = str(dist.as_requirement())
        package_info.append(req)
    return dict(package_info=package_info,
                platform=platform.platform(),
                machine=platform.machine(),
                system=platform.system())

def in_ipnb():
    """
    Check if it is running inside an IPython Notebook (updated for new notebooks)
    """
    try:
        import IPython
        ip = IPython.get_ipython()

        front_end = None
        if "IPKernelApp" in ip.config:
            front_end = ip.config.get('IPKernelApp').get("parent_appname")
        elif "KernelApp" in ip.config:
            front_end = ip.config.get('KernelApp').get("parent_appname")

        if isinstance(front_end, IPython.config.loader.LazyConfigValue) or front_end is None:
            if isinstance(ip, IPython.kernel.zmq.zmqshell.ZMQInteractiveShell):
                return True
            else:
                return False
        elif isinstance(front_end, six.string_types):
            if 'ipython-notebook' in front_end.lower():
                return True
            elif 'notebook' in front_end.lower():
                return True
    except Exception as e:
        logger.debug("Cannot determine if running a notebook because of %s" % e)
        return False
    return False

def str_to_valid_variable_name(s):
    """Adapted from http://stackoverflow.com/a/3303361/280182"""

    # Remove invalid characters
    s = re.sub('[^0-9a-zA-Z_]', '_', s)

    # Remove leading characters until we find a letter or underscore
    s = re.sub('^[^a-zA-Z_]+', '', s)

    return s<commit_msg>Bug fix: do not replace on choice<commit_after># Copyright 2013 Novo Nordisk Foundation Center for Biosustainability, DTU.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import, print_function

import six
from six.moves import range

import re
from collections import OrderedDict
from uuid import uuid1
from time import time
from datetime import datetime
import colorsys
import pip
import platform
from itertools import islice
from functools import partial

import progressbar
from numpy.random import RandomState

import logging
logger = logging.getLogger(__name__)

class ModelFacade(object):

    def __init__(self, id=id, *args, **kwargs):
        self._id = id
        self._model = None

    def _load_model(self):
        raise NotImplementedError("You forgot to implement this method!")

    @property
    def model(self):
        if self._model is None:
            self._model = self._load_model()
        return self._model

    def __getattr__(self, value):
        try:
            return getattr(self.model, value)
        except AttributeError:
            return getattr(super(ModelFacade, self), value, self)

    def __dir__(self):
        return dir(self.model)

    def __setattr__(self, key, value):
        if '_model' in self.__dict__ and not self._model is None:
            setattr(self.model, key, value)
        else:
            self.__dict__[key] = value

class ProblemCache(object):
    def __init__(self, model):
        self.time_machine = None
        self._model = model
        self.variables = {}
        self.constraints = {}
        self.original_objective = model.objective.expression
        self.time_machine = TimeMachine()
        self.transaction_id = None

    def begin_transaction(self):
        self.transaction_id = uuid1()
        self.time_machine(do=int, undo=int, bookmark=self.transaction_id)

    @property
    def model(self):
        return self._model

    def _rebuild_constraint(self, constraint):
        (expression, lb, ub, name) = constraint.expression, constraint.lb, constraint.ub, constraint.name

        def rebuild():
            self.model.solver._remove_constraint(constraint)
            new_constraint = self.model.solver.interface.Constraint(expression, lb=lb, ub=ub, name=name)
            self.constraints[name] = new_constraint
            self.model.solver._add_constraint(new_constraint, sloppy=True)

        return rebuild

    def _append_constraint(self, constraint_id, create, *args, **kwargs):
        self.constraints[constraint_id] = create(self.model, constraint_id, *args, **kwargs)
        self.model.solver._add_constraint(self.constraints[constraint_id])

    def _remove_constraint(self, constraint_id):
        constraint = self.constraints.pop(constraint_id)
        self.model.solver._remove_constraint(constraint)

    def _append_variable(self, variable_id, create, *args, **kwargs):
        self.variables[variable_id] = create(self.model, variable_id, *args, **kwargs)
        self.model.solver._add_variable(self.variables[variable_id])

    def _remove_variable(self, variable_id):
        variable = self.variables.pop(variable_id)
        self.model.solver._remove_variable(variable)

    def _rebuild_variable(self, variable):
        (type, lb, ub, name) = variable.type, variable.lb, variable.ub, variable.name

        def rebuild():
            self.model.solver._remove_variable(variable)
            new_variable = self.model.solver.interface.Variable(name, lb=lb, ub=ub, type=type)
            self.variables[name] = variable
            self.model.solver._add_variable(new_variable, sloppy=True)

        return rebuild

    def add_constraint(self, constraint_id, create, update, *args, **kwargs):
        if constraint_id in self.constraints:
            if update is not None:
                self.time_machine(
                    do=partial(update, self.model, self.constraints[constraint_id], *args, **kwargs),
                    undo=self._rebuild_constraint(self.constraints[constraint_id]))
        else:
            self.time_machine(
                do=partial(self._append_constraint, constraint_id, create, *args, **kwargs),
                undo=partial(self._remove_constraint, constraint_id)
            )

    def add_variable(self, variable_id, create, update, *args, **kwargs):
        if variable_id in self.variables:
            if update is not None:
                self.time_machine(
                    do=partial(update, self.model, self.variables[variable_id], *args, **kwargs),
                    undo=self._rebuild_variable(self.variables[variable_id]))
        else:
            self.time_machine(
                do=partial(self._append_variable, variable_id, create, *args, **kwargs),
                undo=partial(self._remove_variable, variable_id)
            )

    def reset(self):
        self.model.solver._remove_constraints(self.constraints.values())
        self.model.solver._remove_variables(self.variables.values())
        self.model.objective = self.original_objective
        self.variables = {}
        self.constraints = {}
        self.transaction_id = None
        self.time_machine.history.clear()

    def rollback(self):
        if self.transaction_id is None:
            raise RuntimeError("Start transaction must be called before rollback")
        self.time_machine.undo(self.transaction_id)
        self.transaction_id = None

class RandomGenerator():
    def __init__(self, seed=None):
        self._random = RandomState(seed=seed)

    def random(self):
        return self._random.rand()

    def randint(self, a, b=None):
        if b is None:
            b = a
            a = 0
        return self._random.randint(a, b)

    def sample(self, population, k):
        if k == 0:
            return []
        return self._random.choice(population, size=k, replace=False)

    def __getattr__(self, attr):
        return getattr(self._random, attr)

    def __getstate__(self):
        return {'_random': self._random}

    def __setstate__(self, d):
        self._random = d['_random']

class Singleton(object):
    """
    Singleton class to be extended
    """
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

class AutoVivification(dict):

    """Implementation of perl's autovivification feature. Checkout http://stackoverflow.com/a/652284/280182"""

    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

class TimeMachine(object):

    """Travel back and forth in time."""

    def __init__(self):
        super(TimeMachine, self).__init__()
        self.history = OrderedDict()

    def __call__(self, do=None, undo=None, bookmark=None):
        output = do()
        current_time = time()
        if bookmark is None:
            entry_id = uuid1()
        else:
            entry_id = bookmark
        # make sure that entry is added to the end of history
        self.history.pop(entry_id, None)
        self.history[entry_id] = {'unix_epoch':
                                  current_time, 'undo': undo, 'redo': do}
        return entry_id, output

    def __str__(self):
        info = '\n'
        for item in six.iteritems(self.history):
            info += self._history_item_to_str(item)
        return info

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.reset()

    @staticmethod
    def _history_item_to_str(item):
        info = ''
        uuid, entry = item
        info += datetime.fromtimestamp(entry['unix_epoch']).strftime('%Y-%m-%d %H:%M:%S') + '\n'
        undo_entry = entry['undo']
        try:
            elements = undo_entry.func, undo_entry.args, undo_entry.keywords  # partial
            info += 'undo: ' + ' '.join([str(elem) for elem in elements]) + '\n'
        except AttributeError:  # normal python function
            info += 'undo: ' + undo_entry.__name__ + '\n'

        redo_entry = entry['redo']
        try:
            elements = redo_entry.func, redo_entry.args, redo_entry.keywords  # partial
            info += 'redo: ' + ' '.join([str(elem) for elem in elements]) + '\n'
        except AttributeError:
            info += 'redo: ' + redo_entry.__name__ + '\n'
        return info

    def undo(self, bookmark=None):
        if bookmark is None:
            try:
                (uuid, entry) = self.history.popitem()
                entry['undo']()
            except KeyError:  # history is empty
                pass
        elif bookmark in list(self.history.keys()):
            uuid = False
            while uuid is not bookmark:
                (uuid, entry) = self.history.popitem()
                entry['undo']()
        else:
            raise Exception(
                'Provided bookmark %s cannot be found in the time machine.')

    def redo(self):
        raise NotImplementedError

    def reset(self):
        if self.history:  # history is not empty
            self.undo(bookmark=list(self.history.keys())[0])

class Timer(object):
    """Taken from http://stackoverflow.com/a/5849861/280182"""

    def __init__(self, name=None):
        self.name = name

    def __enter__(self):
        self.tstart = time()

    def __exit__(self, type, value, traceback):
        if self.name:
            print('[%s]' % self.name, end=' ')
        print('Elapsed: %s' % (time() - self.tstart))

class IntelliContainer(object):
    def __init__(self, **kwargs):
        self._dict = dict(**kwargs)

    def __getattr__(self, value):
        return self._dict.get(value)

    def __setitem__(self, key, value):
        self._dict[key] = value

    def __iter__(self):
        return six.itervalues(self._dict)

    def __dir__(self):
        return list(self._dict.keys())

class DisplayItemsWidget(progressbar.widgets.Widget):
    """Display an items[pbar.currval]

    Examples
    --------
    import time
    from progressbar import Progressbar, widges
    pbar = ProgressBar(widgets=[DisplayItemsWidget(["asdf"+str(i) for i in range(10)]), widgets.Bar()])
    pbar.maxval = 10
    pbar.start()
    for i in range(10):
        time.sleep(.2)
        pbar.update(i)
    pbar.finish()
    """

    def __init__(self, items):
        self.items = items

    def update(self, pbar):
        try:
            return "%s" % self.items[pbar.currval]
        except IndexError:
            return ""

def partition_(lst, n):
    """Partition a list into n bite size chunks."""
    division = len(lst) / float(n)
    return [lst[int(round(division * i)): int(round(division * (i + 1)))] for i in range(n)]

def partition(ite, n):
    """Partition an iterable into n bite size chunks."""
    try:
        length = len(ite)
    except TypeError:
        ite = list(ite)
        length = len(ite)
    division = length / float(n)
    iterator = iter(ite)
    return [list(islice(iterator, 0, round(division * (i + 1)) - round(division * i))) for i in range(n)]

def flatten(l):
    return [item for sublist in l for item in sublist]

def generate_colors(n):
    hsv_tuples = [(v*1.0/n, 0.5, 0.5) for v in range(n)]
    color_map = {}
    for i in range(n):
        rgb = colorsys.hsv_to_rgb(*hsv_tuples[i])
        color = tuple([rgb[0]*256, rgb[1]*256, rgb[2]*256])
        color_map[i] = '#%02x%02x%02x' % color
    return color_map

def memoize(function, memo={}):
    def wrapper(*args):
        logger.debug("key = %s" % str(args))
        if args in memo:
            logger.debug("Key found")
            return memo[args]
        else:
            logger.debug("Key not found")
            rv = function(*args)
            memo[args] = rv
            return rv
    return wrapper

def get_system_info():
    # pip freeze (adapted from http://stackoverflow.com/a/24322465/280182)
    package_info = list()
    for dist in pip.get_installed_distributions():
        req = str(dist.as_requirement())
        package_info.append(req)
    return dict(package_info=package_info,
                platform=platform.platform(),
                machine=platform.machine(),
                system=platform.system())

def in_ipnb():
    """
    Check if it is running inside an IPython Notebook (updated for new notebooks)
    """
    try:
        import IPython
        ip = IPython.get_ipython()

        front_end = None
        if "IPKernelApp" in ip.config:
            front_end = ip.config.get('IPKernelApp').get("parent_appname")
        elif "KernelApp" in ip.config:
            front_end = ip.config.get('KernelApp').get("parent_appname")

        if isinstance(front_end, IPython.config.loader.LazyConfigValue) or front_end is None:
            if isinstance(ip, IPython.kernel.zmq.zmqshell.ZMQInteractiveShell):
                return True
            else:
                return False
        elif isinstance(front_end, six.string_types):
            if 'ipython-notebook' in front_end.lower():
                return True
            elif 'notebook' in front_end.lower():
                return True
    except Exception as e:
        logger.debug("Cannot determine if running a notebook because of %s" % e)
        return False
    return False

def str_to_valid_variable_name(s):
    """Adapted from http://stackoverflow.com/a/3303361/280182"""

    # Remove invalid characters
    s = re.sub('[^0-9a-zA-Z_]', '_', s)

    # Remove leading characters until we find a letter or underscore
    s = re.sub('^[^a-zA-Z_]+', '', s)

    return s<|endoftext|>


<commit_before>_____________________________________________________________________________________________________

import io

def write_video(stream):
	print "Writing video!"
	with stream.lock:
		# Find the first header frame in the video
		for frame in stream.frames:
			if frame.frame_type == picamera.PiVideoFrameType.sps_header:
				stream.seek(frame.position)
				break
		# Write the rest of the stream to disk (write binary)
		with io.open('/var/www/vids/vidstream.h264', 'wb') as output:
			output.write(stream.read())

stream = picamera.PiCameraCircularIO(camera, seconds=2)
camera.start_recording(stream, format='h264')
try:
	while True:
		camera.wait_recording(1)
		if write_now():
			# write the stream to disk
			write_video(stream)
finally:
	camera.stop_recording()
<commit_msg>Continue integration<commit_after>#Imports
import picamera
from picamera import PiCamera
import time
from datetime import datetime
import os.path
import io
import re

#Functions
#--exit if (y/n) input field
def reYN():
	try:
		if not re.match("^y$)|(", input_str):
			 quit()
	except:
		print "Error: Invalid Input"
#About
print "\nSecurity Camera Logger v4 | Ben Broce & William Hampton\n\n"
print "Streams video to ../vids/vidstream.h264 | Captures to ../pics/[timestamp].jpg"
print "Ctrl-C quits.\n\n"

#Defines
camera = PiCamera()
counter = 0

#Session Config
#--check which functions to enable
Preview = raw_input("Should I display locally (y/n)? ")
streamVid = raw_input("Should I stream video (y/n)? ")
streamPic = raw_input("Should I take pictures (y/n)? ")
#--exit if pics and video both off
try:
	if Preview=="n" and streamVid=="n" and streamPic=="n":
		quit()
except:
	print "Error: No Functions Enabled"

length = float(raw_input("How long should I run (in minutes): "))*60
if streamPic == "y":
	interval = float(raw_input("How often should I take a picture (in seconds): "))

camera.rotation = 180
camera.resolution = (640, 480)
camera.annotate_background = picamera.Color('black')
stream = picamera.PiCameraCircularIO(camera, seconds=2)

#Begin
print "Running..."

try:
	camera.start_preview()
	if streamVid == "y":
		camera.start_recording('/var/www/vids/vidstream.h264')
	while (counter <= length):
		timestamp = datetime.now().strftime("%m-%d-%Y_%H:%M:%S")
		camera.annotate_text = timestamp
		path = '/var/www/PiCamServer/pics/' + timestamp + '.jpg'
		camera.capture(path, use_video_port=True)
		time.sleep(interval)
		counter += interval
finally:
	print "Exiting..."
	if streamVid == "y":
		camera.stop_recording()
	camera.stop_preview()

_____________________________________________________________________________________________________

camera.start_recording(stream, format='h264')
try:
	while True:
		camera.wait_recording(2)
		with stream.lock:
			# Find the first header frame in the video
			for frame in stream.frames:
				if frame.frame_type == picamera.PiVideoFrameType.sps_header:
					stream.seek(frame.position)
					break
			# Write the rest of the stream to disk (write binary)
			with io.open('/var/www/vids/vidstream.h264', 'wb') as output:
				output.write(stream.read())
finally:
	camera.stop_recording()
<|endoftext|>


<commit_before>#
# Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
#

"""
Contains functions that invoke the playbook.
"""
import sys
import json
import traceback
import argparse
from collections import namedtuple

from ansible import constants as CONST
verbosity = CONST.DEFAULT_VERBOSITY or 0

# Overrides the default logger from ansible/utils/display.py.
# fabric_ansible_logger customizes log message formatting
# Note that some internal ansible code inherits "display" from __main__,
# which is this file.
# Also note that CONST is from ansible.cfg
#
from job_manager.fabric_logger import fabric_ansible_logger
logger = fabric_ansible_logger("ansible")

import ansible.utils.display as default_display
default_display.logger = logger

from ansible.utils.display import Display
display = Display(verbosity)

from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.executor.playbook_executor import PlaybookExecutor

from job_manager.job_messages import MsgBundle
from job_manager.job_manager_logger import job_mgr_logger
JM_LOGGER = job_mgr_logger("FabricAnsible")

class PlaybookHelper(object):

    def get_plugin_output(self, pbex):
        output_json = pbex._tqm._variable_manager._nonpersistent_fact_cache[
            'localhost']['output']
        return output_json

    def execute_playbook(self, playbook_info):
        try:
            loader = DataLoader()
            inventory = InventoryManager(loader=loader, sources=['localhost'])
            variable_manager = VariableManager(loader=loader,
                                               inventory=inventory)

            Options = namedtuple('Options',
                                 ['listtags', 'listtasks', 'listhosts',
                                  'syntax', 'connection', 'module_path',
                                  'forks', 'remote_user', 'private_key_file',
                                  'ssh_common_args', 'ssh_extra_args',
                                  'sftp_extra_args', 'scp_extra_args',
                                  'become', 'become_method', 'become_user',
                                  'verbosity', 'check', 'diff'])
            options = Options(listtags=False, listtasks=False, listhosts=False,
                              syntax=False, connection='ssh', module_path=None,
                              forks=100, remote_user='slotlocker',
                              private_key_file=None, ssh_common_args=None,
                              ssh_extra_args=None, sftp_extra_args=None,
                              scp_extra_args=None, become=None,
                              become_method=None, become_user=None,
                              verbosity=None, check=False, diff=False)

            variable_manager.extra_vars = playbook_info['extra_vars']

            pbex = PlaybookExecutor(playbooks=[playbook_info['uri']],
                                    inventory=inventory,
                                    variable_manager=variable_manager,
                                    loader=loader,
                                    options=options, passwords=None)
            ret_val = pbex.run()
            if ret_val != 0:
                msg = MsgBundle.getMessage(MsgBundle.
                                           PLAYBOOK_RETURN_WITH_ERROR)
                raise Exception(msg)

            output = self.get_plugin_output(pbex)
            if output is None or output.get('status') is None:
                msg = MsgBundle.getMessage(MsgBundle.
                                           PLAYBOOK_OUTPUT_MISSING)
                raise Exception(msg)

            if output.get('status').lower() == "failure":
                msg = MsgBundle.getMessage(MsgBundle.
                                           PLAYBOOK_STATUS_FAILED)
                raise Exception(msg)

            return output
        except Exception as exp:
            msg = MsgBundle.getMessage(MsgBundle.PLAYBOOK_EXECUTE_ERROR,
                                       playbook_uri=playbook_info['uri'],
                                       execution_id=playbook_info['extra_vars']
                                       ['playbook_input']['job_execution_id'],
                                       exc_msg=repr(exp))
            if exp.message:
                msg = msg + "\n" + exp.message

            JM_LOGGER.error(msg)
            sys.exit(msg)

def parse_args():
    parser = argparse.ArgumentParser(description='Ansible playbook input '
                                                 'parameters')
    parser.add_argument('-i', '--playbook_input', nargs=1,
                        help='Playbook input json')
    return parser.parse_args()

if __name__ == "__main__":

    playbook_input_json = None
    try:
        playbook_params = parse_args()
        playbook_input_json = json.loads(playbook_params.playbook_input[0])
        if playbook_input_json is None:
            sys.exit(MsgBundle.getMessage(MsgBundle.NO_PLAYBOOK_INPUT_DATA))
    except Exception as exp:
        ERR_MSG = "Failed to start playbook due "\
              "to Exception: %s" % traceback.print_stack()
        JM_LOGGER.error(ERR_MSG)
        sys.exit(MsgBundle.getMessage(MsgBundle.PLAYBOOK_INPUT_PARSING_ERROR,
                                      exc_msg=repr(exp)))
    playbook_helper = PlaybookHelper()
    playbook_helper.execute_playbook(playbook_input_json)

<commit_msg>[DM] Remote Host Logs Missing<commit_after>#
# Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
#

"""
Contains functions that invoke the playbook.
"""
import sys
import json
import traceback
import argparse
from collections import namedtuple
import errno
from ansible.module_utils._text import to_bytes, to_text
from ansible.utils.color import stringc

from ansible import constants as CONST
verbosity = CONST.DEFAULT_VERBOSITY or 0

# Overrides the default logger from ansible/utils/display.py.
# fabric_ansible_logger customizes log message formatting
# Note that some internal ansible code inherits "display" from __main__,
# which is this file.
# Also note that CONST is from ansible.cfg
#
from job_manager.fabric_logger import fabric_ansible_logger
logger = fabric_ansible_logger("ansible")

# Overrides the default display processing from ansible/utils/display.py
# The default display method supresses certain output for remote hosts
# while we want this information sent to the logs
#
def fabric_ansible_display(self, msg, color=None, stderr=False, screen_only=False, log_only=False):
    """ Display a message to the user

    Note: msg *must* be a unicode string to prevent UnicodeError tracebacks.
    """

    nocolor = msg
    if color:
        msg = stringc(msg, color)

    if not log_only:
        if not msg.endswith(u'\n'):
            msg2 = msg + u'\n'
        else:
            msg2 = msg

        msg2 = to_bytes(msg2, encoding=self._output_encoding(stderr=stderr))
        if sys.version_info >= (3,):
            # Convert back to text string on python3
            # We first convert to a byte string so that we get rid of
            # characters that are invalid in the user's locale
            msg2 = to_text(msg2, self._output_encoding(stderr=stderr), errors='replace')

        # Note: After Display() class is refactored need to update the log capture
        # code in 'bin/ansible-connection' (and other relevant places).
        if not stderr:
            fileobj = sys.stdout
        else:
            fileobj = sys.stderr

        fileobj.write(msg2)

        try:
            fileobj.flush()
        except IOError as e:
            # Ignore EPIPE in case fileobj has been prematurely closed, eg.
            # when piping to "head -n1"
            if e.errno != errno.EPIPE:
                raise

    if logger:
        msg2 = nocolor.lstrip(u'\n')

        msg2 = to_bytes(msg2)
        if sys.version_info >= (3,):
            # Convert back to text string on python3
            # We first convert to a byte string so that we get rid of
            # characters that are invalid in the user's locale
            msg2 = to_text(msg2, self._output_encoding(stderr=stderr))

        if color == CONST.COLOR_ERROR:
            logger.error(msg2)
        else:
            logger.info(msg2)

import ansible.utils.display as default_display
default_display.logger = logger
default_display.Display.display = fabric_ansible_display

from ansible.utils.display import Display
display = Display(verbosity)

from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.executor.playbook_executor import PlaybookExecutor

from job_manager.job_messages import MsgBundle
from job_manager.job_manager_logger import job_mgr_logger
JM_LOGGER = job_mgr_logger("FabricAnsible")

class PlaybookHelper(object):

    def get_plugin_output(self, pbex):
        output_json = pbex._tqm._variable_manager._nonpersistent_fact_cache[
            'localhost']['output']
        return output_json

    def execute_playbook(self, playbook_info):
        try:
            loader = DataLoader()
            inventory = InventoryManager(loader=loader, sources=['localhost'])
            variable_manager = VariableManager(loader=loader,
                                               inventory=inventory)

            Options = namedtuple('Options',
                                 ['listtags', 'listtasks', 'listhosts',
                                  'syntax', 'connection', 'module_path',
                                  'forks', 'remote_user', 'private_key_file',
                                  'ssh_common_args', 'ssh_extra_args',
                                  'sftp_extra_args', 'scp_extra_args',
                                  'become', 'become_method', 'become_user',
                                  'verbosity', 'check', 'diff'])
            options = Options(listtags=False, listtasks=False, listhosts=False,
                              syntax=False, connection='ssh', module_path=None,
                              forks=100, remote_user='slotlocker',
                              private_key_file=None, ssh_common_args=None,
                              ssh_extra_args=None, sftp_extra_args=None,
                              scp_extra_args=None, become=None,
                              become_method=None, become_user=None,
                              verbosity=None, check=False, diff=False)

            variable_manager.extra_vars = playbook_info['extra_vars']

            pbex = PlaybookExecutor(playbooks=[playbook_info['uri']],
                                    inventory=inventory,
                                    variable_manager=variable_manager,
                                    loader=loader,
                                    options=options, passwords=None)
            ret_val = pbex.run()
            if ret_val != 0:
                msg = MsgBundle.getMessage(MsgBundle.
                                           PLAYBOOK_RETURN_WITH_ERROR)
                raise Exception(msg)

            output = self.get_plugin_output(pbex)
            if output is None or output.get('status') is None:
                msg = MsgBundle.getMessage(MsgBundle.
                                           PLAYBOOK_OUTPUT_MISSING)
                raise Exception(msg)

            if output.get('status').lower() == "failure":
                msg = MsgBundle.getMessage(MsgBundle.
                                           PLAYBOOK_STATUS_FAILED)
                raise Exception(msg)

            return output
        except Exception as exp:
            msg = MsgBundle.getMessage(MsgBundle.PLAYBOOK_EXECUTE_ERROR,
                                       playbook_uri=playbook_info['uri'],
                                       execution_id=playbook_info['extra_vars']
                                       ['playbook_input']['job_execution_id'],
                                       exc_msg=repr(exp))
            if exp.message:
                msg = msg + "\n" + exp.message

            JM_LOGGER.error(msg)
            sys.exit(msg)

def parse_args():
    parser = argparse.ArgumentParser(description='Ansible playbook input '
                                                 'parameters')
    parser.add_argument('-i', '--playbook_input', nargs=1,
                        help='Playbook input json')
    return parser.parse_args()

if __name__ == "__main__":

    playbook_input_json = None
    try:
        playbook_params = parse_args()
        playbook_input_json = json.loads(playbook_params.playbook_input[0])
        if playbook_input_json is None:
            sys.exit(MsgBundle.getMessage(MsgBundle.NO_PLAYBOOK_INPUT_DATA))
    except Exception as exp:
        ERR_MSG = "Failed to start playbook due "\
              "to Exception: %s" % traceback.print_stack()
        JM_LOGGER.error(ERR_MSG)
        sys.exit(MsgBundle.getMessage(MsgBundle.PLAYBOOK_INPUT_PARSING_ERROR,
                                      exc_msg=repr(exp)))
    playbook_helper = PlaybookHelper()
    playbook_helper.execute_playbook(playbook_input_json)

<|endoftext|>


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

import re

from flask import render_template, request, redirect, url_for

from app import app, db

# hoo boy. compile reviews and articles into full-text 'documents' and search on them
tmp = db.session.execute("SELECT p_id, p_title, p_subtitle FROM ( \
                              SELECT review.id AS p_id, \
                                     review.title AS p_title, \
                                     review.subtitle AS p_subtitle, \
                                     review.url AS p_url, \
                                     setweight(to_tsvector(review.title), 'A') || \
                                     setweight(to_tsvector(review.subtitle), 'A') || \
                                     setweight(to_tsvector(distiller.name), 'C') || \
                                     setweight(to_tsvector(review.body), 'B') || \
                                     setweight(to_tsvector(review.drink_type), 'D') \
                                     AS document \
                              FROM review \
                              LEFT JOIN distiller ON distiller.id = review.distiller_id \
                              WHERE review.is_published \
                              GROUP BY review.id, distiller.id \
                              UNION \
                              SELECT article.id AS p_id, \
                                     article.title AS p_title, \
                                     article.subtitle AS p_subtitle, \
                                     article.url AS p_url, \
                                     setweight(to_tsvector(article.title), 'A') || \
                                     setweight(to_tsvector(article.subtitle), 'A') || \
                                     setweight(to_tsvector(article.body), 'B') \
                                     AS document \
                              FROM article \
                              WHERE article.is_published \
                          ) p_search \
                          WHERE p_search.document @@ to_tsquery('alcohol') \
                          ORDER BY ts_rank(p_search.document, to_tsquery('alcohol')) DESC;")
for row in tmp:
    print(row)

@app.route('/search/')
def search():

    r = re.compile(r'[^a-zA-Z0-9_\-]')
    keywords = re.sub(r, ' ', request.args.get('q', ''))
    if keywords:
        return keywords
    return ''
<commit_msg>Move document query to materialized view, then index it<commit_after># -*- coding: utf-8 -*-

import re

from flask import render_template, request, redirect, url_for

from app import app, db

# hoo boy. compile reviews and articles into full-text 'documents' and search on them
db.session.execute("SET LOCAL maintenance_work_mem = '1GB';")
db.session.execute("SET LOCAL work_mem = '100MB';")
db.session.execute("CREATE MATERIALIZED VIEW IF NOT EXISTS search_index AS \
                    SELECT p_id, p_title, p_subtitle, p_url, p_image, document FROM ( \
                        SELECT review.id AS p_id, \
                               review.title AS p_title, \
                               review.subtitle AS p_subtitle, \
                               review.url AS p_url, \
                               review.image_list AS p_image, \
                               setweight(to_tsvector(review.title), 'A') || \
                               setweight(to_tsvector(review.subtitle), 'A') || \
                               setweight(to_tsvector(distiller.name), 'C') || \
                               setweight(to_tsvector(review.body), 'B') || \
                               setweight(to_tsvector(review.drink_type), 'D') \
                               AS document \
                        FROM review \
                        LEFT JOIN distiller ON distiller.id = review.distiller_id \
                        WHERE review.is_published \
                        GROUP BY review.id, distiller.id \
                        UNION \
                        SELECT article.id AS p_id, \
                               article.title AS p_title, \
                               article.subtitle AS p_subtitle, \
                               article.url AS p_url, \
                               article.image_list AS p_image, \
                               setweight(to_tsvector(article.title), 'A') || \
                               setweight(to_tsvector(article.subtitle), 'A') || \
                               setweight(to_tsvector(article.body), 'B') \
                               AS document \
                        FROM article \
                        WHERE article.is_published \
                    ) p_search;")
db.session.execute("CREATE INDEX IF NOT EXISTS idx_fts_search ON search_index USING gin(document);")
db.session.commit()

@app.route('/search/')
def search():
    tmp = db.session.execute("SELECT p_id, p_title, p_subtitle, p_url, p_image \
                              FROM search_index \
                              WHERE document @@ to_tsquery('alcohol') \
                              ORDER BY ts_rank(document, to_tsquery('alcohol')) DESC;")
    for row in tmp:
        print(row)

    r = re.compile(r'[^a-zA-Z0-9_\-]')
    keywords = re.sub(r, ' ', request.args.get('q', ''))
    if keywords:
        return keywords
    return ''
<|endoftext|>


<commit_before>import json
import requests
import jwt
from datetime import datetime, timedelta
from app.models import User
from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest, Http404
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View

class social(View):

    def create_token(self, user):
        payload = {
            'sub': user.id,
            'iat': datetime.utcnow(),
            'exp': datetime.utcnow() + timedelta(days=14)
        }
        token = jwt.encode(payload, settings.TOKEN_SECRET)
        return token.decode('unicode_escape')

    def parse_token(req):
        token = req.META.get('HTTP_AUTHORIZATION').split()[1]
        return jwt.decode(token, settings.TOKEN_SECRET)

    def callback(self, request, *args, **kwargs):

        access_token_url = 'https://graph.facebook.com/v2.3/oauth/access_token'
        graph_api_url = 'https://graph.facebook.com/v2.3/me?fields=name,email'

        params = json.loads(request.body)

        params = {
            'client_id': params['clientId'],
            'redirect_uri': params['redirectUri'],
            'client_secret': settings.FACEBOOK_SECRET,
            'code': params['code'],
        }

        r = requests.post(access_token_url, params)
        access_token = json.loads(r.text)

        # GET => https://graph.facebook.com/v2.3/me
        # to get user profile (email, first_name, last_name, gender, id)
        r = requests.get(graph_api_url, params=access_token)
        profile = json.loads(r.text)

        if request.META.get('HTTP_AUTHORIZATION'):

            user = User.objects.filter(fb_id=profile['id']).first()

            if user:
                return HttpResponseBadRequest

                user = User(fb_id = profile['id'],
                            name  = profile['name'],
                            email = profile['email'])
                user.save()

            payload = parse_token(request)

        user = User.objects.filter(fb_id=profile['id']).first()
        if user:
            token = self.create_token(user)
            return HttpResponse(json.dumps({ 'token': token }))

        user = User(fb_id = profile['id'],
                    name  = profile['name'],
                    email = profile['email'])
        user.save()

        token = self.create_token(user)
        return HttpResponse(json.dumps({ 'token': token }))

<commit_msg>Fixed callback<commit_after>import json
import requests
import jwt
from datetime import datetime, timedelta
from app.models import User
from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest, Http404
from django.views.generic import View

class social(View):

    def create_token(self, user):
        payload = {
            'sub': user.id,
            'iat': datetime.utcnow(),
            'exp': datetime.utcnow() + timedelta(days=14)
        }
        token = jwt.encode(payload, settings.TOKEN_SECRET)
        return token.decode('unicode_escape')

    def parse_token(req):
        token = req.META.get('HTTP_AUTHORIZATION').split()[1]
        return jwt.decode(token, settings.TOKEN_SECRET)

    def callback(self, request, *args, **kwargs):

        access_token_url = 'https://graph.facebook.com/v2.3/oauth/access_token'
        graph_api_url = 'https://graph.facebook.com/v2.3/me?fields=name,email'

        params = json.loads(request.body)

        params = {
            'client_id': params['clientId'],
            'redirect_uri': params['redirectUri'],
            'client_secret': settings.FACEBOOK_SECRET,
            'code': params['code'],
        }

        r = requests.post(access_token_url, params)
        access_token = json.loads(r.text)

        # GET => https://graph.facebook.com/v2.3/me
        # to get user profile (email, first_name, last_name, gender, id)
        r = requests.get(graph_api_url, params=access_token)
        profile = json.loads(r.text)

        if request.META.get('HTTP_AUTHORIZATION'):

            user = User.objects.filter(fb_id=profile['id']).first()

            if user:
                return HttpResponseBadRequest

            payload = parse_token(request)

            user = User.objects.filter(fb_id=payload['sub']).first()
            if not user:
                return HttpResponseBadRequest

            user = User(fb_id = profile['id'],
                        name  = profile['name'],
                        email = profile['email'])
            user.save()
            token = self.create_token(user)
            return HttpResponse(json.dumps({ 'token': token }))

        user = User.objects.filter(fb_id=profile['id']).first()
        if user:
            token = self.create_token(user)
            return HttpResponse(json.dumps({ 'token': token }))

        user = User(fb_id = profile['id'],
                    name  = profile['name'],
                    email = profile['email'])
        user.save()

        token = self.create_token(user)
        return HttpResponse(json.dumps({ 'token': token }))

<|endoftext|>


<commit_before>import flask_table

class SelectCol(flask_table.Col):
    def td_format(self, content):
        html = '<select name="{}">'.format(content['name'])
        html += '<option></option>'
        for option, value in zip(content['options'], content.get('values',
                                                                 content['options'])):
            html += '<option value="{}"{}>{}</option>'.format(value, ' selected' if
                           option == content.get('default', None) else '', option)
        html += "</select>"
        return html

class CheckBoxCol(flask_table.Col):
    def __init__(self, *args, checked=False, **kwargs):
        super().__init__(*args, **kwargs)
        self.checked = checked

    def td_format(self, content):
        html = '<input type="checkbox" name="{}" value="{}"{}>'.format(content['name'],
                        content['value'], ' checked' if self.checked else '')
        return html

class KeyColumn(flask_table.Col):
    def td_format(self, content):
        key = {name:content[name][0] for name in content.dtype.names} # recarray to dict
        return '{}'.format(key)

class CorrectionTable(flask_table.Table):
    classes = ['Relation']
    animal_id = flask_table.Col('Animal Id')
    session = flask_table.Col('Session')
    scan_idx = flask_table.Col('Scan')
    pipe_version = flask_table.Col('Pipe Version')
    field = flask_table.Col('Field')

    channel = SelectCol('Channel')

class SegmentationTable(flask_table.Table):
    classes = ['Relation']
    animal_id = flask_table.Col('Animal Id')
    session = flask_table.Col('Session')
    scan_idx = flask_table.Col('Scan')
    pipe_version = flask_table.Col('Pipe Version')
    field = flask_table.Col('Field')
    channel = flask_table.Col('Channel')

    compartment = SelectCol('Compartment')
    ignore = CheckBoxCol('Ignore')

class ProgressTable(flask_table.Table):
    classes = ['Relation']
    table = flask_table.Col('Table')
    processed = flask_table.Col('Processed')
    percentage = flask_table.Col('Percentage')

class JobTable(flask_table.Table):
    classes = ['Relation']
    table_name = flask_table.Col('Table Name')
    status = flask_table.Col('Status')
    key = KeyColumn('Key')
    user = flask_table.Col('User')
    connection_id = flask_table.Col('Connection Id')
    error_message = flask_table.Col('Error Message')
    timestamp = flask_table.DatetimeCol('Timestamp')

    delete = CheckBoxCol('Delete')

class SummaryTable(flask_table.Table):
    classes = ['Relation']
    animal_id = flask_table.Col('Animal Id')
    session = flask_table.Col('Session')
    scan_idx = flask_table.Col('Scan Idx')
    field = flask_table.Col('Field')
    pipe_version = flask_table.Col('Pipe Version')

    kwargs = {'animal_id': 'animal_id', 'session': 'session', 'scan_idx': 'scan_idx',
              'field': 'field', 'pipe_version': 'pipe_version'}
    correlation = flask_table.LinkCol('Correlation Image', 'figure', url_kwargs=kwargs,
                                      url_kwargs_extra={'which': 'correlation'})
    average = flask_table.LinkCol('Average Image', 'figure', url_kwargs=kwargs,
                                  url_kwargs_extra={'which': 'average'})
    traces = flask_table.LinkCol('Spike Traces', 'traces', url_kwargs=kwargs,
                                 url_kwargs_extra={'channel': 1, 'segmentation_method': 3,
                                                   'spike_method': 5})

def djtable(table, **kwargs):
    tbl_cls = flask_table.create_table(table.__class__.__name__)
    for col in table.heading.non_blobs:
        tbl_cls.add_column(col, flask_table.Col(col))
    for col in table.heading.blobs:
        tbl_cls.add_column(col, flask_table.Col(col))

    content = table.proj(*table.heading.non_blobs).fetch(as_dict=True, **kwargs)
    for d in content:
        for col in table.heading.blobs:
            d[col] = '- blob -'

    tbl_cls.classes = ['Relation']
    table = tbl_cls(content)

    return table<commit_msg>refactor dj_table<commit_after>import flask_table

class SelectCol(flask_table.Col):
    def td_format(self, content):
        html = '<select name="{}">'.format(content['name'])
        html += '<option></option>'
        for option, value in zip(content['options'], content.get('values',
                                                                 content['options'])):
            html += '<option value="{}"{}>{}</option>'.format(value, ' selected' if
                           option == content.get('default', None) else '', option)
        html += "</select>"
        return html

class CheckBoxCol(flask_table.Col):
    def __init__(self, *args, checked=False, **kwargs):
        super().__init__(*args, **kwargs)
        self.checked = checked

    def td_format(self, content):
        html = '<input type="checkbox" name="{}" value="{}"{}>'.format(content['name'],
                        content['value'], ' checked' if self.checked else '')
        return html

class KeyColumn(flask_table.Col):
    def td_format(self, content):
        key = {name:content[name][0] for name in content.dtype.names} # recarray to dict
        return '{}'.format(key)

class CorrectionTable(flask_table.Table):
    classes = ['Relation']
    animal_id = flask_table.Col('Animal Id')
    session = flask_table.Col('Session')
    scan_idx = flask_table.Col('Scan')
    pipe_version = flask_table.Col('Pipe Version')
    field = flask_table.Col('Field')

    channel = SelectCol('Channel')

class SegmentationTable(flask_table.Table):
    classes = ['Relation']
    animal_id = flask_table.Col('Animal Id')
    session = flask_table.Col('Session')
    scan_idx = flask_table.Col('Scan')
    pipe_version = flask_table.Col('Pipe Version')
    field = flask_table.Col('Field')
    channel = flask_table.Col('Channel')

    compartment = SelectCol('Compartment')
    ignore = CheckBoxCol('Ignore')

class ProgressTable(flask_table.Table):
    classes = ['Relation']
    table = flask_table.Col('Table')
    processed = flask_table.Col('Processed')
    percentage = flask_table.Col('Percentage')

class JobTable(flask_table.Table):
    classes = ['Relation']
    table_name = flask_table.Col('Table Name')
    status = flask_table.Col('Status')
    key = KeyColumn('Key')
    user = flask_table.Col('User')
    connection_id = flask_table.Col('Connection Id')
    error_message = flask_table.Col('Error Message')
    timestamp = flask_table.DatetimeCol('Timestamp')

    delete = CheckBoxCol('Delete')

class SummaryTable(flask_table.Table):
    classes = ['Relation']
    animal_id = flask_table.Col('Animal Id')
    session = flask_table.Col('Session')
    scan_idx = flask_table.Col('Scan Idx')
    field = flask_table.Col('Field')
    pipe_version = flask_table.Col('Pipe Version')

    kwargs = {'animal_id': 'animal_id', 'session': 'session', 'scan_idx': 'scan_idx',
              'field': 'field', 'pipe_version': 'pipe_version'}
    correlation = flask_table.LinkCol('Correlation Image', 'figure', url_kwargs=kwargs,
                                      url_kwargs_extra={'which': 'correlation'})
    average = flask_table.LinkCol('Average Image', 'figure', url_kwargs=kwargs,
                                  url_kwargs_extra={'which': 'average'})
    traces = flask_table.LinkCol('Spike Traces', 'traces', url_kwargs=kwargs,
                                 url_kwargs_extra={'channel': 1, 'segmentation_method': 3,
                                                   'spike_method': 5})

def create_datajoint_table(rel, **fetch_kwargs):
    table_class = flask_table.create_table('{}Table'.format(rel.__class__.__name__))
    for col in rel.heading.attributes:
        table_class.add_column(col, flask_table.Col(col))

    items = rel.proj(*rel.heading.non_blobs).fetch(as_dict=True, **fetch_kwargs)
    for item in items:
        for blob_col in rel.heading.blobs:
            item[blob_col] = '<BLOB>'

    table_class.classes = ['Relation']
    table = table_class(items)

    return table<|endoftext|>


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

"""
URL for creating the badge:
[TODO] Switch to use pybadges once figure out the module not found issue.
'https://img.shields.io/badge/{name}-{status}-{color}.svg'

Commands for build the docker image and deploy to GKE:
docker build -t gcr.io/python-compatibility-tools/badge_server:v1 .
gcloud docker -- push gcr.io/python-compatibility-tools/badge_server:v1
kubectl apply -f deployment/app-with-secret.yaml
"""
import ast
import logging
import os
import requests
import threading

import flask
import redis

from compatibility_lib import compatibility_checker
from compatibility_lib import compatibility_store
from compatibility_lib import configs
from compatibility_lib import package as package_module

app = flask.Flask(__name__)

# Cache storing the package name associated with its check results.
# {
#     'pkg1_dep_badge':{},
#     'pkg1_self_comp_badge': {
#         'py2':{
#             'status': 'SUCCESS',
#             'details': None,
#         },
#         'py3':{
#             'status': 'CHECK_WARNING',
#             'details': '...',
#         }
#     },
#     'pkg1_google_comp_badge': {
#         'py2':{
#             'status': 'SUCCESS',
#             'details': None,
#         },
#         'py3':{
#             'status': 'CHECK_WARNING',
#             'details': {
#                 'package1': '...',
#             },
#         }
#     },
#     'pkg1_api_badge':{},
# }

REDIS_CACHE = {
    'opencensus_self_comp_badge': None,
    'opencensus_google_comp_badge': None,
}

def fake_redis_get(*args, **kwargs):
    key = args[2][0]
    return REDIS_CACHE[key]

def fake_redis_set(*args, **kwargs):
    key = args[2][0]
    value = str(args[2][1]).encode('utf-8')
    REDIS_CACHE[key] = value

# Patch away the redis connections if run locally
if os.environ.get('RUN_LOCALLY') is not None:
    import wrapt
    wrapt.wrap_function_wrapper('redis', 'StrictRedis.get', fake_redis_get)
    wrapt.wrap_function_wrapper('redis', 'StrictRedis.set', fake_redis_set)

redis_host = os.environ.get('REDISHOST', '10.0.0.3')
redis_port = int(os.environ.get('REDISPORT', 6379))
redis_client = redis.StrictRedis(host=redis_host, port=redis_port)

checker = compatibility_checker.CompatibilityChecker()
store = compatibility_store.CompatibilityStore()

URL_PREFIX = 'https://img.shields.io/badge/'

PY_VER_MAPPING = {
    2: 'py2',
    3: 'py3',
}

STATUS_COLOR_MAPPING = {
    'SUCCESS': 'green',
    'UNKNOWN': 'black',
    'INSTALL_ERROR': 'orange',
    'CHECK_WARNING': 'red',
    'CALCULATING': 'blue',
    'CONVERSION_ERROR': 'orange',
}

CONVERSION_ERROR_RES = {
    'py2': {
        'status': 'CONVERSION_ERROR',
        'details': None,
    },
    'py3': {
        'status': 'CONVERSION_ERROR',
        'details': None,
    }
}

SVG_CONTENT_TYPE = 'image/svg+xml'

EMPTY_DETAILS = 'NO DETAILS'

DEP_BADGE = 'dep_badge'
SELF_COMP_BADGE = 'self_comp_badge'
GOOGLE_COMP_BADGE = 'google_comp_badge'
API_BADGE = 'api_badge'

def _get_pair_status_for_packages(pkg_sets):
    version_and_res = {
        'py2': {
            'status': 'SUCCESS',
            'details': {},
        },
        'py3': {
            'status': 'SUCCESS',
            'details': {},
        }
    }
    for pkg_set in pkg_sets:
        pkgs = [package_module.Package(pkg) for pkg in pkg_set]
        pair_res = store.get_pair_compatibility(pkgs)
        for res in pair_res:
            py_version = PY_VER_MAPPING[res.python_major_version]
            # Status showing one of the check failures
            if res.status.value != 'SUCCESS':
                version_and_res[py_version]['status'] = res.status.value
                version_and_res[py_version]['details'][pkg_set[1]] = \
                    res.details if res.details is not None else EMPTY_DETAILS
    return version_and_res

def _get_badge_url(version_and_res, package_name):
    # By default use the status of py3, if it is not SUCCESS, and it can be
    # installed with python2, then use the result of python2.
    package_name = package_name.replace('-', '.')
    status = version_and_res['py3']['status']
    if status != 'SUCCESS' and \
            package_name not in configs.PKG_PY_VERSION_NOT_SUPPORTED.get(2):
        status = version_and_res['py2']['status']

    color = STATUS_COLOR_MAPPING[status]
    url = URL_PREFIX + '{}-{}-{}.svg'.format(
        package_name, status, color)

    return url

@app.route('/')
def greetings():
    return 'hello world'

# Endpoint for testing redis connection.
@app.route('/redis')
def index():
    value = redis_client.incr('counter', 1)
    return 'Visitor number: {}'.format(value)

@app.route('/self_compatibility_badge/image')
def self_compatibility_badge_image():
    """Badge showing whether a package is compatible with itself."""
    package_name = flask.request.args.get('package')

    version_and_res = {
        'py2': {
            'status': 'CALCULATING',
            'details': None,
        },
        'py3': {
            'status': 'CALCULATING',
            'details': None,
        }
    }

    def run_check():
        # First see if this package is already stored in BigQuery.
        package = package_module.Package(package_name)
        compatibility_status = store.get_self_compatibility(package)
        if compatibility_status:
            for res in compatibility_status:
                py_version = PY_VER_MAPPING[res.python_major_version]
                version_and_res[py_version]['status'] = res.status.value
                version_and_res[py_version]['details'] = res.details \
                    if res.details is not None else EMPTY_DETAILS

        # If not pre stored in BigQuery, run the check for the package.
        else:
            py2_res = checker.check([package_name], '2')
            py3_res = checker.check([package_name], '3')

            version_and_res['py2']['status'] = py2_res.get('result')
            py2_description = py2_res.get('description')
            py2_details = EMPTY_DETAILS if py2_description is None \
                else py2_description
            version_and_res['py2']['details'] = py2_details
            version_and_res['py3']['status'] = py3_res.get('result')
            py3_description = py3_res.get('description')
            py3_details = EMPTY_DETAILS if py3_description is None \
                else py3_description
            version_and_res['py3']['details'] = py3_details

        url = _get_badge_url(version_and_res, package_name)

        # Write the result to memory store
        redis_client.set(
            '{}_self_comp_badge'.format(package_name), version_and_res)
        return requests.get(url).text

    self_comp_res = redis_client.get(
        '{}_self_comp_badge'.format(package_name))
    threading.Thread(target=run_check).start()

    if self_comp_res is not None:
        try:
            details = ast.literal_eval(self_comp_res.decode('utf-8'))
        except SyntaxError:
            logging.error(
                'Error occurs while converting to dict, value is {}.'.format(
                    self_comp_res))
            details = CONVERSION_ERROR_RES
    else:
        details = version_and_res

    url = _get_badge_url(details, package_name)
    response = flask.make_response(requests.get(url).text)
    response.content_type = SVG_CONTENT_TYPE
    response.headers['Cache-Control'] = 'no-cache'
    response.add_etag()

    return response

@app.route('/self_compatibility_badge/target')
def self_compatibility_badge_target():
    """Return the dict which contains the self compatibility status and details
    for py2 and py3.

    e.g. {
          'py2':{
              'status': 'SUCCESS',
              'details': None,
          },
          'py3':{
              'status': 'CHECK_WARNING',
              'details': '...',
          }
      }
    """
    package_name = flask.request.args.get('package')
    self_comp_res = redis_client.get(
        '{}_self_comp_badge'.format(package_name))

    return str(self_comp_res)

@app.route('/google_compatibility_badge/image')
def google_compatibility_badge_image():
    """Badge showing whether a package is compatible with Google OSS Python
    packages. If all packages success, status is SUCCESS; else set status
    to one of the failure types, details can be found at the target link."""
    package_name = flask.request.args.get('package')

    default_version_and_res = {
        'py2': {
            'status': 'CALCULATING',
            'details': {},
        },
        'py3': {
            'status': 'CALCULATING',
            'details': {},
        }
    }

    def run_check():
        pkg_sets = [[package_name, pkg] for pkg in configs.PKG_LIST]
        if package_name in configs.PKG_LIST:
            result = _get_pair_status_for_packages(pkg_sets)
        else:
            for pkg_set in pkg_sets:
                for py_ver in [2, 3]:
                    py_version = PY_VER_MAPPING[py_ver]
                    res = checker.check(pkg_set, str(py_ver))
                    status = res.get('result')
                    if status != 'SUCCESS':
                        # Ignore the package that not support for given py_ver
                        if pkg_set[1] in \
                                configs.PKG_PY_VERSION_NOT_SUPPORTED.get(
                                py_ver):
                            continue
                        # Status showing one of the check failures
                        default_version_and_res[
                            py_version]['status'] = res.get('result')
                        description = res.get('description')
                        details = EMPTY_DETAILS if description is None \
                            else description
                        default_version_and_res[
                            py_version]['details'][pkg_set[1]] = details
            result = default_version_and_res

        # Write the result to memory store
        redis_client.set(
            '{}_google_comp_badge'.format(package_name), result)
        url = _get_badge_url(result, package_name)
        return requests.get(url).text

    google_comp_res = redis_client.get(
        '{}_google_comp_badge'.format(package_name))
    threading.Thread(target=run_check).start()

    if google_comp_res is not None:
        try:
            details = ast.literal_eval(google_comp_res.decode('utf-8'))
        except SyntaxError:
            logging.error(
                'Error occurs while converting to dict, value is {}.'.format(
                    google_comp_res))
            details = CONVERSION_ERROR_RES
    else:
        details = default_version_and_res

    url = _get_badge_url(details, package_name)
    response = flask.make_response(requests.get(url).text)
    response.content_type = SVG_CONTENT_TYPE
    response.headers['Cache-Control'] = 'no-cache'
    response.add_etag()

    return response

@app.route('/google_compatibility_badge/target')
def google_compatibility_badge_target():
    """Return the dict which contains the compatibility status with google
    packages and details for py2 and py3.

        e.g. {
              'py2':{
                  'status': 'SUCCESS',
                  'details': None,
              },
              'py3':{
                  'status': 'CHECK_WARNING',
                  'details': {
                      'package1': '...',
                  },
              }
          }
    """
    package_name = flask.request.args.get('package')
    google_comp_res = redis_client.get(
        '{}_google_comp_badge'.format(package_name))

    return str(google_comp_res)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)
<commit_msg>Fix badge server local mode (#74)<commit_after># Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
URL for creating the badge:
[TODO] Switch to use pybadges once figure out the module not found issue.
'https://img.shields.io/badge/{name}-{status}-{color}.svg'

Commands for build the docker image and deploy to GKE:
docker build -t gcr.io/python-compatibility-tools/badge_server:v1 .
gcloud docker -- push gcr.io/python-compatibility-tools/badge_server:v1
kubectl apply -f deployment/app-with-secret.yaml
"""
import ast
import logging
import os
import requests
import threading

import flask
import redis

from compatibility_lib import compatibility_checker
from compatibility_lib import compatibility_store
from compatibility_lib import configs
from compatibility_lib import package as package_module

app = flask.Flask(__name__)

# Cache storing the package name associated with its check results.
# {
#     'pkg1_dep_badge':{},
#     'pkg1_self_comp_badge': {
#         'py2':{
#             'status': 'SUCCESS',
#             'details': None,
#         },
#         'py3':{
#             'status': 'CHECK_WARNING',
#             'details': '...',
#         }
#     },
#     'pkg1_google_comp_badge': {
#         'py2':{
#             'status': 'SUCCESS',
#             'details': None,
#         },
#         'py3':{
#             'status': 'CHECK_WARNING',
#             'details': {
#                 'package1': '...',
#             },
#         }
#     },
#     'pkg1_api_badge':{},
# }

REDIS_CACHE = {}

def fake_redis_get(*args, **kwargs):
    key = args[2][0]
    return REDIS_CACHE.get(key)

def fake_redis_set(*args, **kwargs):
    key = args[2][0]
    value = str(args[2][1]).encode('utf-8')
    REDIS_CACHE[key] = value

# Patch away the redis connections if run locally
if os.environ.get('RUN_LOCALLY') is not None:
    import wrapt
    wrapt.wrap_function_wrapper('redis', 'StrictRedis.get', fake_redis_get)
    wrapt.wrap_function_wrapper('redis', 'StrictRedis.set', fake_redis_set)

redis_host = os.environ.get('REDISHOST', '10.0.0.3')
redis_port = int(os.environ.get('REDISPORT', 6379))
redis_client = redis.StrictRedis(host=redis_host, port=redis_port)

checker = compatibility_checker.CompatibilityChecker()
store = compatibility_store.CompatibilityStore()

URL_PREFIX = 'https://img.shields.io/badge/'

PY_VER_MAPPING = {
    2: 'py2',
    3: 'py3',
}

STATUS_COLOR_MAPPING = {
    'SUCCESS': 'green',
    'UNKNOWN': 'black',
    'INSTALL_ERROR': 'orange',
    'CHECK_WARNING': 'red',
    'CALCULATING': 'blue',
    'CONVERSION_ERROR': 'orange',
}

CONVERSION_ERROR_RES = {
    'py2': {
        'status': 'CONVERSION_ERROR',
        'details': None,
    },
    'py3': {
        'status': 'CONVERSION_ERROR',
        'details': None,
    }
}

SVG_CONTENT_TYPE = 'image/svg+xml'

EMPTY_DETAILS = 'NO DETAILS'

DEP_BADGE = 'dep_badge'
SELF_COMP_BADGE = 'self_comp_badge'
GOOGLE_COMP_BADGE = 'google_comp_badge'
API_BADGE = 'api_badge'

def _get_pair_status_for_packages(pkg_sets):
    version_and_res = {
        'py2': {
            'status': 'SUCCESS',
            'details': {},
        },
        'py3': {
            'status': 'SUCCESS',
            'details': {},
        }
    }
    for pkg_set in pkg_sets:
        pkgs = [package_module.Package(pkg) for pkg in pkg_set]
        pair_res = store.get_pair_compatibility(pkgs)
        for res in pair_res:
            py_version = PY_VER_MAPPING[res.python_major_version]
            # Status showing one of the check failures
            if res.status.value != 'SUCCESS':
                version_and_res[py_version]['status'] = res.status.value
                version_and_res[py_version]['details'][pkg_set[1]] = \
                    res.details if res.details is not None else EMPTY_DETAILS
    return version_and_res

def _get_badge_url(version_and_res, package_name):
    # By default use the status of py3, if it is not SUCCESS, and it can be
    # installed with python2, then use the result of python2.
    package_name = package_name.replace('-', '.')
    status = version_and_res['py3']['status']
    if status != 'SUCCESS' and \
            package_name not in configs.PKG_PY_VERSION_NOT_SUPPORTED.get(2):
        status = version_and_res['py2']['status']

    color = STATUS_COLOR_MAPPING[status]
    url = URL_PREFIX + '{}-{}-{}.svg'.format(
        package_name, status, color)

    return url

@app.route('/')
def greetings():
    return 'hello world'

# Endpoint for testing redis connection.
@app.route('/redis')
def index():
    value = redis_client.incr('counter', 1)
    return 'Visitor number: {}'.format(value)

@app.route('/self_compatibility_badge/image')
def self_compatibility_badge_image():
    """Badge showing whether a package is compatible with itself."""
    package_name = flask.request.args.get('package')

    version_and_res = {
        'py2': {
            'status': 'CALCULATING',
            'details': None,
        },
        'py3': {
            'status': 'CALCULATING',
            'details': None,
        }
    }

    def run_check():
        # First see if this package is already stored in BigQuery.
        package = package_module.Package(package_name)
        compatibility_status = store.get_self_compatibility(package)
        if compatibility_status:
            for res in compatibility_status:
                py_version = PY_VER_MAPPING[res.python_major_version]
                version_and_res[py_version]['status'] = res.status.value
                version_and_res[py_version]['details'] = res.details \
                    if res.details is not None else EMPTY_DETAILS

        # If not pre stored in BigQuery, run the check for the package.
        else:
            py2_res = checker.check([package_name], '2')
            py3_res = checker.check([package_name], '3')

            version_and_res['py2']['status'] = py2_res.get('result')
            py2_description = py2_res.get('description')
            py2_details = EMPTY_DETAILS if py2_description is None \
                else py2_description
            version_and_res['py2']['details'] = py2_details
            version_and_res['py3']['status'] = py3_res.get('result')
            py3_description = py3_res.get('description')
            py3_details = EMPTY_DETAILS if py3_description is None \
                else py3_description
            version_and_res['py3']['details'] = py3_details

        url = _get_badge_url(version_and_res, package_name)

        # Write the result to memory store
        redis_client.set(
            '{}_self_comp_badge'.format(package_name), version_and_res)
        return requests.get(url).text

    self_comp_res = redis_client.get(
        '{}_self_comp_badge'.format(package_name))
    threading.Thread(target=run_check).start()

    if self_comp_res is not None:
        try:
            details = ast.literal_eval(self_comp_res.decode('utf-8'))
        except SyntaxError:
            logging.error(
                'Error occurs while converting to dict, value is {}.'.format(
                    self_comp_res))
            details = CONVERSION_ERROR_RES
    else:
        details = version_and_res

    url = _get_badge_url(details, package_name)
    response = flask.make_response(requests.get(url).text)
    response.content_type = SVG_CONTENT_TYPE
    response.headers['Cache-Control'] = 'no-cache'
    response.add_etag()

    return response

@app.route('/self_compatibility_badge/target')
def self_compatibility_badge_target():
    """Return the dict which contains the self compatibility status and details
    for py2 and py3.

    e.g. {
          'py2':{
              'status': 'SUCCESS',
              'details': None,
          },
          'py3':{
              'status': 'CHECK_WARNING',
              'details': '...',
          }
      }
    """
    package_name = flask.request.args.get('package')
    self_comp_res = redis_client.get(
        '{}_self_comp_badge'.format(package_name))

    return str(self_comp_res)

@app.route('/google_compatibility_badge/image')
def google_compatibility_badge_image():
    """Badge showing whether a package is compatible with Google OSS Python
    packages. If all packages success, status is SUCCESS; else set status
    to one of the failure types, details can be found at the target link."""
    package_name = flask.request.args.get('package')

    default_version_and_res = {
        'py2': {
            'status': 'CALCULATING',
            'details': {},
        },
        'py3': {
            'status': 'CALCULATING',
            'details': {},
        }
    }

    def run_check():
        pkg_sets = [[package_name, pkg] for pkg in configs.PKG_LIST]
        if package_name in configs.PKG_LIST:
            result = _get_pair_status_for_packages(pkg_sets)
        else:
            for pkg_set in pkg_sets:
                for py_ver in [2, 3]:
                    py_version = PY_VER_MAPPING[py_ver]
                    res = checker.check(pkg_set, str(py_ver))
                    status = res.get('result')
                    if status != 'SUCCESS':
                        # Ignore the package that not support for given py_ver
                        if pkg_set[1] in \
                                configs.PKG_PY_VERSION_NOT_SUPPORTED.get(
                                py_ver):
                            continue
                        # Status showing one of the check failures
                        default_version_and_res[
                            py_version]['status'] = res.get('result')
                        description = res.get('description')
                        details = EMPTY_DETAILS if description is None \
                            else description
                        default_version_and_res[
                            py_version]['details'][pkg_set[1]] = details
            result = default_version_and_res

        # Write the result to memory store
        redis_client.set(
            '{}_google_comp_badge'.format(package_name), result)
        url = _get_badge_url(result, package_name)
        return requests.get(url).text

    google_comp_res = redis_client.get(
        '{}_google_comp_badge'.format(package_name))
    threading.Thread(target=run_check).start()

    if google_comp_res is not None:
        try:
            details = ast.literal_eval(google_comp_res.decode('utf-8'))
        except SyntaxError:
            logging.error(
                'Error occurs while converting to dict, value is {}.'.format(
                    google_comp_res))
            details = CONVERSION_ERROR_RES
    else:
        details = default_version_and_res

    url = _get_badge_url(details, package_name)
    response = flask.make_response(requests.get(url).text)
    response.content_type = SVG_CONTENT_TYPE
    response.headers['Cache-Control'] = 'no-cache'
    response.add_etag()

    return response

@app.route('/google_compatibility_badge/target')
def google_compatibility_badge_target():
    """Return the dict which contains the compatibility status with google
    packages and details for py2 and py3.

        e.g. {
              'py2':{
                  'status': 'SUCCESS',
                  'details': None,
              },
              'py3':{
                  'status': 'CHECK_WARNING',
                  'details': {
                      'package1': '...',
                  },
              }
          }
    """
    package_name = flask.request.args.get('package')
    google_comp_res = redis_client.get(
        '{}_google_comp_badge'.format(package_name))

    return str(google_comp_res)

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


<commit_before>__version__ = '1.06'

try:
    from crashreporter import CrashReporter
except ImportError:
    pass
<commit_msg>bump to 1.07<commit_after>__version__ = '1.07'

try:
    from crashreporter import CrashReporter
except ImportError:
    pass
<|endoftext|>