<commit_before>from functools import partial
from django.db.models import Avg
from django.http import JsonResponse
from core.models import DBDataSource, GameResult
from logic.Akinator import Akinator
from logic.AkinatorDataSource import ANSWERS

sessions_pool = {}

ANSWERS_MAP = {
    0: ANSWERS.YES,
    1: ANSWERS.NO,
    2: ANSWERS.DOES_NOT_MATTER,
    3: ANSWERS.DO_NOT_KNOW,
}

def _remove_game(session_id):
    sessions_pool.pop(session_id, None)

def start_game(request):
    session = Akinator(DBDataSource())
    sessions_pool[session.game_id] = session

    session.set_finish_callback(partial(_remove_game, session.game_id))

    content = {
        'sessionId': session.game_id,
        'firstQuestion': session.current_question.text,
    }
    return JsonResponse(content)

def get_game(request):
    """
    Helper function to fetch game based on request data
    """
    session_id = request.REQUEST['sessionId']
    return sessions_pool[session_id]

def process_response(request):
    akinator = get_game(request)

    answer = ANSWERS_MAP[int(request.REQUEST['answer'])]
    entity, question = akinator.process_answer(answer)

    response = {
        'nextQuestion': None,
        'result': None,
    }
    if entity:
        response['result'] = {
            'name': entity.name,
            'description': entity.description,
        }
    else:
        response['nextQuestion'] = question.text

    return JsonResponse(response)

def current_stats(request):
    content = {
        'entities': []
    }

    count = request.REQUEST['count']
    akinator = get_game(request)
    top = akinator.get_top_hypothesis(count)

    for entity, score in top:
        content['entities'].append({
            'name': entity.name,
            'score': score,
        })

    return JsonResponse(content)

def end_game(request):
    akinator = get_game(request)

    status = request.REQUEST['status']
    if status == 'OK':
        akinator.hypothesis_accepted()
    else:
        name = request.REQUEST['name']
        description = request.REQUEST['description']

        akinator.hypothesis_declined(name, description)

    return JsonResponse('OK')

def statistics(request):
    games_count = GameResult.objects.count()
    win_rate = GameResult.objects.filter(success=True).count * 100.0 / games_count
    avg_game_length = GameResult.objects.all().aggregate(Avg('game_length'))['game_length__avg']

    content = {
        'gamesCount': games_count,
        'winRate': win_rate,
        'avgLength': avg_game_length,
    }

    return JsonResponse(content)
<commit_msg>Fixed urls<commit_after>from functools import partial
from django.db.models import Avg
from django.http import JsonResponse
from core.models import DBDataSource, GameResult
from logic.Akinator import Akinator
from logic.AkinatorDataSource import ANSWERS

sessions_pool = {}

ANSWERS_MAP = {
    0: ANSWERS.YES,
    1: ANSWERS.NO,
    2: ANSWERS.DOES_NOT_MATTER,
    3: ANSWERS.DO_NOT_KNOW,
}

def _remove_game(session_id):
    sessions_pool.pop(session_id, None)

def start_game(request):
    session = Akinator(DBDataSource())
    sessions_pool[session.game_id] = session

    session.set_finish_callback(partial(_remove_game, session.game_id))

    content = {
        'sessionId': session.game_id,
        'firstQuestion': session.current_question.text,
    }
    return JsonResponse(content)

def get_game(request):
    """
    Helper function to fetch game based on request data
    """
    session_id = request.REQUEST['sessionId']
    return sessions_pool[session_id]

def process_response(request):
    akinator = get_game(request)

    answer = ANSWERS_MAP[int(request.REQUEST['answer'])]
    entity, question = akinator.process_answer(answer)

    response = {
        'nextQuestion': None,
        'result': None,
    }
    if entity:
        response['result'] = {
            'name': entity.name,
            'description': entity.description,
        }
    else:
        response['nextQuestion'] = question.text

    return JsonResponse(response)

def current_stats(request):
    content = {
        'entities': []
    }

    count = int(request.REQUEST['count'])
    akinator = get_game(request)
    top = akinator.get_top_hypothesis(count)

    for entity, score in top:
        content['entities'].append({
            'name': entity.name,
            'score': score,
        })

    return JsonResponse(content)

def end_game(request):
    akinator = get_game(request)

    status = request.REQUEST['status']
    if status == 'OK':
        akinator.hypothesis_accepted()
    else:
        name = request.REQUEST['name']
        description = request.REQUEST['description']

        akinator.hypothesis_declined(name, description)

    return JsonResponse('OK')

def statistics(request):
    games_count = GameResult.objects.count()
    win_rate = GameResult.objects.filter(success=True).count * 100.0 / games_count
    avg_game_length = GameResult.objects.all().aggregate(Avg('game_length'))['game_length__avg']

    content = {
        'gamesCount': games_count,
        'winRate': win_rate,
        'avgLength': avg_game_length,
    }

    return JsonResponse(content)
<|endoftext|>


<commit_before>from brian import (Network, NeuronGroup, PoissonGroup, Connection,
                   StateMonitor, SpikeMonitor,
                   mV, ms, Hz)
import matplotlib.pyplot as plt

def pif_th():
    lifeq = """
    V : volt
    Vth : volt
    """
    thstep = 15*mV
    nrn = NeuronGroup(1, lifeq, threshold="V>=Vth", reset="Vth+=thstep")
    nrn.V = 0*mV
    nrn.Vth = thstep
    sim = Network(nrn)

    inputgrp = PoissonGroup(20, 20*Hz)
    connection = Connection(inputgrp, nrn, state="V", weight=0.5*mV)

    vmon = StateMonitor(nrn, "V", record=True)
    thmon = StateMonitor(nrn, "Vth", record=True)
    spikemon = SpikeMonitor(nrn, record=True)

    sim.add(inputgrp, connection, vmon, thmon, spikemon)
    sim.run(200*ms)
    return vmon, thmon, spikemon

def pif_reset():
    lifeq = """
    V : volt
    Vth : volt
    """
    thstep = 15*mV
    nrn = NeuronGroup(1, lifeq, threshold="V>=Vth", reset="V=0*mV")
    nrn.V = 0*mV
    nrn.Vth = thstep
    sim = Network(nrn)

    inputgrp = PoissonGroup(20, 20*Hz)
    connection = Connection(inputgrp, nrn, state="V", weight=0.5*mV)

    vmon = StateMonitor(nrn, "V", record=True)
    thmon = StateMonitor(nrn, "Vth", record=True)
    spikemon = SpikeMonitor(nrn, record=True)

    sim.add(inputgrp, connection, vmon, thmon, spikemon)
    sim.run(200*ms)
    return vmon, thmon, spikemon

if __name__=="__main__":
    thvmon, ththmon, thspikemon = pif_th()
    print("Finished 1")
    resetvmon, resetthmon, resetspikemon = pif_reset()
    print("Finished 2")

    plt.figure()
    plt.subplot(3, 1, 1)
    plt.plot(thvmon.times, thvmon[0])
    plt.plot(ththmon.times, ththmon[0], "k--")
    plt.subplot(3, 1, 2)
    plt.plot(resetvmon.times, resetvmon[0], "r")
    plt.plot(resetthmon.times, resetthmon[0], "k--")
    plt.subplot(3, 1, 3)
    for sp in thspikemon[0]:
        plt.plot([sp]*2, [0, 1], "b")
    for sp in resetspikemon[0]:
        plt.plot([sp]*2, [0, 1], "r")

    plt.show()
<commit_msg>Common random input<commit_after>from brian import (Network, NeuronGroup, SpikeGeneratorGroup, Connection,
                   StateMonitor, SpikeMonitor,
                   defaultclock,
                   mV, ms, Hz)
import numpy as np
import random as rnd
import matplotlib.pyplot as plt

duration = 200*ms
inspikes = []
while np.sum(inspikes) < float(duration):
    inspikes.append(rnd.expovariate(500*Hz))
inspikes = np.cumsum(inspikes)
spiketuples = [(0, t) for t in inspikes]
inputgrp = SpikeGeneratorGroup(1, spiketuples)

def pif_th():
    defaultclock.reinit()
    sim = Network()
    lifeq = """
    V : volt
    Vth : volt
    """
    thstep = 15*mV
    nrn = NeuronGroup(1, lifeq, threshold="V>=Vth", reset="Vth+=thstep")
    nrn.V = 0*mV
    nrn.Vth = thstep
    sim.add(nrn)

    connection = Connection(inputgrp, nrn, state="V", weight=0.5*mV)

    vmon = StateMonitor(nrn, "V", record=True)
    thmon = StateMonitor(nrn, "Vth", record=True)
    spikemon = SpikeMonitor(nrn, record=True)

    sim.add(inputgrp, connection, vmon, thmon, spikemon)
    sim.run(duration)
    return vmon, thmon, spikemon

def pif_reset():
    defaultclock.reinit()
    sim = Network()
    lifeq = """
    V : volt
    Vth : volt
    """
    thstep = 15*mV
    nrn = NeuronGroup(1, lifeq, threshold="V>=Vth", reset="V=0*mV")
    nrn.V = 0*mV
    nrn.Vth = thstep
    sim.add(nrn)

    connection = Connection(inputgrp, nrn, state="V", weight=0.5*mV)

    vmon = StateMonitor(nrn, "V", record=True)
    thmon = StateMonitor(nrn, "Vth", record=True)
    spikemon = SpikeMonitor(nrn, record=True)

    sim.add(inputgrp, connection, vmon, thmon, spikemon)
    sim.run(duration)
    return vmon, thmon, spikemon

if __name__=="__main__":
    thvmon, ththmon, thspikemon = pif_th()
    print("Finished 1")
    resetvmon, resetthmon, resetspikemon = pif_reset()
    print("Finished 2")

    plt.figure()
    plt.subplot(3, 1, 1)
    plt.plot(thvmon.times, thvmon[0])
    plt.plot(ththmon.times, ththmon[0], "k--")
    plt.subplot(3, 1, 2)
    plt.plot(resetvmon.times, resetvmon[0], "r")
    plt.plot(resetthmon.times, resetthmon[0], "k--")
    plt.subplot(3, 1, 3)
    for sp in thspikemon[0]:
        plt.plot([sp]*2, [0, 0.5], "b")
    for sp in resetspikemon[0]:
        plt.plot([sp]*2, [0.5, 1], "r")
    plt.axis(xmin=0, xmax=float(duration))

    plt.show()
<|endoftext|>


<commit_before>"""Cosmological Model simulations by Ian Huston
    $Id: cosmomodels.py,v 1.2 2008/04/21 15:31:49 ith Exp $

    Provides generic class CosmologicalModel that can be used as a base for explicit models."""

from __future__ import division # Get rid of integer division problems, i.e. 1/2=0
import numpy as N
import pylab as P
import rk4
import sys

class ModelError(StandardError):
    """Generic error for model simulating. Attributes include current results stack."""

    def __init__(self, expression, tresult=None, yresult=None):
        self.expression = expression
        self.tresult = tresult
        self.yresults = yresult

class CosmologicalModel:
    """Generic class for cosmological model simulations.
    Has no derivs function to pass to ode solver, but does have
    plotting function and initial conditions check."""

    solverlist = ["odeint", "rkdriver_dumb"]

    def __init__(self, ystart, tstart, tend, tstep_wanted, tstep_min, eps=1.0e-6, dxsav=0.0, solver="odeint"):
        """Initialize model variables, some with default values. Default solver is odeint."""
        if not ystart:
            self.ystart = 0.0
        else:
            self.ystart = ystart

        if tstart < tend:
            self.tstart, self.tend = tstart, tend
        elif tstart==tend:
            raise ValueError, "End time is the same as start time!"
        else:
            raise ValueError, "Ending time is before starting time!"

        if tstep_wanted >= tstep_min:
            self.tstep_wanted, self.tstep_min = tstep_wanted, tstep_min
        else:
            raise ValueError, "Desired time step is smaller than specified minimum!"

        if eps < 1:
            self.eps = eps
        else:
            raise ValueError, "Not enough accuracy! Change eps < 1."

        if dxsav >=0.0:
            self.dxsav = dxsav
        else:
            raise ValueError, "Data saving step must be 0 or positive!"

        if solver in self.solverlist:
            self.solver = solver
        else:
            raise ValueError, "Solver not recognized!"

        self.tresult = None
        self.yresult = None
        self.modelrun = False

        self.plottitle = "A generic Cosmological Model"
        self.tname = "Time"
        self.ynames = ["First dependent variable"]

    def derivs(self, t, yarray):
        pass

    def run(self):
        if self.solver == "odeint":
            try:
                self.tresult, self.yresult, self.nok, self.nbad = rk4.odeint(self.ystart, self.tstart,
                    self.tend, self.tstep_wanted, self.tstep_min, self.derivs, self.eps, self.dxsav)
            except IndexError, e:
                raise ModelError(e.message, self.tresult, self.yresult)
            self.modelrun = True
            return

        if self.solver == "rkdriver_dumb":
            #Loosely estimate number of steps based on requested step size
            nstep = ceil((self.tend - self.tstart)/self.tstep_wanted)
            try:
                self.tresult, self.yresult = rk4.rkdriver_dumb(self.ystart, self.tstart, self.tend, nstep, self.derivs)
            except Error, e:
                raise ModelError(e.message, self.tresult, self.yresult)
            self.modelrun = True
            return

        #Don't know how to handle any other solvers!
        raise ModelError("Unknown solver!")

    def plotresults(self, saveplot = False):
        if not self.modelrun:
            raise ModelError("Model has not been run yet, cannot plot results!", self.tresult, self.yresult)

        P.plot(self.tresult, self.yresult)
        P.xlabel(self.tname)
        P.ylabel(self.ynames[0])
        P.title(self.plottitle)
        P.show()

class TestModel(CosmologicalModel):
    """Test class defining a very simple function"""
    def __init__(self, ystart=1.0, tstart=0.0, tend=1.0, tstep_wanted=0.01, tstep_min=0.001):
        CosmologicalModel.__init__(self, ystart, tstart, tend, tstep_wanted, tstep_min)

        self.plottitle = r"TestModel: $\frac{dy}{dt} = t$"
        self.tname = "Time"
        self.ynames = ["Simple y"]

    def derivs(self, t, y):
        return N.cos(t)

<commit_msg>Introduced Basic model, which now outputs quite a nice graph.<commit_after>"""Cosmological Model simulations by Ian Huston
    $Id: cosmomodels.py,v 1.3 2008/04/21 17:49:26 ith Exp $

    Provides generic class CosmologicalModel that can be used as a base for explicit models."""

from __future__ import division # Get rid of integer division problems, i.e. 1/2=0
import numpy as N
import pylab as P
import rk4
import sys

class ModelError(StandardError):
    """Generic error for model simulating. Attributes include current results stack."""

    def __init__(self, expression, tresult=None, yresult=None):
        self.expression = expression
        self.tresult = tresult
        self.yresult = yresult

class CosmologicalModel:
    """Generic class for cosmological model simulations.
    Has no derivs function to pass to ode solver, but does have
    plotting function and initial conditions check."""

    solverlist = ["odeint", "rkdriver_dumb"]

    def __init__(self, ystart, tstart, tend, tstep_wanted, tstep_min, eps=1.0e-6, dxsav=0.0, solver="odeint"):
        """Initialize model variables, some with default values. Default solver is odeint."""

        self.ystart = ystart

        if tstart < tend:
            self.tstart, self.tend = tstart, tend
        elif tstart==tend:
            raise ValueError, "End time is the same as start time!"
        else:
            raise ValueError, "Ending time is before starting time!"

        if tstep_wanted >= tstep_min:
            self.tstep_wanted, self.tstep_min = tstep_wanted, tstep_min
        else:
            raise ValueError, "Desired time step is smaller than specified minimum!"

        if eps < 1:
            self.eps = eps
        else:
            raise ValueError, "Not enough accuracy! Change eps < 1."

        if dxsav >=0.0:
            self.dxsav = dxsav
        else:
            raise ValueError, "Data saving step must be 0 or positive!"

        if solver in self.solverlist:
            self.solver = solver
        else:
            raise ValueError, "Solver not recognized!"

        self.tresult = None
        self.yresult = None
        self.modelrun = False

        self.plottitle = "A generic Cosmological Model"
        self.tname = "Time"
        self.ynames = ["First dependent variable"]

    def derivs(self, t, yarray):
        """Return an array of derivatives of the dependent variables yarray at timestep t"""
        pass

    def run(self):
        """Execute a simulation run using teh parameters already provided."""

        if self.solver == "odeint":
            try:
                self.tresult, self.yresult, self.nok, self.nbad = rk4.odeint(self.ystart, self.tstart,
                    self.tend, self.tstep_wanted, self.tstep_min, self.derivs, self.eps, self.dxsav)
                self.yresult = N.hsplit(self.yresult, self.yresult.shape[1])
            except rk4.SimRunError:
                raise
            except Error, e:
                raise ModelError(e.message, self.tresult, self.yresult)
            self.modelrun = True
            return

        if self.solver == "rkdriver_dumb":
            #Loosely estimate number of steps based on requested step size
            nstep = ceil((self.tend - self.tstart)/self.tstep_wanted)
            try:
                self.tresult, self.yresult = rk4.rkdriver_dumb(self.ystart, self.tstart, self.tend, nstep, self.derivs)
            except Error, e:
                raise ModelError(e.message, self.tresult, self.yresult)
            self.modelrun = True
            return

        #Don't know how to handle any other solvers!
        raise ModelError("Unknown solver!")

    def plotresults(self, saveplot = False):
        """Plot results of simulation run on a graph."""

        if not self.modelrun:
            raise ModelError("Model has not been run yet, cannot plot results!", self.tresult, self.yresult)

        P.plot(self.tresult, self.yresult)
        P.xlabel(self.tname)
        P.ylabel(self.ynames[0])
        P.title(self.plottitle)
        P.show()

class TestModel(CosmologicalModel):
    """Test class defining a very simple function"""
    def __init__(self, ystart=1.0, tstart=0.0, tend=1.0, tstep_wanted=0.01, tstep_min=0.001):
        CosmologicalModel.__init__(self, ystart, tstart, tend, tstep_wanted, tstep_min)

        self.plottitle = r"TestModel: $\frac{dy}{dt} = t$"
        self.tname = "Time"
        self.ynames = ["Simple y"]

    def derivs(self, t, y):
        """Very simple set of ODEs"""
        return N.cos(t)

class BasicBgModel(CosmologicalModel):
    """Basic model with background equations
        Array of dependent variables y is given by:

       y[0] - \phi_0 : Background inflaton
       y[1] - d\phi_0/d\eta : First deriv of \phi
       y[2] - a : Scale Factor
    """

    def __init__(self, ystart=N.array([0.1,0.1,0.1]), tstart=0.0, tend=120.0, tstep_wanted=0.02, tstep_min=0.0001):
        CosmologicalModel.__init__(self, ystart, tstart, tend, tstep_wanted, tstep_min)

        self.plottitle = "Basic Cosmological Model"
        self.tname = "Conformal time"
        self.ynames = [r"Inflaton $\phi$", "", r"Scale factor $a$"]

    def derivs(self, t, y):
        """Basic background equations of motion.
            dydx[0] = dy[0]/d\eta etc"""

        #Mass of inflaton in Planck masses
        mass = 0.1
        mass2 = mass**2

        #potential U = 1/2 m^2 \phi^2
        U = 0.5*(mass2)*(y[0]**2)
        #deriv of potential wrt \phi
        dUdphi =  (mass2)*y[0]

        #factor in eom [1/3 a^2 U_0]^{1/2}
        Ufactor = N.sqrt((1.0/3.0)*(y[2]**2)*U)

        #Set derivatives
        dydx = N.zeros(3)

        #d\phi_0/d\eta = y_1
        dydx[0] = y[1]

        #dy_1/d\eta = -2
        dydx[1] = -2*Ufactor*y[1] - (y[2]**2)*dUdphi

        #da/d\eta = [1/3 a^2 U_0]^{1/2}*a
        dydx[2] = Ufactor*y[2]

        return dydx

    def plotresults(self, saveplot = False):
        """Plot results of simulation run on a graph."""

        if not self.modelrun:
            raise ModelError("Model has not been run yet, cannot plot results!", self.tresult, self.yresult)

        P.plot(self.tresult, self.yresult[0], self.tresult, self.yresult[1])
        P.xlabel(self.tname)
        P.ylabel("")
        P.legend((self.ynames[0], self.ynames[2]))
        P.title(self.plottitle)
        P.show()<|endoftext|>


<commit_before>from django.conf import settings
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models.signals import post_syncdb
from django.utils.translation import ugettext_noop as _

if not settings.PVW_RSR:
    if "notification" in settings.INSTALLED_APPS:
        from notification import models as notification

        def create_notice_types(app, created_models, verbosity, **kwargs):
            print "Creating notice types for SMS updates"
            notification.create_notice_type(
                "phone_added",
                _("Phone number added"),
                _("Your mobile phone has been added to your user profile")
            )
            notification.create_notice_type(
                "phone_confirmed",
                _("Phone confirmed"),
                _("Your mobile phone number has been confirmed for use in updating RSR projects")
            )
            notification.create_notice_type(
                "reporting_enabled",
                _("SMS updates enabled for project"),
                _("You can now send SMS-updates to an RSR project")
            )
            notification.create_notice_type(
                "reporting_cancelled",
                _("SMS updates cancelled"),
                _("SMS-updates to an RSR project has been cancelled")
            )
            notification.create_notice_type(
                "phone_disabled",
                _("Phone disabled"),
                _("SMS-updates from your mobile phone are no longer accepted")
            )
            notification.create_notice_type(
                "update_received",
                _("Update received"),
                _("Akvo has received an update from your phone")
            )

        post_syncdb.connect(create_notice_types, sender=notification)
    else:
        print "Skipping creation of NoticeTypes as notification app not found"

    def create_model_instance(model, **kwargs):
        handle = kwargs.pop('handle')
        try:
            existing_instance = model.objects.get(**handle)
            updated = False
            for key in kwargs.keys():
                if kwargs[key] != getattr(existing_instance, key, False):
                    setattr(existing_instance, key, kwargs[key])
                    updated = True
            if updated:
                existing_instance.save()
                #if verbosity > 1:
                #    print "Updated %s %s" % (label, existing_instance)
            return existing_instance
        except model.DoesNotExist:
            kwargs.update(handle)
            return model.objects.create(**kwargs)
            #if verbosity > 1:
            #    print "Created %s NoticeType" % label

    #workflow for UserProfile
    #principalrolerelation group SMS updater - role SMS updater
    #principalrolerelation group SMS manager - role SMS manager
    #principalrolerelation group SMS manager - role SMS updater

    #if "permissions" in settings.INSTALLED_APPS:
    #    from permissions.utils import register_role
    #
    #    def create_permissions_objects(app, created_models, verbosity, **kwargs):
    #        #register_role('SMS Updater')
    #        print "Done creating permissions objects"
    #
    #    post_syncdb.connect(create_permissions_objects, sender=permissions)
    #else:
    #    print "Skipping creation of Permissions objects as permissions app not found"
    #

    from django.contrib.auth import models as auth_models
    def create_workflow_groups(sender, **kwargs):
        sms_updater_group = create_model_instance(Group, **{'handle': {'name': UserProfile.GROUP_SMS_UPDATER}})
        sms_manager_group = create_model_instance(Group, **{'handle': {'name': UserProfile.GROUP_SMS_MANAGER}})
        print "Done creating groups"

    post_syncdb.connect(create_workflow_groups, sender=auth_models)

    if "workflows" in settings.INSTALLED_APPS:
        from workflows import models as workflows
        from workflows.utils import set_workflow_for_model
        from .models import UserProfile

        def create_workflows_model_relation(app, created_models, verbosity, **kwargs):
            set_workflow_for_model(ContentType.objects.get_for_model(UserProfile), UserProfile.WORKFLOW_SMS_UPDATE)
            print "Created workflow relation for UserProfile"

        post_syncdb.connect(create_workflows_model_relation, sender=workflows)
    else:
        print "Skipping creation of Workflow objects as workflows app not found"

    if "permissions" in settings.INSTALLED_APPS:
        from permissions import models as permissions
        from permissions.utils import add_role
        from .models import UserProfile

        def create_principal_role_relations(sender, **kwargs):
            try:
                sms_updater_group = Group.objects.get(name=UserProfile.GROUP_SMS_UPDATER)
                sms_manager_group = Group.objects.get(name=UserProfile.GROUP_SMS_MANAGER)
                sms_updater_role  = permissions.Role.objects.get(name=UserProfile.GROUP_SMS_UPDATER)
                sms_manager_role  = permissions.Role.objects.get(name=UserProfile.GROUP_SMS_MANAGER)

                add_role(sms_updater_group, sms_updater_role)
                add_role(sms_manager_group, sms_updater_role)
                add_role(sms_manager_group, sms_manager_role)

                print "Created principal role relations for %s and %s" % (UserProfile.GROUP_SMS_MANAGER, UserProfile.GROUP_SMS_UPDATER)
            except:
                print "Role relations could not be created since fixtures are missing. Run manage.py syncdb again please!"

        post_syncdb.connect(create_principal_role_relations, sender=permissions)
    else:
        print "Skipping creation of Roles as permissions app was not found"

    if "akvo.rsr" in settings.INSTALLED_APPS:
        from akvo.rsr import models as rsr
        def create_limited_change_permissions(sender, **kwargs):
            print "Adding RSR limited permissions"
            print
            models = [
                rsr.Organisation, rsr.Project,
                rsr.SmsReporter, rsr.UserProfile, rsr.PartnerSite
            ]
            for model in models:
                opts = model._meta
                model_name = opts.object_name.lower()
                permission, created = Permission.objects.get_or_create(
                    codename=u"rsr_limited_change_%s" % model_name,
                    defaults={
                        'name': u'RSR limited change %s' % model_name,
                        'content_type_id': ContentType.objects.get_for_model(model).id,
                    }
                )
                if created:
                    print 'Created RSR limited change %s Permission' % model_name
                else:
                    print 'RSR limited change %s Permission already exists in the database' % model_name

        post_syncdb.connect(create_limited_change_permissions, sender=rsr)

#if "workflow" in settings.INSTALLED_APPS:
#
#    from workflow import models as workflow
#
#    def create_workflow_objects(app, created_models, verbosity, **kwargs):
#        try:
#            system_acct = User.objects.get(username='system')
#        except:
#            print "Can't create workflow objects without User 'system'."
#            return
#        # Role
#        role1_data = {
#            'handle':       {'name': 'SMS Updater'},
#            'description':  'Allows the user to create project updates via SMS.'
#        }
#        role1 = create_model_instance(workflow.Role, **role1_data)
#        # EventType
#        event_type1_data = {
#            'handle':       {'name': 'UserProfile change'},
#            'description':  "A change in a user's UserProfile has occured.",
#        }
#        event_type1 = create_model_instance(workflow.EventType, **event_type1_data)
#        event_type2_data = {
#            'handle':       {'name': 'Send email'},
#            'description':  "Send an email to a user.",
#        }
#        event_type2 = create_model_instance(workflow.EventType, **event_type2_data)
#        event_type3_data = {
#            'handle':       {'name': 'Send SMS'},
#            'description':  "Send an SMS to a user's mobile phone.",
#        }
#        event_type3 = create_model_instance(workflow.EventType, **event_type3_data)
#        # Workflow
#        workflow1_data = {
#            'handle':       {'name': 'SMS update'},
#            'slug':         'sms-update',
#            'description':  'Workflow for setting up a user to do project updates via SMS.',
#            'status':       workflow.Workflow.DEFINITION,
#            'created_by':   system_acct,
#        }
#        workflow1 = create_model_instance(workflow.Workflow, **workflow1_data)
#        # State
#        #state1_data = {
#        #    'handle':           {'name': 'Phone number added test'},
#        #    'description':      'A phone number is added to the UserProfile',
#        #    'is_start_state':   True,
#        #    'is_end_state':     False,
#        #    'workflow':         workflow1,
#        #    'roles':            role1,
#        #}
#        #state1 = create_model_instance(workflow.State, **state1_data)
#
#
#    post_syncdb.connect(create_workflow_objects, sender=notification)
#else:
#    print "Skipping creation of Workflow objects as workflow app not found"
<commit_msg>Removed PVW_RSR branching from management.py.<commit_after>from django.conf import settings
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models.signals import post_syncdb
from django.utils.translation import ugettext_noop as _

if "notification" in settings.INSTALLED_APPS:
    from notification import models as notification

    def create_notice_types(app, created_models, verbosity, **kwargs):
        print "Creating notice types for SMS updates"
        notification.create_notice_type(
            "phone_added",
            _("Phone number added"),
            _("Your mobile phone has been added to your user profile")
        )
        notification.create_notice_type(
            "phone_confirmed",
            _("Phone confirmed"),
            _("Your mobile phone number has been confirmed for use in updating RSR projects")
        )
        notification.create_notice_type(
            "reporting_enabled",
            _("SMS updates enabled for project"),
            _("You can now send SMS-updates to an RSR project")
        )
        notification.create_notice_type(
            "reporting_cancelled",
            _("SMS updates cancelled"),
            _("SMS-updates to an RSR project has been cancelled")
        )
        notification.create_notice_type(
            "phone_disabled",
            _("Phone disabled"),
            _("SMS-updates from your mobile phone are no longer accepted")
        )
        notification.create_notice_type(
            "update_received",
            _("Update received"),
            _("Akvo has received an update from your phone")
        )
    post_syncdb.connect(create_notice_types, sender=notification)

    def create_model_instance(model, **kwargs):
        handle = kwargs.pop('handle')
        try:
            existing_instance = model.objects.get(**handle)
            updated = False
            for key in kwargs.keys():
                if kwargs[key] != getattr(existing_instance, key, False):
                    setattr(existing_instance, key, kwargs[key])
                    updated = True
            if updated:
                existing_instance.save()
                #if verbosity > 1:
                #    print "Updated %s %s" % (label, existing_instance)
            return existing_instance
        except model.DoesNotExist:
            kwargs.update(handle)
            return model.objects.create(**kwargs)
            #if verbosity > 1:
            #    print "Created %s NoticeType" % label

    #workflow for UserProfile
    #principalrolerelation group SMS updater - role SMS updater
    #principalrolerelation group SMS manager - role SMS manager
    #principalrolerelation group SMS manager - role SMS updater

    #if "permissions" in settings.INSTALLED_APPS:
    #    from permissions.utils import register_role
    #
    #    def create_permissions_objects(app, created_models, verbosity, **kwargs):
    #        #register_role('SMS Updater')
    #        print "Done creating permissions objects"
    #
    #    post_syncdb.connect(create_permissions_objects, sender=permissions)
    #else:
    #    print "Skipping creation of Permissions objects as permissions app not found"
    #

    from django.contrib.auth import models as auth_models
    def create_workflow_groups(sender, **kwargs):
        sms_updater_group = create_model_instance(Group, **{'handle': {'name': UserProfile.GROUP_SMS_UPDATER}})
        sms_manager_group = create_model_instance(Group, **{'handle': {'name': UserProfile.GROUP_SMS_MANAGER}})
        print "Done creating groups"

    post_syncdb.connect(create_workflow_groups, sender=auth_models)

    if "workflows" in settings.INSTALLED_APPS:
        from workflows import models as workflows
        from workflows.utils import set_workflow_for_model
        from .models import UserProfile

        def create_workflows_model_relation(app, created_models, verbosity, **kwargs):
            set_workflow_for_model(ContentType.objects.get_for_model(UserProfile), UserProfile.WORKFLOW_SMS_UPDATE)
            print "Created workflow relation for UserProfile"

        post_syncdb.connect(create_workflows_model_relation, sender=workflows)
    else:
        print "Skipping creation of Workflow objects as workflows app not found"

    if "permissions" in settings.INSTALLED_APPS:
        from permissions import models as permissions
        from permissions.utils import add_role

        def create_principal_role_relations(sender, **kwargs):
            try:
                sms_updater_group = Group.objects.get(name=UserProfile.GROUP_SMS_UPDATER)
                sms_manager_group = Group.objects.get(name=UserProfile.GROUP_SMS_MANAGER)
                sms_updater_role  = permissions.Role.objects.get(name=UserProfile.GROUP_SMS_UPDATER)
                sms_manager_role  = permissions.Role.objects.get(name=UserProfile.GROUP_SMS_MANAGER)

                add_role(sms_updater_group, sms_updater_role)
                add_role(sms_manager_group, sms_updater_role)
                add_role(sms_manager_group, sms_manager_role)

                print "Created principal role relations for %s and %s" % (UserProfile.GROUP_SMS_MANAGER, UserProfile.GROUP_SMS_UPDATER)
            except:
                print "Role relations could not be created since fixtures are missing. Run manage.py syncdb again please!"

        post_syncdb.connect(create_principal_role_relations, sender=permissions)
    else:
        print "Skipping creation of Roles as permissions app was not found"

    if "akvo.rsr" in settings.INSTALLED_APPS:
        from akvo.rsr import models as rsr
        def create_limited_change_permissions(sender, **kwargs):
            print "Adding RSR limited permissions"
            print
            models = [
                rsr.Organisation, rsr.Project,
                rsr.SmsReporter, rsr.UserProfile, rsr.PartnerSite
            ]
            for model in models:
                opts = model._meta
                model_name = opts.object_name.lower()
                permission, created = Permission.objects.get_or_create(
                    codename=u"rsr_limited_change_%s" % model_name,
                    defaults={
                        'name': u'RSR limited change %s' % model_name,
                        'content_type_id': ContentType.objects.get_for_model(model).id,
                    }
                )
                if created:
                    print 'Created RSR limited change %s Permission' % model_name
                else:
                    print 'RSR limited change %s Permission already exists in the database' % model_name

        post_syncdb.connect(create_limited_change_permissions, sender=rsr)

#if "workflow" in settings.INSTALLED_APPS:
#
#    from workflow import models as workflow
#
#    def create_workflow_objects(app, created_models, verbosity, **kwargs):
#        try:
#            system_acct = User.objects.get(username='system')
#        except:
#            print "Can't create workflow objects without User 'system'."
#            return
#        # Role
#        role1_data = {
#            'handle':       {'name': 'SMS Updater'},
#            'description':  'Allows the user to create project updates via SMS.'
#        }
#        role1 = create_model_instance(workflow.Role, **role1_data)
#        # EventType
#        event_type1_data = {
#            'handle':       {'name': 'UserProfile change'},
#            'description':  "A change in a user's UserProfile has occured.",
#        }
#        event_type1 = create_model_instance(workflow.EventType, **event_type1_data)
#        event_type2_data = {
#            'handle':       {'name': 'Send email'},
#            'description':  "Send an email to a user.",
#        }
#        event_type2 = create_model_instance(workflow.EventType, **event_type2_data)
#        event_type3_data = {
#            'handle':       {'name': 'Send SMS'},
#            'description':  "Send an SMS to a user's mobile phone.",
#        }
#        event_type3 = create_model_instance(workflow.EventType, **event_type3_data)
#        # Workflow
#        workflow1_data = {
#            'handle':       {'name': 'SMS update'},
#            'slug':         'sms-update',
#            'description':  'Workflow for setting up a user to do project updates via SMS.',
#            'status':       workflow.Workflow.DEFINITION,
#            'created_by':   system_acct,
#        }
#        workflow1 = create_model_instance(workflow.Workflow, **workflow1_data)
#        # State
#        #state1_data = {
#        #    'handle':           {'name': 'Phone number added test'},
#        #    'description':      'A phone number is added to the UserProfile',
#        #    'is_start_state':   True,
#        #    'is_end_state':     False,
#        #    'workflow':         workflow1,
#        #    'roles':            role1,
#        #}
#        #state1 = create_model_instance(workflow.State, **state1_data)
#
#
#    post_syncdb.connect(create_workflow_objects, sender=notification)
#else:
#    print "Skipping creation of Workflow objects as workflow app not found"
<|endoftext|>


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

"""
    Akvo RSR is covered by the GNU Affero General Public License.
    See more details in the license.txt file located at the root folder of the
    Akvo RSR module. For additional details on the GNU license please
    see < http://www.gnu.org/licenses/agpl.html >.
"""

from django.conf import settings
from django.contrib.sites.models import Site
from django.http import Http404

from djangotoolbox.utils import make_tls_property

SITE_ID = settings.__dict__['_wrapped'].__class__.SITE_ID = make_tls_property()

class PartnerSitesRouterMiddleware(object):
    def process_request(self, request, organisation_id=None, site=None):
        domain = request.get_host().split(':')[0]
        local_domains = ('localhost', '127.0.0.1')
        if domain.endswith('.dev') or domain in local_domains:  # local development
            if domain in local_domains:
                domain = 'akvo.dev'
            try:
                site = Site.objects.get(domain=domain)
            except:
                try:
                    site = Site.objects.get(domain='akvo.dev')
                except:
                    raise Http404
        elif domain.endswith('.akvo.org'):  # Akvo domain
            try:
                site = Site.objects.get(domain=domain)
            except:
                try:
                    site = Site.objects.get(domain='www.akvo.org')
                except:
                    raise Http404
        else:  # probably a partner-nominated domain
            try:
                site = Site.objects.get(partner_domain=domain)
            except:
                raise Http404
        if site is not None and site.enabled:
            SITE_ID.value = site.id
            if site.organisation is not None:
                organisation_id = site.organisation.id
                request.urlconf = 'akvo.urls_partner_sites'
        request.organisation_id = organisation_id
        return
<commit_msg>Added PVW_RSR check to PartnerSitesRouterMiddleware.<commit_after># -*- coding: utf-8 -*-

"""
    Akvo RSR is covered by the GNU Affero General Public License.
    See more details in the license.txt file located at the root folder of the
    Akvo RSR module. For additional details on the GNU license please
    see < http://www.gnu.org/licenses/agpl.html >.
"""

from django.conf import settings
from django.contrib.sites.models import Site
from django.http import Http404

from djangotoolbox.utils import make_tls_property

SITE_ID = settings.__dict__['_wrapped'].__class__.SITE_ID = make_tls_property()

class PartnerSitesRouterMiddleware(object):
    def process_request(self, request, organisation_id=None, site=None):
        if settings.PVW_RSR:
            return
        domain = request.get_host().split(':')[0]
        local_domains = ('localhost', '127.0.0.1')
        if domain.endswith('.dev') or domain in local_domains:  # local development
            if domain in local_domains:
                domain = 'akvo.dev'
            try:
                site = Site.objects.get(domain=domain)
            except:
                try:
                    site = Site.objects.get(domain='akvo.dev')
                except:
                    raise Http404
        elif domain.endswith('.akvo.org'):  # Akvo domain
            try:
                site = Site.objects.get(domain=domain)
            except:
                try:
                    site = Site.objects.get(domain='www.akvo.org')
                except:
                    raise Http404
        else:  # probably a partner-nominated domain
            try:
                site = Site.objects.get(partner_domain=domain)
            except:
                raise Http404
        if site is not None and site.enabled:
            SITE_ID.value = site.id
            if site.organisation is not None:
                organisation_id = site.organisation.id
                request.urlconf = 'akvo.urls_partner_sites'
        request.organisation_id = organisation_id
        return
<|endoftext|>


<commit_before>import time
import logging
from banal import hash_data
from datetime import datetime
from flask_babel import get_locale
from flask import request, Response, Blueprint

from aleph import signals, __version__
from aleph.core import settings

log = logging.getLogger(__name__)
blueprint = Blueprint('cache', __name__)

class NotModified(Exception):
    """Converts to HTTP status 304."""
    pass

def handle_not_modified(exc):
    return Response(status=304)

def enable_cache(vary_user=True, vary=None):
    """Enable caching in the context of a view.

    If desired, instructions on the cache parameters can be included, such as
    if the data is fit for public caches (default: no, vary_user) and what
    values to include in the generation of an etag.
    """
    if not settings.CACHE:
        return

    request._http_cache = True
    request._http_revalidate = vary is not None
    args = sorted(set(request.args.items()))
    cache_parts = [args, vary, request._app_locale]

    if vary_user and request.authz.logged_in:
        cache_parts.extend((request.authz.roles))
        request._http_private = True

    request._http_etag = hash_data(cache_parts)
    if request._http_etag in request.if_none_match:
        raise NotModified()

def tag_request(**kwargs):
    """Store metadata for structured log output."""
    for tag, value in kwargs.items():
        if value is not None:
            request._log_tags[tag] = value

@blueprint.before_app_request
def setup_request():
    """Set some request attributes at the beginning of the request.
    By default, caching will be disabled."""
    request._begin_time = time.time()
    request._app_locale = str(get_locale())
    request.session_id = request.headers.get('X-Aleph-Session')
    request._http_cache = False
    request._http_private = False
    request._http_revalidate = False
    request._http_etag = None
    request._log_tags = {}

@blueprint.after_app_request
def finalize_response(resp):
    """Post-request processing to set cache parameters."""
    generate_request_log(resp)
    # set X-Content-Type-Options: "nosniff"
    resp.headers['X-Content-Type-Options'] = 'nosniff'
    if resp.is_streamed:
        # http://wiki.nginx.org/X-accel#X-Accel-Buffering
        resp.headers['X-Accel-Buffering'] = 'no'

    if not request._http_cache:
        resp.cache_control.no_cache = True
        return resp

    if request.method != 'GET' or resp.status_code != 200:
        resp.cache_control.no_cache = True
        return resp

    resp.cache_control.public = True
    resp.vary.add('Accept-Language')
    resp.vary.add('Authorization')

    if request._http_etag:
        resp.set_etag(request._http_etag)
        if request._http_revalidate:
            resp.cache_control.must_revalidate = request._http_revalidate
        else:
            resp.cache_control.max_age = 3600 * 12
    else:
        resp.expires = -1

    if request._http_private:
        resp.cache_control.public = None
        resp.cache_control.private = True
    return resp

def generate_request_log(resp):
    """Collect data about the request for analytical purposes."""
    payload = {
        'v': __version__,
        'session_id': request.session_id,
        'method': request.method,
        'endpoint': request.endpoint,
        'referrer': request.referrer,
        'ip': request.remote_addr,
        'ua': str(request.user_agent),
        'time': datetime.utcnow().isoformat(),
        'url': request.url,
        'path': request.full_path,
        'status': resp.status_code,
        'locale': request._app_locale
    }
    if hasattr(request, 'authz'):
        payload['role_id'] = request.authz.id
    if hasattr(request, '_begin_time'):
        took = time.time() - request._begin_time
        payload['took'] = int(took * 1000)
    tags = dict(request.view_args or ())
    tags.update(request._log_tags)
    for tag, value in tags.items():
        if value is not None and tag not in payload:
            payload[tag] = value

    signals.handle_request_log.send(payload=payload)
<commit_msg>add strict Feature-Policy<commit_after>import time
import logging
from banal import hash_data
from datetime import datetime
from flask_babel import get_locale
from flask import request, Response, Blueprint

from aleph import signals, __version__
from aleph.core import settings

log = logging.getLogger(__name__)
blueprint = Blueprint('cache', __name__)

class NotModified(Exception):
    """Converts to HTTP status 304."""
    pass

def handle_not_modified(exc):
    return Response(status=304)

def enable_cache(vary_user=True, vary=None):
    """Enable caching in the context of a view.

    If desired, instructions on the cache parameters can be included, such as
    if the data is fit for public caches (default: no, vary_user) and what
    values to include in the generation of an etag.
    """
    if not settings.CACHE:
        return

    request._http_cache = True
    request._http_revalidate = vary is not None
    args = sorted(set(request.args.items()))
    cache_parts = [args, vary, request._app_locale]

    if vary_user and request.authz.logged_in:
        cache_parts.extend((request.authz.roles))
        request._http_private = True

    request._http_etag = hash_data(cache_parts)
    if request._http_etag in request.if_none_match:
        raise NotModified()

def tag_request(**kwargs):
    """Store metadata for structured log output."""
    for tag, value in kwargs.items():
        if value is not None:
            request._log_tags[tag] = value

@blueprint.before_app_request
def setup_request():
    """Set some request attributes at the beginning of the request.
    By default, caching will be disabled."""
    request._begin_time = time.time()
    request._app_locale = str(get_locale())
    request.session_id = request.headers.get('X-Aleph-Session')
    request._http_cache = False
    request._http_private = False
    request._http_revalidate = False
    request._http_etag = None
    request._log_tags = {}

@blueprint.after_app_request
def finalize_response(resp):
    """Post-request processing to set cache parameters."""
    generate_request_log(resp)
    # set X-Content-Type-Options: "nosniff"
    resp.headers['X-Content-Type-Options'] = "nosniff"
    resp.headers['Feature-Policy'] = "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'"
    if resp.is_streamed:
        # http://wiki.nginx.org/X-accel#X-Accel-Buffering
        resp.headers['X-Accel-Buffering'] = 'no'

    if not request._http_cache:
        resp.cache_control.no_cache = True
        return resp

    if request.method != 'GET' or resp.status_code != 200:
        resp.cache_control.no_cache = True
        return resp

    resp.cache_control.public = True
    resp.vary.add('Accept-Language')
    resp.vary.add('Authorization')

    if request._http_etag:
        resp.set_etag(request._http_etag)
        if request._http_revalidate:
            resp.cache_control.must_revalidate = request._http_revalidate
        else:
            resp.cache_control.max_age = 3600 * 12
    else:
        resp.expires = -1

    if request._http_private:
        resp.cache_control.public = None
        resp.cache_control.private = True
    return resp

def generate_request_log(resp):
    """Collect data about the request for analytical purposes."""
    payload = {
        'v': __version__,
        'session_id': request.session_id,
        'method': request.method,
        'endpoint': request.endpoint,
        'referrer': request.referrer,
        'ip': request.remote_addr,
        'ua': str(request.user_agent),
        'time': datetime.utcnow().isoformat(),
        'url': request.url,
        'path': request.full_path,
        'status': resp.status_code,
        'locale': request._app_locale
    }
    if hasattr(request, 'authz'):
        payload['role_id'] = request.authz.id
    if hasattr(request, '_begin_time'):
        took = time.time() - request._begin_time
        payload['took'] = int(took * 1000)
    tags = dict(request.view_args or ())
    tags.update(request._log_tags)
    for tag, value in tags.items():
        if value is not None and tag not in payload:
            payload[tag] = value

    signals.handle_request_log.send(payload=payload)
<|endoftext|>


<commit_before>
import os
import sys
import time
import datetime
import pytz
import json

from uuid import uuid4
from email import utils

DEFAULT_SEVERITY = "normal"  # "normal", "ok" or "clear"
DEFAULT_TIMEOUT = 86400

prog = os.path.basename(sys.argv[0])

class Alert(object):

    def __init__(self, resource, event, **kwargs):

        if not resource:
            raise ValueError('Missing mandatory value for "resource"')
        if not event:
            raise ValueError('Missing mandatory value for "event"')
        if any(['.' in key for key in kwargs.get('attributes', dict()).keys()])\
                or any(['$' in key for key in kwargs.get('attributes', dict()).keys()]):
            raise ValueError('Attribute keys must not contain "." or "$"')

        self.id = kwargs.get('id', str(uuid4()))
        self.resource = resource
        self.event = event
        self.environment = kwargs.get('environment', None) or ""
        self.severity = kwargs.get('severity', None) or DEFAULT_SEVERITY
        self.correlate = kwargs.get('correlate', None) or list()
        if self.correlate and event not in self.correlate:
            self.correlate.append(event)
        self.status = kwargs.get('status', None) or "unknown"
        self.service = kwargs.get('service', None) or list()
        self.group = kwargs.get('group', None) or "Misc"
        self.value = kwargs.get('value', None) or "n/a"
        self.text = kwargs.get('text', None) or ""
        self.tags = kwargs.get('tags', None) or list()
        self.attributes = kwargs.get('attributes', None) or dict()
        self.origin = kwargs.get('origin', None) or '%s/%s' % (prog, os.uname()[1])
        self.event_type = kwargs.get('event_type', kwargs.get('type', None)) or "exceptionAlert"
        self.create_time = kwargs.get('create_time', None) or datetime.datetime.utcnow()
        self.receive_time = None
        self.timeout = kwargs.get('timeout', None) or DEFAULT_TIMEOUT
        self.raw_data = kwargs.get('raw_data', kwargs.get('rawData', None)) or ""

    def get_id(self, short=False):

        if short:
            return self.id[:8]
        else:
            return self.id

    def get_header(self):

        return {
            "origin": self.origin,
            "type": self.event_type,
            "correlation-id": self.id
        }

    def get_body(self):

        return {
            'id': self.id,
            'resource': self.resource,
            'event': self.event,
            'environment': self.environment,
            'severity': self.severity,
            'correlate': self.correlate,
            'status': self.status,
            'service': self.service,
            'group': self.group,
            'value': self.value,
            'text': self.text,
            'tags': self.tags,
            'attributes': self.attributes,
            'origin': self.origin,
            'type': self.event_type,
            'createTime': self.create_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.create_time.microsecond // 1000),
            'timeout': self.timeout,
            'rawData': self.raw_data
        }

    def get_type(self):
        return self.event_type

    def receive_now(self):
        self.receive_time = datetime.datetime.utcnow()

    def __repr__(self):
        return 'Alert(id=%r, environment=%r, resource=%r, event=%r, severity=%r, status=%r)' % (
            self.id, self.environment, self.resource, self.event, self.severity, self.status)

    def __str__(self):
        return json.dumps(self.get_body(), indent=4)

    @staticmethod
    def parse_alert(alert):

        try:
            alert = json.loads(alert)
        except ValueError, e:
            raise ValueError('Could not parse alert - %s: %s' % (e, alert))

        for k, v in alert.iteritems():
            if k in ['createTime', 'receiveTime', 'lastReceiveTime', 'expireTime']:
                try:
                    alert[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%fZ')
                except ValueError, e:
                    raise ValueError('Could not parse date time string: %s' % e)

        return Alert(
            resource=alert.get('resource', None),
            event=alert.get('event', None),
            environment=alert.get('environment', None),
            severity=alert.get('severity', None),
            correlate=alert.get('correlate', list()),
            status=alert.get('status', None),
            service=alert.get('service', list()),
            group=alert.get('group', None),
            value=alert.get('value', None),
            text=alert.get('text', None),
            tags=alert.get('tags', list()),
            attributes=alert.get('attributes', dict()),
            origin=alert.get('origin', None),
            event_type=alert.get('type', None),
            create_time=alert.get('createTime', None),
            timeout=alert.get('timeout', None),
            raw_data=alert.get('rawData', None),
        )

class AlertDocument(object):

    def __init__(self, id, resource, event, environment, severity, correlate, status, service, group, value, text,
                 tags, attributes, origin, event_type, create_time, timeout, raw_data, duplicate_count, repeat,
                 previous_severity, trend_indication, receive_time, last_receive_id, last_receive_time, history):

        self.id = id
        self.resource = resource
        self.event = event
        self.environment = environment or ""
        self.severity = severity
        self.correlate = correlate or list()
        self.status = status
        self.service = service or list()
        self.group = group or 'Misc'
        self.value = value or 'n/a'
        self.text = text or ""
        self.tags = tags or list()
        self.attributes = attributes or dict()
        self.origin = origin or '%s/%s' % (prog, os.uname()[1])
        self.event_type = event_type or 'exceptionAlert'
        self.create_time = create_time or datetime.datetime.utcnow()
        self.timeout = timeout or DEFAULT_TIMEOUT
        self.raw_data = raw_data

        self.duplicate_count = duplicate_count
        self.repeat = repeat
        self.previous_severity = previous_severity
        self.trend_indication = trend_indication
        self.receive_time = receive_time
        self.last_receive_id = last_receive_id
        self.last_receive_time = last_receive_time
        self.history = history

    def get_id(self, short=False):

        if short:
            return self.id[:8]
        else:
            return self.id

    def get_header(self):

        return {
            "origin": self.origin,
            "type": self.event_type,
            "correlation-id": self.id
        }

    def get_date(self, attr, fmt='iso', timezone='Europe/London'):

        tz = pytz.timezone(timezone)

        if hasattr(self, attr):
            if fmt == 'local':
                return getattr(self, attr).replace(tzinfo=pytz.UTC).astimezone(tz).strftime('%Y/%m/%d %H:%M:%S')
            elif fmt == 'iso' or fmt == 'iso8601':
                return getattr(self, attr).replace(microsecond=0).isoformat() + ".%03dZ" % (getattr(self, attr).microsecond // 1000)
            elif fmt == 'rfc' or fmt == 'rfc2822':
                return utils.formatdate(time.mktime(getattr(self, attr).replace(tzinfo=pytz.UTC).timetuple()), True)
            elif fmt == 'short':
                return getattr(self, attr).replace(tzinfo=pytz.UTC).astimezone(tz).strftime('%a %d %H:%M:%S')
            elif fmt == 'epoch':
                return time.mktime(getattr(self, attr).replace(tzinfo=pytz.UTC).timetuple())
            elif fmt == 'raw':
                return getattr(self, attr)
            else:
                raise ValueError("Unknown date format %s" % fmt)
        else:
            return ValueError("Attribute %s not a date" % attr)

    def get_body(self):

        return {
            'id': self.id,
            'resource': self.resource,
            'event': self.event,
            'environment': self.environment,
            'severity': self.severity,
            'correlate': self.correlate,
            'status': self.status,
            'service': self.service,
            'group': self.group,
            'value': self.value,
            'text': self.text,
            'tags': self.tags,
            'attributes': self.attributes,
            'origin': self.origin,
            'type': self.event_type,
            'createTime': self.create_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.create_time.microsecond // 1000),
            'timeout': self.timeout,
            'rawData': self.raw_data,
            'duplicateCount': self.duplicate_count,
            'repeat': self.repeat,
            'previousSeverity': self.previous_severity,
            'trendIndication': self.trend_indication,
            'receiveTime': self.receive_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.receive_time.microsecond // 1000),
            'lastReceiveId': self.last_receive_id,
            'lastReceiveTime': self.last_receive_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.last_receive_time.microsecond // 1000),
            'history': self.history
        }

    def __repr__(self):
        return 'AlertDocument(id=%r, environment=%r, resource=%r, event=%r, severity=%r, status=%r)' % (
            self.id, self.environment, self.resource, self.event, self.severity, self.status)

    def __str__(self):
        return json.dumps(self.get_body(), indent=4)

    @staticmethod
    def parse_alert(alert):

        for k, v in alert.iteritems():
            if k in ['createTime', 'receiveTime', 'lastReceiveTime', 'expireTime']:
                if '.' in v:
                    try:
                        alert[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%fZ')
                    except ValueError, e:
                        raise ValueError('Could not parse date time string: %s' % e)
                else:
                    try:
                        alert[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%SZ')  # if us = 000000
                    except ValueError, e:
                        raise ValueError('Could not parse date time string: %s' % e)

        return AlertDocument(
            id=alert.get('id', None),
            resource=alert.get('resource', None),
            event=alert.get('event', None),
            environment=alert.get('environment', None),
            severity=alert.get('severity', None),
            correlate=alert.get('correlate', list()),
            status=alert.get('status', None),
            service=alert.get('service', list()),
            group=alert.get('group', None),
            value=alert.get('value', None),
            text=alert.get('text', None),
            tags=alert.get('tags', list()),
            attributes=alert.get('attributes', dict()),
            origin=alert.get('origin', None),
            event_type=alert.get('type', None),
            create_time=alert.get('createTime', None),
            timeout=alert.get('timeout', None),
            raw_data=alert.get('rawData', None),
            duplicate_count=alert.get('duplicateCount', None),
            repeat=alert.get('repeat', None),
            previous_severity=alert.get('previousSeverity', None),
            trend_indication=alert.get('trendIndication', None),
            receive_time=alert.get('receiveTime', None),
            last_receive_id=alert.get('lastReceiveId', None),
            last_receive_time=alert.get('lastReceiveTime', None),
            history=alert.get('history', None)
        )
<commit_msg>do not indent alert str() output<commit_after>
import os
import sys
import time
import datetime
import pytz
import json

from uuid import uuid4
from email import utils

DEFAULT_SEVERITY = "normal"  # "normal", "ok" or "clear"
DEFAULT_TIMEOUT = 86400

prog = os.path.basename(sys.argv[0])

class Alert(object):

    def __init__(self, resource, event, **kwargs):

        if not resource:
            raise ValueError('Missing mandatory value for "resource"')
        if not event:
            raise ValueError('Missing mandatory value for "event"')
        if any(['.' in key for key in kwargs.get('attributes', dict()).keys()])\
                or any(['$' in key for key in kwargs.get('attributes', dict()).keys()]):
            raise ValueError('Attribute keys must not contain "." or "$"')

        self.id = kwargs.get('id', str(uuid4()))
        self.resource = resource
        self.event = event
        self.environment = kwargs.get('environment', None) or ""
        self.severity = kwargs.get('severity', None) or DEFAULT_SEVERITY
        self.correlate = kwargs.get('correlate', None) or list()
        if self.correlate and event not in self.correlate:
            self.correlate.append(event)
        self.status = kwargs.get('status', None) or "unknown"
        self.service = kwargs.get('service', None) or list()
        self.group = kwargs.get('group', None) or "Misc"
        self.value = kwargs.get('value', None) or "n/a"
        self.text = kwargs.get('text', None) or ""
        self.tags = kwargs.get('tags', None) or list()
        self.attributes = kwargs.get('attributes', None) or dict()
        self.origin = kwargs.get('origin', None) or '%s/%s' % (prog, os.uname()[1])
        self.event_type = kwargs.get('event_type', kwargs.get('type', None)) or "exceptionAlert"
        self.create_time = kwargs.get('create_time', None) or datetime.datetime.utcnow()
        self.receive_time = None
        self.timeout = kwargs.get('timeout', None) or DEFAULT_TIMEOUT
        self.raw_data = kwargs.get('raw_data', kwargs.get('rawData', None)) or ""

    def get_id(self, short=False):

        if short:
            return self.id[:8]
        else:
            return self.id

    def get_header(self):

        return {
            "origin": self.origin,
            "type": self.event_type,
            "correlation-id": self.id
        }

    def get_body(self):

        return {
            'id': self.id,
            'resource': self.resource,
            'event': self.event,
            'environment': self.environment,
            'severity': self.severity,
            'correlate': self.correlate,
            'status': self.status,
            'service': self.service,
            'group': self.group,
            'value': self.value,
            'text': self.text,
            'tags': self.tags,
            'attributes': self.attributes,
            'origin': self.origin,
            'type': self.event_type,
            'createTime': self.create_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.create_time.microsecond // 1000),
            'timeout': self.timeout,
            'rawData': self.raw_data
        }

    def get_type(self):
        return self.event_type

    def receive_now(self):
        self.receive_time = datetime.datetime.utcnow()

    def __repr__(self):
        return 'Alert(id=%r, environment=%r, resource=%r, event=%r, severity=%r, status=%r)' % (
            self.id, self.environment, self.resource, self.event, self.severity, self.status)

    def __str__(self):
        return json.dumps(self.get_body())

    @staticmethod
    def parse_alert(alert):

        try:
            alert = json.loads(alert)
        except ValueError, e:
            raise ValueError('Could not parse alert - %s: %s' % (e, alert))

        for k, v in alert.iteritems():
            if k in ['createTime', 'receiveTime', 'lastReceiveTime', 'expireTime']:
                try:
                    alert[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%fZ')
                except ValueError, e:
                    raise ValueError('Could not parse date time string: %s' % e)

        return Alert(
            resource=alert.get('resource', None),
            event=alert.get('event', None),
            environment=alert.get('environment', None),
            severity=alert.get('severity', None),
            correlate=alert.get('correlate', list()),
            status=alert.get('status', None),
            service=alert.get('service', list()),
            group=alert.get('group', None),
            value=alert.get('value', None),
            text=alert.get('text', None),
            tags=alert.get('tags', list()),
            attributes=alert.get('attributes', dict()),
            origin=alert.get('origin', None),
            event_type=alert.get('type', None),
            create_time=alert.get('createTime', None),
            timeout=alert.get('timeout', None),
            raw_data=alert.get('rawData', None),
        )

class AlertDocument(object):

    def __init__(self, id, resource, event, environment, severity, correlate, status, service, group, value, text,
                 tags, attributes, origin, event_type, create_time, timeout, raw_data, duplicate_count, repeat,
                 previous_severity, trend_indication, receive_time, last_receive_id, last_receive_time, history):

        self.id = id
        self.resource = resource
        self.event = event
        self.environment = environment or ""
        self.severity = severity
        self.correlate = correlate or list()
        self.status = status
        self.service = service or list()
        self.group = group or 'Misc'
        self.value = value or 'n/a'
        self.text = text or ""
        self.tags = tags or list()
        self.attributes = attributes or dict()
        self.origin = origin or '%s/%s' % (prog, os.uname()[1])
        self.event_type = event_type or 'exceptionAlert'
        self.create_time = create_time or datetime.datetime.utcnow()
        self.timeout = timeout or DEFAULT_TIMEOUT
        self.raw_data = raw_data

        self.duplicate_count = duplicate_count
        self.repeat = repeat
        self.previous_severity = previous_severity
        self.trend_indication = trend_indication
        self.receive_time = receive_time
        self.last_receive_id = last_receive_id
        self.last_receive_time = last_receive_time
        self.history = history

    def get_id(self, short=False):

        if short:
            return self.id[:8]
        else:
            return self.id

    def get_header(self):

        return {
            "origin": self.origin,
            "type": self.event_type,
            "correlation-id": self.id
        }

    def get_date(self, attr, fmt='iso', timezone='Europe/London'):

        tz = pytz.timezone(timezone)

        if hasattr(self, attr):
            if fmt == 'local':
                return getattr(self, attr).replace(tzinfo=pytz.UTC).astimezone(tz).strftime('%Y/%m/%d %H:%M:%S')
            elif fmt == 'iso' or fmt == 'iso8601':
                return getattr(self, attr).replace(microsecond=0).isoformat() + ".%03dZ" % (getattr(self, attr).microsecond // 1000)
            elif fmt == 'rfc' or fmt == 'rfc2822':
                return utils.formatdate(time.mktime(getattr(self, attr).replace(tzinfo=pytz.UTC).timetuple()), True)
            elif fmt == 'short':
                return getattr(self, attr).replace(tzinfo=pytz.UTC).astimezone(tz).strftime('%a %d %H:%M:%S')
            elif fmt == 'epoch':
                return time.mktime(getattr(self, attr).replace(tzinfo=pytz.UTC).timetuple())
            elif fmt == 'raw':
                return getattr(self, attr)
            else:
                raise ValueError("Unknown date format %s" % fmt)
        else:
            return ValueError("Attribute %s not a date" % attr)

    def get_body(self):

        return {
            'id': self.id,
            'resource': self.resource,
            'event': self.event,
            'environment': self.environment,
            'severity': self.severity,
            'correlate': self.correlate,
            'status': self.status,
            'service': self.service,
            'group': self.group,
            'value': self.value,
            'text': self.text,
            'tags': self.tags,
            'attributes': self.attributes,
            'origin': self.origin,
            'type': self.event_type,
            'createTime': self.create_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.create_time.microsecond // 1000),
            'timeout': self.timeout,
            'rawData': self.raw_data,
            'duplicateCount': self.duplicate_count,
            'repeat': self.repeat,
            'previousSeverity': self.previous_severity,
            'trendIndication': self.trend_indication,
            'receiveTime': self.receive_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.receive_time.microsecond // 1000),
            'lastReceiveId': self.last_receive_id,
            'lastReceiveTime': self.last_receive_time.replace(microsecond=0).isoformat() + ".%03dZ" % (self.last_receive_time.microsecond // 1000),
            'history': self.history
        }

    def __repr__(self):
        return 'AlertDocument(id=%r, environment=%r, resource=%r, event=%r, severity=%r, status=%r)' % (
            self.id, self.environment, self.resource, self.event, self.severity, self.status)

    def __str__(self):
        return json.dumps(self.get_body())

    @staticmethod
    def parse_alert(alert):

        for k, v in alert.iteritems():
            if k in ['createTime', 'receiveTime', 'lastReceiveTime', 'expireTime']:
                if '.' in v:
                    try:
                        alert[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%fZ')
                    except ValueError, e:
                        raise ValueError('Could not parse date time string: %s' % e)
                else:
                    try:
                        alert[k] = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%SZ')  # if us = 000000
                    except ValueError, e:
                        raise ValueError('Could not parse date time string: %s' % e)

        return AlertDocument(
            id=alert.get('id', None),
            resource=alert.get('resource', None),
            event=alert.get('event', None),
            environment=alert.get('environment', None),
            severity=alert.get('severity', None),
            correlate=alert.get('correlate', list()),
            status=alert.get('status', None),
            service=alert.get('service', list()),
            group=alert.get('group', None),
            value=alert.get('value', None),
            text=alert.get('text', None),
            tags=alert.get('tags', list()),
            attributes=alert.get('attributes', dict()),
            origin=alert.get('origin', None),
            event_type=alert.get('type', None),
            create_time=alert.get('createTime', None),
            timeout=alert.get('timeout', None),
            raw_data=alert.get('rawData', None),
            duplicate_count=alert.get('duplicateCount', None),
            repeat=alert.get('repeat', None),
            previous_severity=alert.get('previousSeverity', None),
            trend_indication=alert.get('trendIndication', None),
            receive_time=alert.get('receiveTime', None),
            last_receive_id=alert.get('lastReceiveId', None),
            last_receive_time=alert.get('lastReceiveTime', None),
            history=alert.get('history', None)
        )
<|endoftext|>