<commit_before>from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify

from flask_cors import CORS, cross_origin

import config as conf
import subprocess
import os
import re
import socket

app = Flask(__name__)
CORS(app)

# Chatbot route handling
@app.route('/chatbot/<demo>')
def getChatbot(demo):
    if demo=='ubuntu':
        return render_template('chatbot_ubuntu.html')
    elif demo=='swisscom':
        return render_template('chatbot_swisscom.html')
@app.route('/chatbot/<demo>/<question>', methods=['POST'])
def submitChatbot(demo, question):
    print("Question:", question)
    if request.method == 'POST':
        if demo=='ubuntu':
            predict_dir = conf.chatbot_ubuntu['path']
            model_id = conf.chatbot_ubuntu['model_id']
            python_env = conf.chatbot_ubuntu['python_env']
        elif demo=='swisscom':
            predict_dir = conf.chatbot_swisscom['path']
            model_id = conf.chatbot_swisscom['model_id']
            python_env = conf.chatbot_swisscom['python_env']
        elif demo=='ubuntuseq2seq':
            predict_dir = conf.chatbot_ubuntu_seq2seq['path']
            model_id = conf.chatbot_ubuntu_seq2seq['model_id']
            python_env = conf.chatbot_ubuntu_seq2seq['python_env']
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(("localhost", 9988))
            s.sendall(question.encode())
            answer = s.recv(1024).decode("utf-8")
            s.close()
            return answer

        model_dir = predict_dir + 'runs/' + model_id
        subprocess.call([python_env, predict_dir + 'demo_prediction.py', '--model_dir=' + model_dir, '--raw_query=' + "'" + question + "'"])
        # Generate answer here
        with open(predict_dir + "answers.txt", "r") as text_file:
            answer = text_file.readlines()[0]
        answer = answer.split('___|||___')
        encoder = answer[0].split('___***___');
        solr = answer[1].split('___***___');
        encoder = answer[0].split('___***___');
        answer = {'solr':solr, 'encoder': encoder}
        return jsonify(answer)

# Opinion target route handling
def parse_output(output_path):
    f = open(output_path,'r')
    pred_labels = []
    for line in f:
        line = line.strip()
        if len(line.split()) == 3:
            pred_label = line.split()[2]
            pred_labels.append(pred_label)
    return " ".join(pred_labels)

@app.route('/opinion')
def getOpinion():
    return render_template('opinion_target.html')

@app.route('/opinion/<input>', methods=['POST'])
def submitOpinion(input):
    if request.method == 'POST':
        script_dir = conf.ate['path'] + 'run_demo.py'
        predict_dir = conf.ate['path'] + '/predictions/predictions.txt'
        python_env = conf.ate['python_env']
        response = ""
        subprocess.call([python_env, script_dir, '--sentence', '"'+ input + '"'])
        answer = parse_output(predict_dir)
        print("Question received for ATE project", answer)
        answer = {'labels': answer}
        return jsonify(answer)

# NER route handling
@app.route('/ner')
def getNER():
    return render_template('ner.html')

@app.route('/ner/<input>', methods=['POST'])
def submitNER(input):
    if request.method == 'POST':
        script_dir = conf.ner['path'] + 'run_demo.py'
        predict_dir = conf.ner['path'] + 'predictions/predictions.txt'
        python_env = conf.ner['python_env']
        response = ""
        subprocess.call([python_env, script_dir, '--sentence', '"'+ input + '"'])
        answer = parse_output(predict_dir)
        print("Question received for NER project", answer)
        answer = {'labels': answer}
        return jsonify(answer)

# KP Extraction route handling
@app.route('/kp')
def getKP():
    return render_template('kp_extraction.html')

@app.route('/kp', methods=['POST'])
def submitKP():
    if request.method == 'POST':
        print('input ',request.form['inp_url'])
        html_content = subprocess.check_output(['curl', request.form['inp_url']], close_fds=True)
        write_file(os.path.join(conf.kpextract['path'],'tmp','html_file'), html_content.decode('utf-8'))
        text_content = subprocess.check_output([conf.kpextract['python_env'], conf.kpextract['fetcher_path'], os.path.join(conf.kpextract['path'],'tmp','html_file')])
        write_file(os.path.join(conf.kpextract['path'],'tmp','raw_text'),text_content.decode('utf-8'))
        subprocess.call([conf.kpextract['python_env'], '-m', 'kpextract.models.singlerank', os.path.join(conf.kpextract['path'],'tmp','raw_text') , '6', '14', os.path.join(conf.kpextract['path'],'tmp')])
        html_doc, list_kp = read_kp_output()
        return render_template('kpboard.html', html_doc=html_doc, list_kp=list_kp)

def read_file(path):
    with open(path, 'r') as f:
        return f.read()

def write_file(path, s):
    with open(path, 'w') as f:
        f.write(s)

def read_kp_output():
    processed_text = read_file(os.path.join(conf.kpextract['path'],'tmp','result_text.txt'))
    processed_text = re.sub('\n+', '\n', processed_text)
    html_doc = processed_text.replace('\n', '

')
    html_doc = html_doc.replace('<phrase>', '')
    html_doc = html_doc.replace('</phrase>', '')
    html_doc = '
' + html_doc + '
'

    list_kp_text =  read_file(os.path.join(conf.kpextract['path'],'tmp','result_kp.txt'))
    list_kp = list_kp_text.split(';')

    return html_doc, list_kp

# Summary route handling
@app.route('/summary')
def getSummary():
    return render_template('summary.html')

import os
if not os.path.exists('%s/run/launch.py'%conf.summary['path']):
    print('File required to run summary')
import sys
sys.path.insert(0,'%s/run'%conf.summary['path'])
ret_path=os.path.abspath('.')
os.chdir(conf.summary['path'])
import launch
os.chdir(ret_path)

@app.route('/summary/<input>', methods=['POST'])
def submitSummary(input):
    if request.method == 'POST':
        # Generate answer here
        answer = input.replace('**n**', '\n')
        ret_path=os.path.abspath('.')
        os.chdir(conf.summary['path'])
        with open('tmp.txt','w') as fopen:
            fopen.write(answer)
        launch.predict()
        answer = ''.join(open('output.txt','r').readlines())
        os.system('rm tmp.txt output.txt')
        os.chdir(ret_path)
        return answer

if __name__ == '__main__':
    app.run(host= '127.0.0.1')
<commit_msg>Added get<commit_after>from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify

from flask_cors import CORS, cross_origin

import config as conf
import subprocess
import os
import re
import socket

app = Flask(__name__)
CORS(app)

# Chatbot route handling
@app.route('/chatbot/<demo>')
def getChatbot(demo):
    if demo=='ubuntu':
        return render_template('chatbot_ubuntu.html')
    elif demo=='swisscom':
        return render_template('chatbot_swisscom.html')
    elif demo=='ubuntuseq2seq':
        return render_template('chatbot_seq2seq_ubuntu.html')
@app.route('/chatbot/<demo>/<question>', methods=['POST'])
def submitChatbot(demo, question):
    print("Question:", question)
    if request.method == 'POST':
        if demo=='ubuntu':
            predict_dir = conf.chatbot_ubuntu['path']
            model_id = conf.chatbot_ubuntu['model_id']
            python_env = conf.chatbot_ubuntu['python_env']
        elif demo=='swisscom':
            predict_dir = conf.chatbot_swisscom['path']
            model_id = conf.chatbot_swisscom['model_id']
            python_env = conf.chatbot_swisscom['python_env']
        elif demo=='ubuntuseq2seq':
            predict_dir = conf.chatbot_ubuntu_seq2seq['path']
            model_id = conf.chatbot_ubuntu_seq2seq['model_id']
            python_env = conf.chatbot_ubuntu_seq2seq['python_env']
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(("localhost", 9988))
            s.sendall(question.encode())
            answer = s.recv(1024).decode("utf-8")
            s.close()
            return answer

        model_dir = predict_dir + 'runs/' + model_id
        subprocess.call([python_env, predict_dir + 'demo_prediction.py', '--model_dir=' + model_dir, '--raw_query=' + "'" + question + "'"])
        # Generate answer here
        with open(predict_dir + "answers.txt", "r") as text_file:
            answer = text_file.readlines()[0]
        answer = answer.split('___|||___')
        encoder = answer[0].split('___***___');
        solr = answer[1].split('___***___');
        encoder = answer[0].split('___***___');
        answer = {'solr':solr, 'encoder': encoder}
        return jsonify(answer)

# Opinion target route handling
def parse_output(output_path):
    f = open(output_path,'r')
    pred_labels = []
    for line in f:
        line = line.strip()
        if len(line.split()) == 3:
            pred_label = line.split()[2]
            pred_labels.append(pred_label)
    return " ".join(pred_labels)

@app.route('/opinion')
def getOpinion():
    return render_template('opinion_target.html')

@app.route('/opinion/<input>', methods=['POST'])
def submitOpinion(input):
    if request.method == 'POST':
        script_dir = conf.ate['path'] + 'run_demo.py'
        predict_dir = conf.ate['path'] + '/predictions/predictions.txt'
        python_env = conf.ate['python_env']
        response = ""
        subprocess.call([python_env, script_dir, '--sentence', '"'+ input + '"'])
        answer = parse_output(predict_dir)
        print("Question received for ATE project", answer)
        answer = {'labels': answer}
        return jsonify(answer)

# NER route handling
@app.route('/ner')
def getNER():
    return render_template('ner.html')

@app.route('/ner/<input>', methods=['POST'])
def submitNER(input):
    if request.method == 'POST':
        script_dir = conf.ner['path'] + 'run_demo.py'
        predict_dir = conf.ner['path'] + 'predictions/predictions.txt'
        python_env = conf.ner['python_env']
        response = ""
        subprocess.call([python_env, script_dir, '--sentence', '"'+ input + '"'])
        answer = parse_output(predict_dir)
        print("Question received for NER project", answer)
        answer = {'labels': answer}
        return jsonify(answer)

# KP Extraction route handling
@app.route('/kp')
def getKP():
    return render_template('kp_extraction.html')

@app.route('/kp', methods=['POST'])
def submitKP():
    if request.method == 'POST':
        print('input ',request.form['inp_url'])
        html_content = subprocess.check_output(['curl', request.form['inp_url']], close_fds=True)
        write_file(os.path.join(conf.kpextract['path'],'tmp','html_file'), html_content.decode('utf-8'))
        text_content = subprocess.check_output([conf.kpextract['python_env'], conf.kpextract['fetcher_path'], os.path.join(conf.kpextract['path'],'tmp','html_file')])
        write_file(os.path.join(conf.kpextract['path'],'tmp','raw_text'),text_content.decode('utf-8'))
        subprocess.call([conf.kpextract['python_env'], '-m', 'kpextract.models.singlerank', os.path.join(conf.kpextract['path'],'tmp','raw_text') , '6', '14', os.path.join(conf.kpextract['path'],'tmp')])
        html_doc, list_kp = read_kp_output()
        return render_template('kpboard.html', html_doc=html_doc, list_kp=list_kp)

def read_file(path):
    with open(path, 'r') as f:
        return f.read()

def write_file(path, s):
    with open(path, 'w') as f:
        f.write(s)

def read_kp_output():
    processed_text = read_file(os.path.join(conf.kpextract['path'],'tmp','result_text.txt'))
    processed_text = re.sub('\n+', '\n', processed_text)
    html_doc = processed_text.replace('\n', '

')
    html_doc = html_doc.replace('<phrase>', '')
    html_doc = html_doc.replace('</phrase>', '')
    html_doc = '
' + html_doc + '
'

    list_kp_text =  read_file(os.path.join(conf.kpextract['path'],'tmp','result_kp.txt'))
    list_kp = list_kp_text.split(';')

    return html_doc, list_kp

# Summary route handling
@app.route('/summary')
def getSummary():
    return render_template('summary.html')

import os
if not os.path.exists('%s/run/launch.py'%conf.summary['path']):
    print('File required to run summary')
import sys
sys.path.insert(0,'%s/run'%conf.summary['path'])
ret_path=os.path.abspath('.')
os.chdir(conf.summary['path'])
import launch
os.chdir(ret_path)

@app.route('/summary/<input>', methods=['POST'])
def submitSummary(input):
    if request.method == 'POST':
        # Generate answer here
        answer = input.replace('**n**', '\n')
        ret_path=os.path.abspath('.')
        os.chdir(conf.summary['path'])
        with open('tmp.txt','w') as fopen:
            fopen.write(answer)
        launch.predict()
        answer = ''.join(open('output.txt','r').readlines())
        os.system('rm tmp.txt output.txt')
        os.chdir(ret_path)
        return answer

if __name__ == '__main__':
    app.run(host= '127.0.0.1')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
This module defines the functions used to compute loss ratio and loss curves
using the probabilistic event based approach.
"""

import math

from numpy import zeros # pylint: disable=E1101, E0611
from numpy import array # pylint: disable=E1101, E0611
from numpy import linspace # pylint: disable=E1101, E0611
from numpy import histogram # pylint: disable=E1101, E0611
from numpy import where # pylint: disable=E1101, E0611

from openquake import kvs
from openquake import shapes
from openquake.parser import vulnerability
from openquake.logs import LOG

DEFAULT_NUMBER_OF_SAMPLES = 25

def _compute_loss_ratios(vuln_function, ground_motion_field_set):
    """Compute loss ratios using the ground motion field set passed."""
    if vuln_function == shapes.EMPTY_VULN_FUNCTION or not \
                        ground_motion_field_set["IMLs"]:
        return array([])

    imls = vuln_function.imls
    loss_ratios = []

    # seems like with numpy you can only specify a single fill value
    # if the x_new is outside the range. Here we need two different values,
    # depending if the x_new is below or upon the defined values
    for ground_motion_field in ground_motion_field_set["IMLs"]:
        if ground_motion_field < imls[0]:
            loss_ratios.append(0.0)
        elif ground_motion_field > imls[-1]:
            loss_ratios.append(imls[-1])
        else:
            loss_ratios.append(vuln_function.ordinate_for(
                    ground_motion_field))

    return array(loss_ratios)

def _compute_loss_ratios_range(loss_ratios, num=DEFAULT_NUMBER_OF_SAMPLES):
    """Compute the range of loss ratios used to build the loss ratio curve."""
    return linspace(loss_ratios.min(), loss_ratios.max(), num)

def _compute_cumulative_histogram(loss_ratios, loss_ratios_range):
    "Compute the cumulative histogram."

    # ruptures (earthquake) occured but probably due to distance,
    # magnitude and soil conditions, no ground motion was felt at that location
    if (loss_ratios <= 0.0).all():
        return zeros(len(loss_ratios_range) - 1)

    invalid_ratios = lambda ratios: len(where(array(ratios) <= 0.0)[0])

    hist = histogram(loss_ratios, bins=loss_ratios_range)
    hist = hist[0][::-1].cumsum()[::-1]

    # ratios with value 0.0 must be deleted on the first bin
    hist[0] = hist[0] - invalid_ratios(loss_ratios)
    return hist

def _compute_rates_of_exceedance(cum_histogram, tses):
    """Compute the rates of exceedance for the given cumulative histogram
    using the passed tses (tses is time span * number of realizations)."""
    if tses <= 0:
        raise ValueError("TSES is not supposed to be less than zero!")

    return (array(cum_histogram).astype(float) / tses)

def _compute_probs_of_exceedance(rates_of_exceedance, time_span):
    """Compute the probabilities of exceedance using the given rates of
    exceedance unsing the passed time span."""
    probs_of_exceedance = []
    for idx in xrange(len(rates_of_exceedance)):
        probs_of_exceedance.append(1 - math.exp(
                (rates_of_exceedance[idx] * -1) \
                *  time_span))

    return array(probs_of_exceedance)

def compute_loss_ratio_curve(vuln_function, ground_motion_field_set,
        num=DEFAULT_NUMBER_OF_SAMPLES):
    """Compute a loss ratio curve using the probailistic event approach.

    A loss ratio curve is a function that has loss ratios as X values
    and PoEs (Probabilities of Exceendance) as Y values.
    """

    # with no gmfs (no earthquakes), an empty curve is enough
    if not ground_motion_field_set["IMLs"]:
        return shapes.EMPTY_CURVE

    loss_ratios = _compute_loss_ratios(vuln_function, ground_motion_field_set)
    loss_ratios_range = _compute_loss_ratios_range(loss_ratios, num)

    probs_of_exceedance = _compute_probs_of_exceedance(
            _compute_rates_of_exceedance(_compute_cumulative_histogram(
            loss_ratios, loss_ratios_range), ground_motion_field_set["TSES"]),
            ground_motion_field_set["TimeSpan"])

    return _generate_curve(loss_ratios_range, probs_of_exceedance)

def _generate_curve(losses, probs_of_exceedance):
    """Generate a loss ratio (or loss) curve, given a set of losses
    and corresponding PoEs (Probabilities of Exceedance). This function
    is intended to be used internally."""

    data = []
    for idx in xrange(len(losses) - 1):
        mean_loss_ratio = (losses[idx] + losses[idx + 1]) / 2
        data.append((mean_loss_ratio, probs_of_exceedance[idx]))

    return shapes.Curve(data)

def _asset_for_gmfs(job_id, gmfs_key):
    """Return the asset related to the GMFs given."""

    row = lambda key: key.split(kvs.MEMCACHE_KEY_SEPARATOR)[2]
    column = lambda key: key.split(kvs.MEMCACHE_KEY_SEPARATOR)[3]

    key = kvs.tokens.asset_key(
            job_id, row(gmfs_key), column(gmfs_key))

    return kvs.get_value_json_decoded(key)

class AggregateLossCurve(object):
    """Aggregate a set of losses and produce the resulting loss curve."""

    @staticmethod
    def from_kvs(job_id):
        """Return an aggregate curve using the GMFs and assets
        stored in the underlying kvs system."""

        vuln_model = vulnerability.load_vuln_curves_from_kvs(job_id)
        aggregate_curve = AggregateLossCurve(vuln_model)

        client = kvs.get_client(binary=False)
        gmfs_keys = client.keys("%s*%s*" % (job_id, kvs.tokens.GMF_KEY_TOKEN))
        LOG.debug("Found %s stored GMFs..." % len(gmfs_keys))

        for gmfs_key in gmfs_keys: # O(2*n)
            asset = _asset_for_gmfs(job_id, gmfs_key)
            gmfs = kvs.get_value_json_decoded(gmfs_key)
            aggregate_curve.append(gmfs, asset)

        return aggregate_curve

    def __init__(self, vuln_model):
        self.distribution = []
        self.initialized = False
        self.vuln_model = vuln_model

    def append(self, gmfs, asset):
        """Add the losses distribution identified by the given GMFs
        and asset to the set used to compute the aggregate curve."""

        if not self.initialized:
            self.initialized = True
            self._initialize_parameters(gmfs)

        self._check_gmfs_length(gmfs)
        self._check_parameter(self._tses, gmfs, "TSES")
        self._check_parameter(self._time_span, gmfs, "TimeSpan")

        loss_ratios = _compute_loss_ratios(self.vuln_model[
                asset["VulnerabilityFunction"]], gmfs)

        self.distribution.append(loss_ratios * asset["AssetValue"])

    def _initialize_parameters(self, gmfs):
        """Initialize the GMFs parameters."""
        self._tses = gmfs["TSES"]
        self._time_span = gmfs["TimeSpan"]
        self._gmfs_length = len(gmfs["IMLs"])

    def _check_gmfs_length(self, gmfs):
        """Check if the GMFs passed has the same length of
        the stored GMFs."""

        if self._gmfs_length != len(gmfs["IMLs"]):
            raise ValueError("GMFs must be of the same size. " \
                    "Expected %s, but was %s" % (
                    self._gmfs_length, len(gmfs["IMLs"])))

    def _check_parameter(self, value, gmfs, name):
        """Check if the parameter of the GMFs passed is the
        same of the stored GMFs."""

        if value != gmfs[name]:
            raise ValueError("%s parameter must be the same for all " \
                    "the GMFs used. Expected %s, but was %s"
                    % (name, value, gmfs[name]))

    @property
    def losses(self):
        """Return the losses used to compute the aggregate curve."""
        if not self.distribution:
            return array([])
        else: # if needed because numpy returns a scalar if the list is empty
            return array(self.distribution).sum(axis=0)

    def compute(self, num=DEFAULT_NUMBER_OF_SAMPLES):
        """Compute the aggregate loss curve."""
        losses = self.losses

        if not len(losses):
            return shapes.EMPTY_CURVE

        loss_range = _compute_loss_ratios_range(losses, num)

        probs_of_exceedance = _compute_probs_of_exceedance(
                _compute_rates_of_exceedance(_compute_cumulative_histogram(
                losses, loss_range), self._tses), self._time_span)

        return _generate_curve(loss_range, probs_of_exceedance)
<commit_msg>Refactored code<commit_after># -*- coding: utf-8 -*-
"""
This module defines the functions used to compute loss ratio and loss curves
using the probabilistic event based approach.
"""

import math

from numpy import zeros # pylint: disable=E1101, E0611
from numpy import array # pylint: disable=E1101, E0611
from numpy import linspace # pylint: disable=E1101, E0611
from numpy import histogram # pylint: disable=E1101, E0611
from numpy import where # pylint: disable=E1101, E0611

from openquake import kvs
from openquake import shapes
from openquake.parser import vulnerability
from openquake.logs import LOG

DEFAULT_NUMBER_OF_SAMPLES = 25

def _compute_loss_ratios(vuln_function, ground_motion_field_set):
    """Compute loss ratios using the ground motion field set passed."""
    if vuln_function == shapes.EMPTY_VULN_FUNCTION:
        return array([])

    imls = vuln_function.imls
    loss_ratios = []

    # seems like with numpy you can only specify a single fill value
    # if the x_new is outside the range. Here we need two different values,
    # depending if the x_new is below or upon the defined values
    for ground_motion_field in ground_motion_field_set["IMLs"]:
        if ground_motion_field < imls[0]:
            loss_ratios.append(0.0)
        elif ground_motion_field > imls[-1]:
            loss_ratios.append(imls[-1])
        else:
            loss_ratios.append(vuln_function.ordinate_for(
                    ground_motion_field))

    return array(loss_ratios)

def _compute_loss_ratios_range(loss_ratios, num=DEFAULT_NUMBER_OF_SAMPLES):
    """Compute the range of loss ratios used to build the loss ratio curve."""
    return linspace(loss_ratios.min(), loss_ratios.max(), num)

def _compute_cumulative_histogram(loss_ratios, loss_ratios_range):
    "Compute the cumulative histogram."

    # ruptures (earthquake) occured but probably due to distance,
    # magnitude and soil conditions, no ground motion was felt at that location
    if (loss_ratios <= 0.0).all():
        return zeros(len(loss_ratios_range) - 1)

    invalid_ratios = lambda ratios: len(where(array(ratios) <= 0.0)[0])

    hist = histogram(loss_ratios, bins=loss_ratios_range)
    hist = hist[0][::-1].cumsum()[::-1]

    # ratios with value 0.0 must be deleted on the first bin
    hist[0] = hist[0] - invalid_ratios(loss_ratios)
    return hist

def _compute_rates_of_exceedance(cum_histogram, tses):
    """Compute the rates of exceedance for the given cumulative histogram
    using the passed tses (tses is time span * number of realizations)."""
    if tses <= 0:
        raise ValueError("TSES is not supposed to be less than zero!")

    return (array(cum_histogram).astype(float) / tses)

def _compute_probs_of_exceedance(rates_of_exceedance, time_span):
    """Compute the probabilities of exceedance using the given rates of
    exceedance unsing the passed time span."""
    probs_of_exceedance = []
    for idx in xrange(len(rates_of_exceedance)):
        probs_of_exceedance.append(1 - math.exp(
                (rates_of_exceedance[idx] * -1) \
                *  time_span))

    return array(probs_of_exceedance)

def compute_loss_ratio_curve(vuln_function, ground_motion_field_set,
        num=DEFAULT_NUMBER_OF_SAMPLES):
    """Compute a loss ratio curve using the probailistic event approach.

    A loss ratio curve is a function that has loss ratios as X values
    and PoEs (Probabilities of Exceendance) as Y values.
    """

    # with no gmfs (no earthquakes), an empty curve is enough
    if not ground_motion_field_set["IMLs"]:
        return shapes.EMPTY_CURVE

    loss_ratios = _compute_loss_ratios(vuln_function, ground_motion_field_set)
    loss_ratios_range = _compute_loss_ratios_range(loss_ratios, num)

    probs_of_exceedance = _compute_probs_of_exceedance(
            _compute_rates_of_exceedance(_compute_cumulative_histogram(
            loss_ratios, loss_ratios_range), ground_motion_field_set["TSES"]),
            ground_motion_field_set["TimeSpan"])

    return _generate_curve(loss_ratios_range, probs_of_exceedance)

def _generate_curve(losses, probs_of_exceedance):
    """Generate a loss ratio (or loss) curve, given a set of losses
    and corresponding PoEs (Probabilities of Exceedance). This function
    is intended to be used internally."""

    data = []
    for idx in xrange(len(losses) - 1):
        mean_loss_ratio = (losses[idx] + losses[idx + 1]) / 2
        data.append((mean_loss_ratio, probs_of_exceedance[idx]))

    return shapes.Curve(data)

def _asset_for_gmfs(job_id, gmfs_key):
    """Return the asset related to the GMFs given."""

    row = lambda key: key.split(kvs.MEMCACHE_KEY_SEPARATOR)[2]
    column = lambda key: key.split(kvs.MEMCACHE_KEY_SEPARATOR)[3]

    key = kvs.tokens.asset_key(
            job_id, row(gmfs_key), column(gmfs_key))

    return kvs.get_value_json_decoded(key)

class AggregateLossCurve(object):
    """Aggregate a set of losses and produce the resulting loss curve."""

    @staticmethod
    def from_kvs(job_id):
        """Return an aggregate curve using the GMFs and assets
        stored in the underlying kvs system."""

        vuln_model = vulnerability.load_vuln_curves_from_kvs(job_id)
        aggregate_curve = AggregateLossCurve(vuln_model)

        client = kvs.get_client(binary=False)
        gmfs_keys = client.keys("%s*%s*" % (job_id, kvs.tokens.GMF_KEY_TOKEN))
        LOG.debug("Found %s stored GMFs..." % len(gmfs_keys))

        for gmfs_key in gmfs_keys: # O(2*n)
            asset = _asset_for_gmfs(job_id, gmfs_key)
            gmfs = kvs.get_value_json_decoded(gmfs_key)
            aggregate_curve.append(gmfs, asset)

        return aggregate_curve

    def __init__(self, vuln_model):
        self.distribution = []
        self.initialized = False
        self.vuln_model = vuln_model

    def append(self, gmfs, asset):
        """Add the losses distribution identified by the given GMFs
        and asset to the set used to compute the aggregate curve."""

        if not self.initialized:
            self.initialized = True
            self._initialize_parameters(gmfs)

        self._check_gmfs_length(gmfs)
        self._check_parameter(self._tses, gmfs, "TSES")
        self._check_parameter(self._time_span, gmfs, "TimeSpan")

        loss_ratios = _compute_loss_ratios(self.vuln_model[
                asset["VulnerabilityFunction"]], gmfs)

        self.distribution.append(loss_ratios * asset["AssetValue"])

    def _initialize_parameters(self, gmfs):
        """Initialize the GMFs parameters."""
        self._tses = gmfs["TSES"]
        self._time_span = gmfs["TimeSpan"]
        self._gmfs_length = len(gmfs["IMLs"])

    def _check_gmfs_length(self, gmfs):
        """Check if the GMFs passed has the same length of
        the stored GMFs."""

        if self._gmfs_length != len(gmfs["IMLs"]):
            raise ValueError("GMFs must be of the same size. " \
                    "Expected %s, but was %s" % (
                    self._gmfs_length, len(gmfs["IMLs"])))

    def _check_parameter(self, value, gmfs, name):
        """Check if the parameter of the GMFs passed is the
        same of the stored GMFs."""

        if value != gmfs[name]:
            raise ValueError("%s parameter must be the same for all " \
                    "the GMFs used. Expected %s, but was %s"
                    % (name, value, gmfs[name]))

    @property
    def losses(self):
        """Return the losses used to compute the aggregate curve."""
        if not self.distribution:
            return array([])
        else: # if needed because numpy returns a scalar if the list is empty
            return array(self.distribution).sum(axis=0)

    def compute(self, num=DEFAULT_NUMBER_OF_SAMPLES):
        """Compute the aggregate loss curve."""
        losses = self.losses

        if not len(losses):
            return shapes.EMPTY_CURVE

        loss_range = _compute_loss_ratios_range(losses, num)

        probs_of_exceedance = _compute_probs_of_exceedance(
                _compute_rates_of_exceedance(_compute_cumulative_histogram(
                losses, loss_range), self._tses), self._time_span)

        return _generate_curve(loss_range, probs_of_exceedance)
<|endoftext|>


<commit_before>import sys
import traceback

from django         import http
from django.conf    import settings
from django.views   import debug

from shoogie        import models

class ExceptionLoggingMiddleware(object):
    def process_exception(self, request, exception):
        if settings.DEBUG:
            return
        exc_type, exc_val, tb = sys.exc_info()
        if issubclass(exc_type, http.Http404):
            return
        reporter = debug.ExceptionReporter(request, exc_type, exc_val, tb)
        user     = request.user
        if user.is_anonymous():
            user = None

        tb_desc = traceback.extract_tb(tb, 1)
        tb_file, tb_line_num, tb_function, tb_text = tb_desc[0]

        models.ServerError.objects.create(
                hostname        = request.get_host()[:64],
                request_method  = request.method[:10],
                request_path    = request.path[:1024],
                query_string    = request.META.get('QUERY_STRING',''),
                post_data       = request.raw_post_data,
                cookie_data     = repr(request.COOKIES),
                session_id      = request.session.session_key[:64],
                session_data    = repr(dict(request.session.iteritems())),
                user            = user,
                exception_type  = exc_type.__name__[:128],
                exception_str   = str(exc_val),
                source_file     = tb_file[-256:],
                source_line_num = tb_line_num,
                source_function = tb_function[:128],
                source_text     = tb_text[:256],
                issue           = '',
                technical_response = reporter.get_traceback_html(),
            )

<commit_msg>raw_post_data sometimes raises an exception, use request.POST instead<commit_after>import sys
import traceback

from django         import http
from django.conf    import settings
from django.views   import debug

from shoogie        import models

class ExceptionLoggingMiddleware(object):
    def process_exception(self, request, exception):
        if settings.DEBUG:
            return
        exc_type, exc_val, tb = sys.exc_info()
        if issubclass(exc_type, http.Http404):
            return
        reporter = debug.ExceptionReporter(request, exc_type, exc_val, tb)
        user     = request.user
        if user.is_anonymous():
            user = None

        tb_desc = traceback.extract_tb(tb, 1)
        tb_file, tb_line_num, tb_function, tb_text = tb_desc[0]

        models.ServerError.objects.create(
                hostname        = request.get_host()[:64],
                request_method  = request.method[:10],
                request_path    = request.path[:1024],
                query_string    = request.META.get('QUERY_STRING',''),
                post_data       = repr(dict(request.POST)),
                cookie_data     = repr(request.COOKIES),
                session_id      = request.session.session_key[:64],
                session_data    = repr(dict(request.session.iteritems())),
                user            = user,
                exception_type  = exc_type.__name__[:128],
                exception_str   = str(exc_val),
                source_file     = tb_file[-256:],
                source_line_num = tb_line_num,
                source_function = tb_function[:128],
                source_text     = tb_text[:256],
                issue           = '',
                technical_response = reporter.get_traceback_html(),
            )

<|endoftext|>


<commit_before>"""
jupyterlab_widgets setup
"""
import os

from jupyter_packaging import (
    create_cmdclass, install_npm, ensure_targets,
    combine_commands, ensure_python, get_version,
)
import setuptools

HERE = os.path.abspath(os.path.dirname(__file__))

# The name of the project
name="jupyterlab_widgets"

# Ensure a valid python version
ensure_python(">=3.6")

# Get our version
version = get_version(os.path.join(name, "_version.py"))

lab_path = os.path.join(HERE, name, "static")

# Representative files that should exist after a successful build
jstargets = [
    os.path.join(HERE, "lib", "index.js"),
    os.path.join(HERE, name, "static", "package.json"),
]

package_data_spec = {
    name: [
        "*"
    ]
}

labext_name = "@jupyter-widgets/jupyterlab-manager"

data_files_spec = [
    ("share/jupyter/labextensions/%s" % labext_name, lab_path, "*.*"),
]

cmdclass = create_cmdclass("jsdeps",
    package_data_spec=package_data_spec,
    data_files_spec=data_files_spec
)

cmdclass["jsdeps"] = combine_commands(
    install_npm(HERE, build_cmd="build", npm=["jlpm"]),
    ensure_targets(jstargets),
)

with open("README.md", "r") as fh:
    long_description = fh.read()

setup_args = dict(
    name=name,
    version=version,
    url="https://github.com/jupyter-widgets/ipywidgets",
    author="Jupyter Development Team",
    description="A JupyterLab extension.",
    long_description= long_description,
    long_description_content_type="text/markdown",
    cmdclass= cmdclass,
    packages=setuptools.find_packages(),
    install_requires=[
        "jupyterlab~=3.0.0b6",
    ],
    zip_safe=False,
    include_package_data=True,
    python_requires=">=3.6",
    license="BSD-3-Clause",
    platforms="Linux, Mac OS X, Windows",
    keywords=["Jupyter", "JupyterLab"],
    classifiers=[
        "License :: OSI Approved :: BSD License",
        "Programming Language :: Python",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Framework :: Jupyter",
    ],
)

if __name__ == "__main__":
    setuptools.setup(**setup_args)
<commit_msg>Package schema files<commit_after>"""
jupyterlab_widgets setup
"""
import os

from jupyter_packaging import (
    create_cmdclass, install_npm, ensure_targets,
    combine_commands, ensure_python, get_version,
)
import setuptools

HERE = os.path.abspath(os.path.dirname(__file__))

# The name of the project
name="jupyterlab_widgets"

# Ensure a valid python version
ensure_python(">=3.6")

# Get our version
version = get_version(os.path.join(name, "_version.py"))

lab_path = os.path.join(HERE, name, "static")

# Representative files that should exist after a successful build
jstargets = [
    os.path.join(HERE, "lib", "index.js"),
    os.path.join(HERE, name, "static", "package.json"),
]

package_data_spec = {
    name: [
        "*"
    ]
}

labext_name = "@jupyter-widgets/jupyterlab-manager"

data_files_spec = [
    ("share/jupyter/labextensions/%s" % labext_name, lab_path, "*.*"),
    ("share/jupyter/lab/schemas/%s" % labext_name, os.path.join(lab_path, 'schemas', labext_name), "*.*"),
]

cmdclass = create_cmdclass("jsdeps",
    package_data_spec=package_data_spec,
    data_files_spec=data_files_spec
)

cmdclass["jsdeps"] = combine_commands(
    install_npm(HERE, build_cmd="build", npm=["jlpm"]),
    ensure_targets(jstargets),
)

with open("README.md", "r") as fh:
    long_description = fh.read()

setup_args = dict(
    name=name,
    version=version,
    url="https://github.com/jupyter-widgets/ipywidgets",
    author="Jupyter Development Team",
    description="A JupyterLab extension.",
    long_description= long_description,
    long_description_content_type="text/markdown",
    cmdclass= cmdclass,
    packages=setuptools.find_packages(),
    install_requires=[
        "jupyterlab~=3.0.0b6",
    ],
    zip_safe=False,
    include_package_data=True,
    python_requires=">=3.6",
    license="BSD-3-Clause",
    platforms="Linux, Mac OS X, Windows",
    keywords=["Jupyter", "JupyterLab"],
    classifiers=[
        "License :: OSI Approved :: BSD License",
        "Programming Language :: Python",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Framework :: Jupyter",
    ],
)

if __name__ == "__main__":
    setuptools.setup(**setup_args)
<|endoftext|>


<commit_before>import config
import glob
import flask
import os
import json

app = flask.Flask("Centinel")

@app.errorhandler(404)
def not_found(error):
    return flask.make_response(flask.jsonify({'error': 'Not found'}), 404)

@app.route("/versions")
def get_recommended_versions():
    return flask.jsonify({"versions" : config.recommended_versions})

@app.route("/results", methods=['POST'])
def submit_result():
    result = flask.request.json

    # abort if message is empty of if there is no result file
    if not result or "files" not in result:
        flask.abort(400)

    #XXX: validate file and file name
    data = result["files"]["data"]
    file_name = result["files"]["file_name"]
    file_path = os.path.join(config.results_dir, file_name)

    #XXX: overwrite file if exists?
    with open(file_path, "w") as result_fh:
        json.dump(data, result_fh)

    return flask.jsonify({"status" : "success"}), 201

@app.route("/results")
def get_results():
    results = {}

    #XXX: cache the list of results?
    # look in results directory
    for path in glob.glob(os.path.join(config.results_dir,'[!_]*.json')):
        # get name of file and path
        file_name, ext = os.path.splitext(os.path.basename(path))
        # read the result file
        with open(path) as result_file:
            try:
                results[file_name] = json.load(result_file)
            except Exception, e:
                print "Couldn't open file - %s" % (path)

    return flask.jsonify({"results" : results})

@app.route("/experiments")
@app.route("/experiments/<name>")
def get_experiments(name=None):
    experiments = {}

    # look for experiments in experiments directory
    for path in glob.glob(os.path.join(config.experiments_dir,'[!_]*.py')):
        # get name of file and path
        file_name, ext = os.path.splitext(os.path.basename(path))
        # read the result file
        with open(path) as experiment_file:
            experiments[file_name] = experiment_file.read()

    # send all the experiment files
    if name == None:
        return flask.jsonify({"experiments" : experiments})

    if name in experiments:
        # send requested experiment file
        #XXX: Don't send a python file in JSON
        return flask.jsonify({"experiments" : experiments[name]})
    else:
        # not found
        flask.abort(404)

@app.route("/clients")
@app.route("/clients/<name>")
def get_clients(name=None):
    clients = {}

    with open(config.clients_file) as clients_fh:
        clients = json.load(clients_fh)

    # send all the client details
    if name == None:
        return flask.jsonify(clients)

    if name in clients:
        # send requested client details
        return flask.jsonify(client[name])
    else:
        # not found
        flask.abort(404)

@app.route("/log", methods=["POST"])
def submit_log():
    pass

if __name__ == "__main__":
    app.run(debug=True)
<commit_msg>Use multipart/form-data to send result file<commit_after>import config
import glob
import flask
import os
import json

from werkzeug import secure_filename

app = flask.Flask("Centinel")

@app.errorhandler(404)
def not_found(error):
    return flask.make_response(flask.jsonify({'error': 'Not found'}), 404)

@app.route("/versions")
def get_recommended_versions():
    return flask.jsonify({"versions" : config.recommended_versions})

@app.route("/results", methods=['POST'])
def submit_result():
    # abort if there is no result file
    if not flask.request.files:
        flask.abort(400)

    #XXX: overwrite file if exists?
    result_file = flask.request.files['result']
    file_name = secure_filename(result_file.filename)
    file_path = os.path.join(config.results_dir, file_name)
    result_file.save(file_path)

    return flask.jsonify({"status" : "success"}), 201

@app.route("/results")
def get_results():
    results = {}

    #XXX: cache the list of results?
    # look in results directory
    for path in glob.glob(os.path.join(config.results_dir,'[!_]*.json')):
        # get name of file and path
        file_name, ext = os.path.splitext(os.path.basename(path))
        # read the result file
        with open(path) as result_file:
            try:
                results[file_name] = json.load(result_file)
            except Exception, e:
                print "Couldn't open file - %s" % (path)

    return flask.jsonify({"results" : results})

@app.route("/experiments")
@app.route("/experiments/<name>")
def get_experiments(name=None):
    experiments = {}

    # look for experiments in experiments directory
    for path in glob.glob(os.path.join(config.experiments_dir,'[!_]*.py')):
        # get name of file and path
        file_name, ext = os.path.splitext(os.path.basename(path))
        # read the result file
        with open(path) as experiment_file:
            experiments[file_name] = experiment_file.read()

    # send all the experiment files
    if name == None:
        return flask.jsonify({"experiments" : experiments})

    if name in experiments:
        # send requested experiment file
        #XXX: Don't send a python file in JSON
        return flask.jsonify({"experiments" : experiments[name]})
    else:
        # not found
        flask.abort(404)

@app.route("/clients")
@app.route("/clients/<name>")
def get_clients(name=None):
    clients = {}

    with open(config.clients_file) as clients_fh:
        clients = json.load(clients_fh)

    # send all the client details
    if name == None:
        return flask.jsonify(clients)

    if name in clients:
        # send requested client details
        return flask.jsonify(client[name])
    else:
        # not found
        flask.abort(404)

@app.route("/log", methods=["POST"])
def submit_log():
    pass

if __name__ == "__main__":
    app.run(debug=True)
<|endoftext|>


<commit_before>#-*- coding: utf-8 -*-
from django.conf import settings
from django.core import exceptions
from django.utils.importlib import import_module
from shop.payment.api import PaymentAPI
from shop.shipping.api import ShippingAPI
from shop.util.loader import load_class

class BackendsPool(object):
    """
    A pool for backends.
    It handles loading backend modules (both shipping and payment backends), and
    keeping a cached copy of the classes in-memory (so that the backends aren't
    loaded from file every time one requests them)
    """

    SHIPPING = 'SHOP_SHIPPING_BACKENDS'
    PAYMENT = 'SHOP_PAYMENT_BACKENDS'

    PAYMENT_SHOP_INTERFACE = PaymentAPI()
    SHIPPING_SHOP_INTERFACE = ShippingAPI()

    def __init__(self, use_cache=True):
        """
        The use_cache parameter is mostly used for testing, since setting it
        to false will trigger reloading from disk
        """
        self._payment_backends_list = []
        self._shippment_backends_list = []
        self.use_cache = use_cache

    def get_payment_backends_list(self):
        """
        Returns the list of payment backends, as instances, from the list of
        backends defined in settings.SHOP_PAYMENT_BACKENDS
        """
        if self._payment_backends_list and self.use_cache:
            return self._payment_backends_list
        else:
            self._payment_backends_list = self._load_backends_list(self.PAYMENT,
                                            self.PAYMENT_SHOP_INTERFACE)
            return self._payment_backends_list

    def get_shipping_backends_list(self):
        """
        Returns the list of shipping backends, as instances, from the list of
        backends defined in settings.SHOP_SHIPPING_BACKENDS
        """
        if self._shippment_backends_list and self.use_cache:
            return self._shippment_backends_list
        else:
            self._shippment_backends_list = self._load_backends_list(self.SHIPPING,
                                            self.SHIPPING_SHOP_INTERFACE)
            return self._shippment_backends_list

    def _check_backend_for_validity(self, backend_instance):
        """
        This enforces having a valid name and url namespace defined.
        Backends, both shipping and payment are namespaced in respectively
        /pay/ and /ship/ URL spaces, so as to avoid name clashes.

        "Namespaces are one honking great idea -- let's do more of those!"
        """
        backend_name = getattr(backend_instance, 'backend_name', "")
        if not backend_name:
            d_tuple = (str(backend_instance), str(type(backend_instance)))
            raise NotImplementedError(
            'One of your backends ("%s" of type "%s") lacks a name, please define one.' % d_tuple
            )

        url_namespace = getattr(backend_instance, 'url_namespace', "")
        if not url_namespace:
            raise NotImplementedError(
                'Please set a namespace for backend "%s"' % backend_instance.backend_name)

    def _load_backends_list(self, setting_name, shop_object):
        """ This actually loads the backends from disk"""
        result = []
        if not getattr(settings, setting_name, None):
            return result

        for backend_path in getattr(settings, setting_name, None):
            # The load_class function takes care of the classloading. It returns
            # a CLASS, not an INSTANCE!
            mod_class = load_class(backend_path,setting_name)

            # Seems like it is a real, valid class - let's instanciate it!
            # This is where the backends receive their self.shop reference!
            mod_instance = mod_class(shop=shop_object)

            self._check_backend_for_validity(mod_instance)

            # The backend seems valid (nothing raised), let's add it to the
            # return list.
            result.append(mod_instance)

        return result

backends_pool = BackendsPool()<commit_msg>Cleaned up imports<commit_after>#-*- coding: utf-8 -*-
from django.conf import settings
from shop.payment.api import PaymentAPI
from shop.shipping.api import ShippingAPI
from shop.util.loader import load_class

class BackendsPool(object):
    """
    A pool for backends.
    It handles loading backend modules (both shipping and payment backends), and
    keeping a cached copy of the classes in-memory (so that the backends aren't
    loaded from file every time one requests them)
    """

    SHIPPING = 'SHOP_SHIPPING_BACKENDS'
    PAYMENT = 'SHOP_PAYMENT_BACKENDS'

    PAYMENT_SHOP_INTERFACE = PaymentAPI()
    SHIPPING_SHOP_INTERFACE = ShippingAPI()

    def __init__(self, use_cache=True):
        """
        The use_cache parameter is mostly used for testing, since setting it
        to false will trigger reloading from disk
        """
        self._payment_backends_list = []
        self._shippment_backends_list = []
        self.use_cache = use_cache

    def get_payment_backends_list(self):
        """
        Returns the list of payment backends, as instances, from the list of
        backends defined in settings.SHOP_PAYMENT_BACKENDS
        """
        if self._payment_backends_list and self.use_cache:
            return self._payment_backends_list
        else:
            self._payment_backends_list = self._load_backends_list(self.PAYMENT,
                                            self.PAYMENT_SHOP_INTERFACE)
            return self._payment_backends_list

    def get_shipping_backends_list(self):
        """
        Returns the list of shipping backends, as instances, from the list of
        backends defined in settings.SHOP_SHIPPING_BACKENDS
        """
        if self._shippment_backends_list and self.use_cache:
            return self._shippment_backends_list
        else:
            self._shippment_backends_list = self._load_backends_list(self.SHIPPING,
                                            self.SHIPPING_SHOP_INTERFACE)
            return self._shippment_backends_list

    def _check_backend_for_validity(self, backend_instance):
        """
        This enforces having a valid name and url namespace defined.
        Backends, both shipping and payment are namespaced in respectively
        /pay/ and /ship/ URL spaces, so as to avoid name clashes.

        "Namespaces are one honking great idea -- let's do more of those!"
        """
        backend_name = getattr(backend_instance, 'backend_name', "")
        if not backend_name:
            d_tuple = (str(backend_instance), str(type(backend_instance)))
            raise NotImplementedError(
            'One of your backends ("%s" of type "%s") lacks a name, please define one.' % d_tuple
            )

        url_namespace = getattr(backend_instance, 'url_namespace', "")
        if not url_namespace:
            raise NotImplementedError(
                'Please set a namespace for backend "%s"' % backend_instance.backend_name)

    def _load_backends_list(self, setting_name, shop_object):
        """ This actually loads the backends from disk"""
        result = []
        if not getattr(settings, setting_name, None):
            return result

        for backend_path in getattr(settings, setting_name, None):
            # The load_class function takes care of the classloading. It returns
            # a CLASS, not an INSTANCE!
            mod_class = load_class(backend_path,setting_name)

            # Seems like it is a real, valid class - let's instanciate it!
            # This is where the backends receive their self.shop reference!
            mod_instance = mod_class(shop=shop_object)

            self._check_backend_for_validity(mod_instance)

            # The backend seems valid (nothing raised), let's add it to the
            # return list.
            result.append(mod_instance)

        return result

backends_pool = BackendsPool()<|endoftext|>


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

import os
from signal import SIGTERM
from subprocess import Popen

from tests.app import app

def test(tmpdir, cov):
    tmpdir.ensure("app.pid")
    pidpath = tmpdir.join("app.pid")
    pidfile = str(pidpath)

    args = ["python", app.__file__, pidfile]
    cmd = " ".join(args)
    p = Popen(cmd, shell=True)
    status = p.wait()

    assert status == 0

    assert os.path.exists(pidfile)
    assert os.path.isfile(pidfile)

    f = open(pidfile, "r")
    pid = int(f.read().strip())
    f.close()

    os.kill(pid, SIGTERM)
    assert True

    os.remove(pidfile)

    cov.combine()
<commit_msg>tests.app.test_daemon: Skip if we can't import pytest_cov (for coverage reasons)<commit_after>#!/usr/bin/env python

import os
from signal import SIGTERM
from subprocess import Popen

import pytest
pytest.importorskip("pytest_cov")

from tests.app import app

def test(tmpdir, cov):
    tmpdir.ensure("app.pid")
    pidpath = tmpdir.join("app.pid")
    pidfile = str(pidpath)

    args = ["python", app.__file__, pidfile]
    cmd = " ".join(args)
    p = Popen(cmd, shell=True)
    status = p.wait()

    assert status == 0

    assert os.path.exists(pidfile)
    assert os.path.isfile(pidfile)

    f = open(pidfile, "r")
    pid = int(f.read().strip())
    f.close()

    os.kill(pid, SIGTERM)
    assert True

    os.remove(pidfile)

    cov.combine()
<|endoftext|>


<commit_before>import socket
from email.utils import formatdate

CRLF = '\r\n'

def create_server():
    addr = ('127.0.0.1', 8001)

    server = socket.socket(
        socket.AF_INET,
        socket.SOCK_STREAM,
        socket.IPPROTO_IP
    )

    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    server.bind(addr)
    server.listen(1)
    return server

def respond():
    server = create_server()
    try:
        conn, addr = server.accept()
        message_in = ""
        while True:
            msg = conn.recv(16)
            message_in += msg
            if len(msg) < 16:
                break
        try:
            parse_request(message_in)
            conn.sendall(response_ok())
        except (NotImplementedError, ValueError, AttributeError) as e:
            conn.sendall(response_error(e.message))
        conn.close()
    except KeyboardInterrupt:
        break

def response_ok():
    response = []
    now = formatdate(usegmt=True)
    body = "Hello World, I need to travel."
    response.append('HTTP/1.1 200 OK')
    response.append('Date: {}'.format(now))
    response.append('Content-Type: text/plain')
    response.append('Content-Length: {}'.format(len(body)))
    response.append('Connection: close')
    response.append('')
    response.append(body)
    return CRLF.join(response)

def response_error():
    response = []
    now = formatdate(usegmt=True)
    body = ('\nThe server encountered an unexpected internal '
            'error.')
    response.append('HTTP 1.1 500 Internal Server Error')
    response.append('Date: {}'.format(now))
    response.append('Content-Type: text/html')
    response.append('Content-Length: {}'.format(len(body)))
    response.append('Connection: close')
    response.append('')
    response.append(body)
    return CRLF.join(response)

def parse_request(request):
    request = request.split(CRLF)
    host = False
    if 'GET' not in request[0]:
        raise NotImplementedError('405')
    elif 'HTTP/1.1' not in request[0]:
        raise ValueError('505')
    for line in request[1:]:
        if 'Host:' in line:
            host = True
    if not host:
        raise AttributeError('400')
    request_line = request.split()
    return request_line[1]

if __name__ == '__main__':
    respond()
<commit_msg>response_error returns a good response<commit_after>import socket
from email.utils import formatdate

CRLF = '\r\n'

def create_server():
    addr = ('127.0.0.1', 8001)

    server = socket.socket(
        socket.AF_INET,
        socket.SOCK_STREAM,
        socket.IPPROTO_IP
    )

    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    server.bind(addr)
    server.listen(1)
    return server

def respond():
    server = create_server()
    while True:
        try:
            conn, addr = server.accept()
            message_in = ""
            while True:
                msg = conn.recv(16)
                message_in += msg
                if len(msg) < 16:
                    break
            try:
                parse_request(message_in)
                conn.sendall(response_ok())
            except (NotImplementedError, ValueError, AttributeError) as e:
                conn.sendall(response_error(e.message))
            conn.close()
        except KeyboardInterrupt:
            break

def response_ok():
    response = []
    now = formatdate(usegmt=True)
    body = "Thank you for the appropriate request."
    response.append('HTTP/1.1 200 OK')
    response.append('Date: {}'.format(now))
    response.append('Content-Type: text/plain')
    response.append('Content-Length: {}'.format(len(body)))
    response.append('Connection: close')
    response.append('')
    response.append(body)
    return CRLF.join(response)

def response_error(message):
    codes = {'405': 'Method Not Allowed',
             '505': 'HTTP Version Not Supported',
             '400': 'Bad Request'
             }
    response = []
    now = formatdate(usegmt=True)
    body = (codes[message])
    response.append('HTTP 1.1 {} {}'.format(message, codes[message]))
    response.append('Date: {}'.format(now))
    response.append('Content-Type: text/plain')
    response.append('Content-Length: {}'.format(len(body)))
    response.append('Connection: close')
    response.append('')
    response.append(body)
    return CRLF.join(response)

def parse_request(request):
    request = request.split(CRLF)
    host = False
    if 'GET' not in request[0]:
        raise NotImplementedError('405')
    elif 'HTTP/1.1' not in request[0]:
        raise ValueError('505')
    for line in request[1:]:
        if 'Host:' in line:
            host = True
    if not host:
        raise AttributeError('400')
    request_line = request.split()
    return request_line[1]

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


<commit_before># Copyright 2013: Mirantis Inc.
# All Rights Reserved.
#
#    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.

import mock

from rally.benchmark.scenarios.nova import utils
from rally.benchmark import utils as butils
from rally import exceptions as rally_exceptions
from tests import fakes
from tests import test

class NovaScenarioTestCase(test.TestCase):

    def setUp(self):
        super(NovaScenarioTestCase, self).setUp()

    def test_generate_random_name(self):
        for length in [8, 16, 32, 64]:
            name = utils.NovaScenario._generate_random_name(length)
            self.assertEqual(len(name), length)
            self.assertTrue(name.isalpha())

    def test_failed_server_status(self):
        server_manager = fakes.FakeFailedServerManager()
        self.assertRaises(rally_exceptions.GetResourceFailure,
                          butils.get_from_manager(),
                          server_manager.create('fails', '1', '2'))

    @mock.patch("rally.benchmark.scenarios.nova.utils.time.sleep")
    @mock.patch("rally.utils")
    @mock.patch("rally.benchmark.utils.osclients")
    @mock.patch("rally.benchmark.utils.resource_is")
    def test_server_helper_methods(self, mock_ris, mock_osclients,
                                   mock_rally_utils, mock_sleep):

        def _is_ready(resource):
            return resource.status == "ACTIVE"

        mock_ris.return_value = _is_ready
        get_from_mgr = butils.get_from_manager()

        fc = fakes.FakeClients()
        mock_osclients.Clients.return_value = fc
        fake_nova = fakes.FakeNovaClient()
        fc.get_nova_client = lambda: fake_nova
        fsm = fakes.FakeServerManager(fake_nova.images)
        fake_server = fsm.create("s1", "i1", 1)
        fsm.create = lambda name, iid, fid, **kwargs: fake_server
        fake_nova.servers = fsm
        fake_image_id = fsm.create_image(fake_server, 'img')
        fake_image = fsm.images.get(fake_image_id)
        fsm.create_image = lambda svr, name: fake_image.id
        temp_keys = ["username", "password", "tenant_name", "uri"]
        users_endpoints = [dict(zip(temp_keys, temp_keys))]
        utils.NovaScenario._clients = butils.\
            create_openstack_clients(users_endpoints, temp_keys)[0]
        utils.utils = mock_rally_utils
        utils.bench_utils.get_from_manager = lambda: get_from_mgr

        utils.NovaScenario._boot_server("s1", "i1", 1)
        utils.NovaScenario._create_image(fake_server)
        utils.NovaScenario._suspend_server(fake_server)
        utils.NovaScenario._delete_server(fake_server)

        expected = [
            mock.call.wait_for(fake_server, is_ready=_is_ready,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600),
            mock.call.wait_for(fake_image, is_ready=_is_ready,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600),
            mock.call.wait_for(fake_server, is_ready=_is_ready,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600),
            mock.call.wait_for(fake_server, is_ready=butils.is_none,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600)
        ]

        self.assertEqual(expected, mock_rally_utils.mock_calls)
<commit_msg>Add missing tests for rally/benchmark/scenarios/nova/utils.py<commit_after># Copyright 2013: Mirantis Inc.
# All Rights Reserved.
#
#    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.

import mock

from rally.benchmark.scenarios.nova import utils
from rally.benchmark import utils as butils
from rally import exceptions as rally_exceptions
from rally.openstack.common.fixture import mockpatch
from tests import fakes
from tests import test

BM_UTILS = 'rally.benchmark.utils'
NOVA_UTILS = "rally.benchmark.scenarios.nova.utils"

class NovaScenarioTestCase(test.TestCase):

    def setUp(self):
        super(NovaScenarioTestCase, self).setUp()
        self.server = mock.Mock()
        self.server1 = mock.Mock()
        self.image = mock.Mock()
        self.res_is = mockpatch.Patch(BM_UTILS + ".resource_is")
        self.get_fm = mockpatch.Patch(BM_UTILS + '.get_from_manager')
        self.wait_for = mockpatch.Patch(NOVA_UTILS + ".utils.wait_for")
        self.useFixture(self.wait_for)
        self.useFixture(self.res_is)
        self.useFixture(self.get_fm)
        self.gfm = self.get_fm.mock
        self.useFixture(mockpatch.Patch('time.sleep'))

    def test_generate_random_name(self):
        for length in [8, 16, 32, 64]:
            name = utils.NovaScenario._generate_random_name(length)
            self.assertEqual(len(name), length)
            self.assertTrue(name.isalpha())

    def test_failed_server_status(self):
        self.get_fm.cleanUp()
        server_manager = fakes.FakeFailedServerManager()
        self.assertRaises(rally_exceptions.GetResourceFailure,
                          butils.get_from_manager(),
                          server_manager.create('fails', '1', '2'))

    @mock.patch("rally.utils")
    @mock.patch(BM_UTILS + ".osclients")
    def test_server_helper_methods(self, mock_osclients, mock_rally_utils):
        def _is_ready(resource):
            return resource.status == "ACTIVE"

        self.res_is.mock.return_value = _is_ready
        get_from_mgr = butils.get_from_manager()

        fc = fakes.FakeClients()
        mock_osclients.Clients.return_value = fc
        fake_nova = fakes.FakeNovaClient()
        fc.get_nova_client = lambda: fake_nova
        fsm = fakes.FakeServerManager(fake_nova.images)
        fake_server = fsm.create("s1", "i1", 1)
        fsm.create = lambda name, iid, fid, **kwargs: fake_server
        fake_nova.servers = fsm
        fake_image_id = fsm.create_image(fake_server, 'img')
        fake_image = fsm.images.get(fake_image_id)
        fsm.create_image = lambda svr, name: fake_image.id
        temp_keys = ["username", "password", "tenant_name", "uri"]
        users_endpoints = [dict(zip(temp_keys, temp_keys))]
        utils.NovaScenario._clients = butils.\
            create_openstack_clients(users_endpoints, temp_keys)[0]
        utils.utils = mock_rally_utils
        utils.bench_utils.get_from_manager = lambda: get_from_mgr

        utils.NovaScenario._boot_server("s1", "i1", 1)
        utils.NovaScenario._create_image(fake_server)
        utils.NovaScenario._suspend_server(fake_server)
        utils.NovaScenario._delete_server(fake_server)

        expected = [
            mock.call.wait_for(fake_server, is_ready=_is_ready,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600),
            mock.call.wait_for(fake_image, is_ready=_is_ready,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600),
            mock.call.wait_for(fake_server, is_ready=_is_ready,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600),
            mock.call.wait_for(fake_server, is_ready=butils.is_none,
                               update_resource=butils.get_from_manager(),
                               check_interval=3, timeout=600)
        ]

        self.assertEqual(expected, mock_rally_utils.mock_calls)

    def test_server_reboot(self):
        utils.NovaScenario._reboot_server(self.server)
        self.server.reboot.assert_called_once_with(reboot_type='SOFT')
        self.wait_for.mock.assert_called_once_with(self.server,
                                                   update_resource=self.gfm(),
                                                   is_ready=self.res_is.mock(),
                                                   check_interval=3,
                                                   timeout=600)
        self.res_is.mock.assert_has_calls(mock.call('ACTIVE'))

    def test_server_start(self):
        utils.NovaScenario._start_server(self.server)
        self.server.start.assert_called_once_with()
        self.wait_for.mock.assert_called_once_with(self.server,
                                                   update_resource=self.gfm(),
                                                   is_ready=self.res_is.mock(),
                                                   check_interval=2,
                                                   timeout=600)
        self.res_is.mock.assert_has_calls(mock.call('ACTIVE'))

    def test_server_stop(self):
        utils.NovaScenario._stop_server(self.server)
        self.server.stop.assert_called_once_with()
        self.wait_for.mock.assert_called_once_with(self.server,
                                                   update_resource=self.gfm(),
                                                   is_ready=self.res_is.mock(),
                                                   check_interval=2,
                                                   timeout=600)
        self.res_is.mock.assert_has_calls(mock.call('SHUTOFF'))

    def test_server_rescue(self):
        utils.NovaScenario._rescue_server(self.server)
        self.server.rescue.assert_called_once_with()
        self.wait_for.mock.assert_called_once_with(self.server,
                                                   update_resource=self.gfm(),
                                                   is_ready=self.res_is.mock(),
                                                   check_interval=3,
                                                   timeout=600)
        self.res_is.mock.assert_has_calls(mock.call('RESCUE'))

    def test_server_unrescue(self):
        utils.NovaScenario._unrescue_server(self.server)
        self.server.unrescue.assert_called_once_with()
        self.wait_for.mock.assert_called_once_with(self.server,
                                                   update_resource=self.gfm(),
                                                   is_ready=self.res_is.mock(),
                                                   check_interval=3,
                                                   timeout=600)
        self.res_is.mock.assert_has_calls(mock.call('ACTIVE'))

    @mock.patch(BM_UTILS + ".is_none")
    @mock.patch(NOVA_UTILS + '.NovaScenario.clients')
    def test_delete_all_servers(self, mock_clients, mock_isnone):
        mock_clients("nova").servers.list.return_value = [self.server,
                                                          self.server1]
        utils.NovaScenario._delete_all_servers()
        expected = [
            mock.call(self.server, is_ready=mock_isnone,
                      update_resource=self.gfm(),
                      check_interval=3, timeout=600),
            mock.call(self.server1, is_ready=mock_isnone,
                      update_resource=self.gfm(),
                      check_interval=3, timeout=600)
        ]
        self.assertEqual(expected, self.wait_for.mock.mock_calls)

    def test_delete_image(self):
        utils.NovaScenario._delete_image(self.image)
        self.image.delete.assert_called_once_with()
        self.wait_for.mock.assert_called_once_with(self.image,
                                                   update_resource=self.gfm(),
                                                   is_ready=self.res_is.mock(),
                                                   check_interval=3,
                                                   timeout=600)
        self.res_is.mock.assert_has_calls(mock.call('DELETED'))

    @mock.patch(NOVA_UTILS + '.NovaScenario.clients')
    def test_boot_servers(self, mock_clients):
        mock_clients("nova").servers.list.return_value = [self.server,
                                                          self.server1]
        utils.NovaScenario._boot_servers('prefix', 'image', 'flavor', 2)
        expected = [
            mock.call(self.server, is_ready=self.res_is.mock(),
                      update_resource=self.gfm(),
                      check_interval=3, timeout=600),
            mock.call(self.server1, is_ready=self.res_is.mock(),
                      update_resource=self.gfm(),
                      check_interval=3, timeout=600)
        ]
        self.assertEqual(expected, self.wait_for.mock.mock_calls)
        self.res_is.mock.assert_has_calls(mock.call('ACTIVE'))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

import os

from django.db import models
from django.shortcuts import get_object_or_404
from django.utils.cache import add_never_cache_headers
from django.utils.translation import get_language_from_request

from rest_framework import generics
from rest_framework import status
from rest_framework import views
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.response import Response

from shop import app_settings
from shop.models.product import ProductModel
from shop.rest.filters import CMSPagesFilterBackend
from shop.rest.money import JSONRenderer
from shop.rest.renderers import CMSPageRenderer
from shop.serializers.bases import ProductSerializer
from shop.serializers.defaults import AddToCartSerializer

class ProductListView(generics.ListAPIView):
    """
    This view is used to list all products which shall be visible below a certain URL.

    Usage: Add it to the urlpatterns responsible for rendering the catalog's views. The
    file containing this patterns can be referenced by the CMS apphook ``ProductsListApp``
    and used by the CMS pages responsible for rendering the catalog's list.
    ```
    urlpatterns = [
        url(r'^$', ProductListView.as_view()),
        url(r'^(?P<slug>[\w-]+)/?$', ProductRetrieveView.as_view()),  # see below
        ...
    ]
    ```

    You may add these attributes to the ``as_view()`` method:

    :param renderer_classes: A list or tuple of REST renderer classes.

    :param product_model: The product model onto which the filter set is applied.

    :param serializer_class: The serializer class used to process the queryset returned
        by the catalog's product list view.

    :param limit_choices_to: Limit the queryset of product models to these choices.

    :param filter_class: A filter set which must be inherit from :class:`django_filters.FilterSet`.
    """

    renderer_classes = (CMSPageRenderer, JSONRenderer, BrowsableAPIRenderer)
    product_model = ProductModel
    serializer_class = app_settings.PRODUCT_SUMMARY_SERIALIZER
    limit_choices_to = models.Q()
    filter_class = None

    def get(self, request, *args, **kwargs):
        # TODO: we must find a better way to invalidate the cache.
        # Simply adding a no-cache header eventually decreases the performance dramatically.
        response = self.list(request, *args, **kwargs)
        add_never_cache_headers(response)
        return response

    def get_queryset(self):
        qs = self.product_model.objects.filter(self.limit_choices_to)
        # restrict queryset by language
        if hasattr(self.product_model, 'translations'):
            language = get_language_from_request(self.request)
            qs = qs.prefetch_related('translations').filter(translations__language_code=language)
        qs = qs.select_related('polymorphic_ctype')
        return qs

    def get_template_names(self):
        # TODO: let this be configurable through a View member variable
        return [self.request.current_page.get_template()]

class SyncCatalogView(views.APIView):
    """
    This view is used to synchronize the number items in the cart from using the catalog's list
    view. It is intended for sites, where we don't want having to access the product's detail
    view for adding it to the cart.

    Use Angular directive <ANY shop-sync-catalog-item="..."> on each catalog item to set up
    the communication with this view.

    To the ``urlpatterns`` responsible for the list view, add
    ```
    urlpatterns = [
        ...
        url(r'^sync-catalog$', SyncCatalogView.as_view(
            serializer_class=SyncCatalogSerializer,
        )),
        ...
    ]
    ```
    to the URLs as specified by the merchant's implementation of its ``ProductsListApp``.

    The class ``SyncCatalogSerializer`` must be provided by the merchant implementation.
    """
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)
    product_model = ProductModel
    product_field = 'product'
    serializer_class = None  # must be overridden by SyncCatalogView.as_view()
    filter_class = None  # may be overridden by SyncCatalogView.as_view()
    limit_choices_to = models.Q()

    def get_context(self, request, **kwargs):
        filter_kwargs = {'id': request.data.get('id')}
        if hasattr(self.product_model, 'translations'):
            filter_kwargs.update(translations__language_code=get_language_from_request(self.request))
        queryset = self.product_model.objects.filter(self.limit_choices_to, **filter_kwargs)
        product = get_object_or_404(queryset)
        return {self.product_field: product, 'request': request}

    def get(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(context=context, **kwargs)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(data=request.data, context=context)
        if serializer.is_valid():
            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class AddToCartView(views.APIView):
    """
    Handle the "Add to Cart" dialog on the products detail page.
    """
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)
    product_model = ProductModel
    serializer_class = AddToCartSerializer
    lookup_field = lookup_url_kwarg = 'slug'
    limit_choices_to = models.Q()

    def get_context(self, request, **kwargs):
        assert self.lookup_url_kwarg in kwargs
        filter_kwargs = {self.lookup_field: kwargs.pop(self.lookup_url_kwarg)}
        if hasattr(self.product_model, 'translations'):
            filter_kwargs.update(translations__language_code=get_language_from_request(self.request))
        queryset = self.product_model.objects.filter(self.limit_choices_to, **filter_kwargs)
        product = get_object_or_404(queryset)
        return {'product': product, 'request': request}

    def get(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(context=context, **kwargs)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(data=request.data, context=context)
        if serializer.is_valid():
            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ProductRetrieveView(generics.RetrieveAPIView):
    """
    This view is used to retrieve and render a certain product.

    Usage: Add it to the urlpatterns responsible for rendering the catalog's views. The
    file containing this patterns can be referenced by the CMS apphook ``ProductsListApp``
    and used by the CMS pages responsible for rendering the catalog's list.
    ```
    urlpatterns = [
        url(r'^$', ProductListView.as_view()),  # see above
        url(r'^(?P<slug>[\w-]+)/?$', ProductRetrieveView.as_view()),
        ...
    ]
    ```
    You may add these attributes to the ``as_view()`` method:

    :param renderer_classes: A list or tuple of REST renderer classes.

    :param lookup_field: The model field used to retrieve the product instance.

    :param lookup_url_kwarg: The name of the parsed URL fragment.

    :param serializer_class: The serializer class used to process the queryset returned
        by the catalog's product detail view.

    :param limit_choices_to: Limit the queryset of product models to these choices.
    """

    renderer_classes = (CMSPageRenderer, JSONRenderer, BrowsableAPIRenderer)
    lookup_field = lookup_url_kwarg = 'slug'
    product_model = ProductModel
    serializer_class = ProductSerializer
    limit_choices_to = models.Q()

    def get_template_names(self):
        product = self.get_object()
        app_label = product._meta.app_label.lower()
        basename = '{}-detail.html'.format(product.__class__.__name__.lower())
        return [
            os.path.join(app_label, 'catalog', basename),
            os.path.join(app_label, 'catalog/product-detail.html'),
            'shop/catalog/product-detail.html',
        ]

    def get_renderer_context(self):
        renderer_context = super(ProductRetrieveView, self).get_renderer_context()
        if renderer_context['request'].accepted_renderer.format == 'html':
            # add the product as Python object to the context
            renderer_context['product'] = self.get_object()
        return renderer_context

    def get_object(self):
        if not hasattr(self, '_product'):
            assert self.lookup_url_kwarg in self.kwargs
            filter_kwargs = {self.lookup_field: self.kwargs[self.lookup_url_kwarg]}
            if hasattr(self.product_model, 'translations'):
                filter_kwargs.update(translations__language_code=get_language_from_request(self.request))
            queryset = self.product_model.objects.filter(self.limit_choices_to, **filter_kwargs)
            self._product = get_object_or_404(queryset)
        return self._product

class ProductSelectView(generics.ListAPIView):
    """
    A simple list view, which is used only by the admin backend. It is required to fetch
    the data for rendering the select widget when looking up for a product.
    """
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)
    serializer_class = app_settings.PRODUCT_SELECT_SERIALIZER

    def get_queryset(self):
        term = self.request.GET.get('term', '')
        if len(term) >= 2:
            return ProductModel.objects.select_lookup(term)[:10]
        return ProductModel.objects.all()[:10]

class AddFilterContextMixin(object):
    """
    A mixin to enrich the render context by ``filter`` containing information
    on how to render the filter set, supplied by attribute ``filter_class``.
    """
    def get_renderer_context(self):
        renderer_context = super(AddFilterContextMixin, self).get_renderer_context()
        if self.filter_class and renderer_context['request'].accepted_renderer.format == 'html':
            # restrict filter set to products associated to this CMS page only
            queryset = self.product_model.objects.filter(self.limit_choices_to)
            queryset = CMSPagesFilterBackend().filter_queryset(self.request, queryset, self)
            renderer_context['filter'] = self.filter_class.get_render_context(self.request, queryset)
        return renderer_context
<commit_msg>fixed docstring<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

import os

from django.db import models
from django.shortcuts import get_object_or_404
from django.utils.cache import add_never_cache_headers
from django.utils.translation import get_language_from_request

from rest_framework import generics
from rest_framework import status
from rest_framework import views
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.response import Response

from shop import app_settings
from shop.models.product import ProductModel
from shop.rest.filters import CMSPagesFilterBackend
from shop.rest.money import JSONRenderer
from shop.rest.renderers import CMSPageRenderer
from shop.serializers.bases import ProductSerializer
from shop.serializers.defaults import AddToCartSerializer

class ProductListView(generics.ListAPIView):
    """
    This view is used to list all products which shall be visible below a certain URL.

    Usage: Add it to the urlpatterns responsible for rendering the catalog's views. The
    file containing this patterns can be referenced by the CMS apphook used by the CMS pages
    responsible for rendering the catalog's list view.
    ```
    urlpatterns = [
        url(r'^$', ProductListView.as_view()),
        url(r'^(?P<slug>[\w-]+)/?$', ProductRetrieveView.as_view()),  # see below
        ...
    ]
    ```

    You may add these attributes to the ``as_view()`` method:

    :param renderer_classes: A list or tuple of REST renderer classes.

    :param product_model: The product model onto which the filter set is applied.

    :param serializer_class: The serializer class used to process the queryset returned
        by the catalog's product list view.

    :param limit_choices_to: Limit the queryset of product models to these choices.

    :param filter_class: A filter set which must be inherit from :class:`django_filters.FilterSet`.
    """

    renderer_classes = (CMSPageRenderer, JSONRenderer, BrowsableAPIRenderer)
    product_model = ProductModel
    serializer_class = app_settings.PRODUCT_SUMMARY_SERIALIZER
    limit_choices_to = models.Q()
    filter_class = None

    def get(self, request, *args, **kwargs):
        # TODO: we must find a better way to invalidate the cache.
        # Simply adding a no-cache header eventually decreases the performance dramatically.
        response = self.list(request, *args, **kwargs)
        add_never_cache_headers(response)
        return response

    def get_queryset(self):
        qs = self.product_model.objects.filter(self.limit_choices_to)
        # restrict queryset by language
        if hasattr(self.product_model, 'translations'):
            language = get_language_from_request(self.request)
            qs = qs.prefetch_related('translations').filter(translations__language_code=language)
        qs = qs.select_related('polymorphic_ctype')
        return qs

    def get_template_names(self):
        # TODO: let this be configurable through a View member variable
        return [self.request.current_page.get_template()]

class SyncCatalogView(views.APIView):
    """
    This view is used to synchronize the number items in the cart from using the catalog's list
    view. It is intended for sites, where we don't want having to access the product's detail
    view for adding it to the cart.

    Use Angular directive <ANY shop-sync-catalog-item="..."> on each catalog item to set up
    the communication with this view.

    To the ``urlpatterns`` responsible for the list view, add
    ```
    urlpatterns = [
        ...
        url(r'^sync-catalog$', SyncCatalogView.as_view(
            serializer_class=SyncCatalogSerializer,
        )),
        ...
    ]
    ```
    to the URLs as specified by the merchant's implementation of its catalog list.

    The class ``SyncCatalogSerializer`` must be provided by the merchant implementation.
    """
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)
    product_model = ProductModel
    product_field = 'product'
    serializer_class = None  # must be overridden by SyncCatalogView.as_view()
    filter_class = None  # may be overridden by SyncCatalogView.as_view()
    limit_choices_to = models.Q()

    def get_context(self, request, **kwargs):
        filter_kwargs = {'id': request.data.get('id')}
        if hasattr(self.product_model, 'translations'):
            filter_kwargs.update(translations__language_code=get_language_from_request(self.request))
        queryset = self.product_model.objects.filter(self.limit_choices_to, **filter_kwargs)
        product = get_object_or_404(queryset)
        return {self.product_field: product, 'request': request}

    def get(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(context=context, **kwargs)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(data=request.data, context=context)
        if serializer.is_valid():
            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class AddToCartView(views.APIView):
    """
    Handle the "Add to Cart" dialog on the products detail page.
    """
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)
    product_model = ProductModel
    serializer_class = AddToCartSerializer
    lookup_field = lookup_url_kwarg = 'slug'
    limit_choices_to = models.Q()

    def get_context(self, request, **kwargs):
        assert self.lookup_url_kwarg in kwargs
        filter_kwargs = {self.lookup_field: kwargs.pop(self.lookup_url_kwarg)}
        if hasattr(self.product_model, 'translations'):
            filter_kwargs.update(translations__language_code=get_language_from_request(self.request))
        queryset = self.product_model.objects.filter(self.limit_choices_to, **filter_kwargs)
        product = get_object_or_404(queryset)
        return {'product': product, 'request': request}

    def get(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(context=context, **kwargs)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs):
        context = self.get_context(request, **kwargs)
        serializer = self.serializer_class(data=request.data, context=context)
        if serializer.is_valid():
            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ProductRetrieveView(generics.RetrieveAPIView):
    """
    This view is used to retrieve and render a certain product.

    Usage: Add it to the urlpatterns responsible for rendering the catalog's views. The
    file containing this patterns can be referenced by the CMS apphook ``ProductsListApp``
    and used by the CMS pages responsible for rendering the catalog's list.
    ```
    urlpatterns = [
        url(r'^$', ProductListView.as_view()),  # see above
        url(r'^(?P<slug>[\w-]+)/?$', ProductRetrieveView.as_view()),
        ...
    ]
    ```
    You may add these attributes to the ``as_view()`` method:

    :param renderer_classes: A list or tuple of REST renderer classes.

    :param lookup_field: The model field used to retrieve the product instance.

    :param lookup_url_kwarg: The name of the parsed URL fragment.

    :param serializer_class: The serializer class used to process the queryset returned
        by the catalog's product detail view.

    :param limit_choices_to: Limit the queryset of product models to these choices.
    """

    renderer_classes = (CMSPageRenderer, JSONRenderer, BrowsableAPIRenderer)
    lookup_field = lookup_url_kwarg = 'slug'
    product_model = ProductModel
    serializer_class = ProductSerializer
    limit_choices_to = models.Q()

    def get_template_names(self):
        product = self.get_object()
        app_label = product._meta.app_label.lower()
        basename = '{}-detail.html'.format(product.__class__.__name__.lower())
        return [
            os.path.join(app_label, 'catalog', basename),
            os.path.join(app_label, 'catalog/product-detail.html'),
            'shop/catalog/product-detail.html',
        ]

    def get_renderer_context(self):
        renderer_context = super(ProductRetrieveView, self).get_renderer_context()
        if renderer_context['request'].accepted_renderer.format == 'html':
            # add the product as Python object to the context
            renderer_context['product'] = self.get_object()
        return renderer_context

    def get_object(self):
        if not hasattr(self, '_product'):
            assert self.lookup_url_kwarg in self.kwargs
            filter_kwargs = {self.lookup_field: self.kwargs[self.lookup_url_kwarg]}
            if hasattr(self.product_model, 'translations'):
                filter_kwargs.update(translations__language_code=get_language_from_request(self.request))
            queryset = self.product_model.objects.filter(self.limit_choices_to, **filter_kwargs)
            self._product = get_object_or_404(queryset)
        return self._product

class ProductSelectView(generics.ListAPIView):
    """
    A simple list view, which is used only by the admin backend. It is required to fetch
    the data for rendering the select widget when looking up for a product.
    """
    renderer_classes = (JSONRenderer, BrowsableAPIRenderer)
    serializer_class = app_settings.PRODUCT_SELECT_SERIALIZER

    def get_queryset(self):
        term = self.request.GET.get('term', '')
        if len(term) >= 2:
            return ProductModel.objects.select_lookup(term)[:10]
        return ProductModel.objects.all()[:10]

class AddFilterContextMixin(object):
    """
    A mixin to enrich the render context by ``filter`` containing information
    on how to render the filter set, supplied by attribute ``filter_class``.
    """
    def get_renderer_context(self):
        renderer_context = super(AddFilterContextMixin, self).get_renderer_context()
        if self.filter_class and renderer_context['request'].accepted_renderer.format == 'html':
            # restrict filter set to products associated to this CMS page only
            queryset = self.product_model.objects.filter(self.limit_choices_to)
            queryset = CMSPagesFilterBackend().filter_queryset(self.request, queryset, self)
            renderer_context['filter'] = self.filter_class.get_render_context(self.request, queryset)
        return renderer_context
<|endoftext|>