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

""" Unit tests for the shortcodes module. """

import unittest
import shortcodes

@shortcodes.register('foo')
def foo_handler(context, content, pargs, kwargs):
    return 'bar'

@shortcodes.register('wrap', 'endwrap')
def wrap_handler(context, content, pargs, kwargs):
    return '<%s>%s</%s>' % (pargs[0], content, pargs[0])

@shortcodes.register('args')
def args_handler(context, content, pargs, kwargs):
    for key, value in sorted(kwargs.items()):
        pargs.append(key + ':' + value)
    return '|'.join(pargs)

@shortcodes.register('context')
def context_handler(context, content, pargs, kwargs):
    return str(context)

class InsertionTests(unittest.TestCase):

    def test_empty_string(self):
        text = ''
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '')

    def test_string_without_shortcodes(self):
        text = 'foo'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'foo')

    def test_simple_insertion(self):
        text = '[% foo %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'bar')

    def test_simple_insertion_with_text(self):
        text = '..[% foo %]..'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '..bar..')

class EscapingTests(unittest.TestCase):

    def test_escaped_shortcode(self):
        text = r'\[% foo %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '[% foo %]')

    def test_double_escaped_shortcode(self):
        text = r'\\[% foo %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, r'\[% foo %]')

class ArgumentTests(unittest.TestCase):

    def test_args_with_double_quoted_strings(self):
        text = '[% args arg1 "arg 2" key1=arg3 key2="arg 4" %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'arg1|arg 2|key1:arg3|key2:arg 4')

    def test_args_with_single_quoted_strings(self):
        text = "[% args arg1 'arg 2' key1=arg3 key2='arg 4' %]"
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'arg1|arg 2|key1:arg3|key2:arg 4')

class NestingTests(unittest.TestCase):

    def test_wrapping_simple_text(self):
        text = '[% wrap div %]foo[% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '
foo
')

    def test_wrapping_shortcode(self):
        text = '[% wrap div %][% foo %][% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '
bar
')

    def test_wrapping_wrapping_shortcode(self):
        text = '[% wrap div %][% wrap p %][% foo %][% endwrap %][% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '

bar

')

    def test_wrapping_and_text_mix(self):
        text = '[% wrap div %]..[% wrap p %].[% foo %].[% endwrap %]..[% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '
..
.bar.
..
')

class ContextTests(unittest.TestCase):

    def test_context_object(self):
        text = '[% context %]'
        rendered = shortcodes.Parser().parse(text, 101)
        self.assertEqual(rendered, '101')

if __name__ == '__main__':
    unittest.main()
<commit_msg>Add unit tests for per-parser handler registration<commit_after>#!/usr/bin/env python3

""" Unit tests for the shortcodes module. """

import unittest
import shortcodes

@shortcodes.register('foo')
def foo_handler(context, content, pargs, kwargs):
    return 'bar'

@shortcodes.register('wrap', 'endwrap')
def wrap_handler(context, content, pargs, kwargs):
    return '<%s>%s</%s>' % (pargs[0], content, pargs[0])

@shortcodes.register('args')
def args_handler(context, content, pargs, kwargs):
    for key, value in sorted(kwargs.items()):
        pargs.append(key + ':' + value)
    return '|'.join(pargs)

@shortcodes.register('context')
def context_handler(context, content, pargs, kwargs):
    return str(context)

class InsertionTests(unittest.TestCase):

    def test_empty_string(self):
        text = ''
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '')

    def test_string_without_shortcodes(self):
        text = 'foo'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'foo')

    def test_simple_insertion(self):
        text = '[% foo %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'bar')

    def test_simple_insertion_with_text(self):
        text = '..[% foo %]..'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '..bar..')

class EscapingTests(unittest.TestCase):

    def test_escaped_shortcode(self):
        text = r'\[% foo %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '[% foo %]')

    def test_double_escaped_shortcode(self):
        text = r'\\[% foo %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, r'\[% foo %]')

class ArgumentTests(unittest.TestCase):

    def test_args_with_double_quoted_strings(self):
        text = '[% args arg1 "arg 2" key1=arg3 key2="arg 4" %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'arg1|arg 2|key1:arg3|key2:arg 4')

    def test_args_with_single_quoted_strings(self):
        text = "[% args arg1 'arg 2' key1=arg3 key2='arg 4' %]"
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, 'arg1|arg 2|key1:arg3|key2:arg 4')

class NestingTests(unittest.TestCase):

    def test_wrapping_simple_text(self):
        text = '[% wrap div %]foo[% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '
foo
')

    def test_wrapping_shortcode(self):
        text = '[% wrap div %][% foo %][% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '
bar
')

    def test_wrapping_wrapping_shortcode(self):
        text = '[% wrap div %][% wrap p %][% foo %][% endwrap %][% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '

bar

')

    def test_wrapping_and_text_mix(self):
        text = '[% wrap div %]..[% wrap p %].[% foo %].[% endwrap %]..[% endwrap %]'
        rendered = shortcodes.Parser().parse(text)
        self.assertEqual(rendered, '
..
.bar.
..
')

class ContextTests(unittest.TestCase):

    def test_context_object(self):
        text = '[% context %]'
        rendered = shortcodes.Parser().parse(text, 101)
        self.assertEqual(rendered, '101')

class LocalRegistrationTests(unittest.TestCase):

    def test_locally_registered_handler(self):
        text = '[% local %]'
        parser = shortcodes.Parser()
        parser.register(foo_handler, 'local')
        rendered = parser.parse(text)
        self.assertEqual(rendered, 'bar')

    def test_locally_registered_wrap(self):
        text = '[% localwrap div %]foo[% endlocalwrap %]'
        parser = shortcodes.Parser()
        parser.register(wrap_handler, 'localwrap', 'endlocalwrap')
        rendered = parser.parse(text)
        self.assertEqual(rendered, '
foo
')

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2015-2018 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.
import logging

from openquake.baselib import parallel
from openquake.hazardlib.calc.hazard_curve import classical
from openquake.commonlib import source

from openquake.calculators import base
from openquake.calculators.classical import ClassicalCalculator, PSHACalculator
from openquake.calculators.ucerf_base import UcerfFilter
# FIXME: the counting of effective ruptures has to be revised

@base.calculators.add('ucerf_psha')
class UcerfPSHACalculator(PSHACalculator):
    """
    UCERF classical calculator.
    """
    def pre_execute(self):
        super().pre_execute()
        self.src_filter = UcerfFilter(
            self.sitecol, self.oqparam.maximum_distance)
        for sm in self.csm.source_models:  # one branch at the time
            [grp] = sm.src_groups
            ucerf = grp.sources[0].orig
            logging.info('Getting background sources from %s', ucerf.source_id)
            bgsources = ucerf.get_background_sources(self.src_filter)
            grp.sources.extend(bgsources)
            for src in grp:
                self.csm.infos[src.source_id] = source.SourceInfo(src)
                grp.tot_ruptures += src.num_ruptures

    def execute(self):
        """
        Run in parallel `core_task(sources, sitecol, monitor)`, by
        parallelizing on the sources according to their weight and
        tectonic region type.
        """
        monitor = self.monitor(self.core_task.__name__)
        oq = self.oqparam
        acc = self.zerodict()
        self.nsites = []  # used in agg_dicts
        param = dict(imtls=oq.imtls, truncation_level=oq.truncation_level,
                     filter_distance=oq.filter_distance)
        self.csm.split_all()
        for sm in self.csm.source_models:  # one branch at the time
            [grp] = sm.src_groups
            gsims = self.csm.info.get_gsims(sm.ordinal)
            acc = parallel.Starmap.apply(
                classical, (grp, self.src_filter, gsims, param, monitor),
                name='classical_%d' % sm.ordinal,
                concurrent_tasks=oq.concurrent_tasks,
            ).reduce(self.agg_dicts, acc)

        with self.monitor('store source_info', autoflush=True):
            self.store_source_info(self.csm.infos, acc)
        return acc  # {grp_id: pmap}

@base.calculators.add('ucerf_classical')
class UCERFClassicalCalculator(ClassicalCalculator):
    pre_calculator = 'ucerf_psha'
<commit_msg>Removed duplication<commit_after># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2015-2018 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.
import logging

from openquake.baselib import parallel
from openquake.hazardlib.calc.hazard_curve import classical
from openquake.commonlib import source

from openquake.calculators import base
from openquake.calculators.classical import ClassicalCalculator, PSHACalculator
from openquake.calculators.ucerf_base import UcerfFilter
# FIXME: the counting of effective ruptures has to be revised

@base.calculators.add('ucerf_psha')
class UcerfPSHACalculator(PSHACalculator):
    """
    UCERF classical calculator.
    """
    def pre_execute(self):
        super().pre_execute()
        self.src_filter = UcerfFilter(
            self.sitecol, self.oqparam.maximum_distance)
        for sm in self.csm.source_models:  # one branch at the time
            [grp] = sm.src_groups
            ucerf = grp.sources[0].orig
            logging.info('Getting background sources from %s', ucerf.source_id)
            bgsources = ucerf.get_background_sources(self.src_filter)
            grp.sources.extend(bgsources)
            for src in grp:
                self.csm.infos[src.source_id] = source.SourceInfo(src)
                grp.tot_ruptures += src.num_ruptures

    def execute(self):
        """
        Run in parallel `core_task(sources, sitecol, monitor)`, by
        parallelizing on the sources according to their weight and
        tectonic region type.
        """
        monitor = self.monitor(self.core_task.__name__)
        oq = self.oqparam
        acc = self.zerodict()
        self.nsites = []  # used in agg_dicts
        param = dict(imtls=oq.imtls, truncation_level=oq.truncation_level,
                     filter_distance=oq.filter_distance)
        for sm in self.csm.source_models:  # one branch at the time
            [grp] = sm.src_groups
            gsims = self.csm.info.get_gsims(sm.ordinal)
            acc = parallel.Starmap.apply(
                classical, (grp, self.src_filter, gsims, param, monitor),
                name='classical_%d' % sm.ordinal,
                concurrent_tasks=oq.concurrent_tasks,
            ).reduce(self.agg_dicts, acc)

        with self.monitor('store source_info', autoflush=True):
            self.store_source_info(self.csm.infos, acc)
        return acc  # {grp_id: pmap}

@base.calculators.add('ucerf_classical')
class UCERFClassicalCalculator(ClassicalCalculator):
    pre_calculator = 'ucerf_psha'
<|endoftext|>


<commit_before>#! /usr/bin/python
# -*- coding: utf8 -*-

import tensorflow as tf
import tensorlayer as tl
slim = tf.contrib.slim
from tensorflow.contrib.slim.python.slim.nets.alexnet import alexnet_v2
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_base, inception_v3, inception_v3_arg_scope
# from tensorflow.contrib.slim.python.slim.nets.resnet_v2 import resnet_v2_152
# from tensorflow.contrib.slim.python.slim.nets.vgg import vgg_16
import skimage
import skimage.io
import skimage.transform
import time, os
try:
    from data.imagenet_classes import *
except Exception as e:
    raise Exception("{} / download the file from: https://github.com/zsdonghao/tensorlayer/tree/master/example/data".format(e))
import numpy as np
"""
You will learn:
1. What is TF-Slim ?
1. How to combine TensorLayer and TF-Slim ?

Introduction of Slim    : https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim
Slim Pre-trained Models : https://github.com/tensorflow/models/tree/master/slim

With the help of SlimNetsLayer, all Slim Model can be combined into TensorLayer.
All models in the following link, end with `return net, end_points`` are available.
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim/python/slim/nets

Bugs
-----
tf.variable_scope :
        https://groups.google.com/a/tensorflow.org/forum/#!topic/discuss/RoxrU3UnbFA
load inception_v3 for prediction:
        http://stackoverflow.com/questions/39357454/restore-checkpoint-in-tensorflow-tensor-name-not-found
"""
def load_image(path):
    # load image
    img = skimage.io.imread(path)
    img = img / 255.0
    assert (0 <= img).all() and (img <= 1.0).all()
    # print "Original Image Shape: ", img.shape
    # we crop image from center
    short_edge = min(img.shape[:2])
    yy = int((img.shape[0] - short_edge) / 2)
    xx = int((img.shape[1] - short_edge) / 2)
    crop_img = img[yy: yy + short_edge, xx: xx + short_edge]
    # resize to 299, 299
    resized_img = skimage.transform.resize(crop_img, (299, 299))
    return resized_img

def print_prob(prob):
    synset = class_names
    # print prob
    pred = np.argsort(prob)[::-1]
    # Get top1 label
    top1 = synset[pred[0]]
    print("Top1: ", top1, prob[pred[0]])
    # Get top5 label
    top5 = [(synset[pred[i]], prob[pred[i]]) for i in range(5)]
    print("Top5: ", top5)
    return top1

## Alexnet_v2 / All TF-Slim nets can be merged into TensorLayer
# x = tf.placeholder(tf.float32, shape=[None, 299, 299, 3])
# net_in = tl.layers.InputLayer(x, name='input_layer')
# network = tl.layers.SlimNetsLayer(layer=net_in, slim_layer=alexnet_v2,
#                                 slim_args= {
#                                        'num_classes' : 1000,
#                                        'is_training' : True,
#                                        'dropout_keep_prob' : 0.5,
#                                        'spatial_squeeze' : True,
#                                        'scope' : 'alexnet_v2'
#                                         },
#                                     name='alexnet_v2'  # <-- the name should be the same with the ckpt model
#                                     )
# sess = tf.InteractiveSession()
# # sess.run(tf.initialize_all_variables())
# tl.layers.initialize_global_variables(sess)
# network.print_params()

## InceptionV3 / All TF-Slim nets can be merged into TensorLayer
x = tf.placeholder(tf.float32, shape=[None, 299, 299, 3])
net_in = tl.layers.InputLayer(x, name='input_layer')
with slim.arg_scope(inception_v3_arg_scope()):
    ## Alternatively, you should implement inception_v3 without TensorLayer as follow.
    # logits, end_points = inception_v3(X, num_classes=1001,
    #                                   is_training=False)
    network = tl.layers.SlimNetsLayer(layer=net_in, slim_layer=inception_v3,
                                    slim_args= {
                                             'num_classes' : 1001,
                                             'is_training' : False,
                                            #  'dropout_keep_prob' : 0.8,       # for training
                                            #  'min_depth' : 16,
                                            #  'depth_multiplier' : 1.0,
                                            #  'prediction_fn' : slim.softmax,
                                            #  'spatial_squeeze' : True,
                                            #  'reuse' : None,
                                            #  'scope' : 'InceptionV3'
                                            },
                                        name='InceptionV3'  # <-- the name should be the same with the ckpt model
                                        )

sess = tf.InteractiveSession()

network.print_params(False)

saver = tf.train.Saver()
if not os.path.isfile("inception_v3.ckpt"):
    print("Please download inception_v3 ckpt from : https://github.com/tensorflow/models/tree/master/slim#Install")
    exit()
try:    # TF12+
    saver.restore(sess, "./inception_v3.ckpt")
except: # TF11
    saver.restore(sess, "inception_v3.ckpt")
print("Model Restored")

from scipy.misc import imread, imresize
y = network.outputs
probs = tf.nn.softmax(y)
img1 = load_image("data/puzzle.jpeg") # test data in github: https://github.com/zsdonghao/tensorlayer/tree/master/example/data
img1 = img1.reshape((1, 299, 299, 3))

start_time = time.time()
prob = sess.run(probs, feed_dict= {x : img1})
print("End time : %.5ss" % (time.time() - start_time))
print_prob(prob[0][1:]) # Note : as it have 1001 outputs, the 1st output is nothing

## You can save the model into npz file
# tl.files.save_npz(network.all_params, name='model_inceptionV3.npz')

#
<commit_msg>update link<commit_after>#! /usr/bin/python
# -*- coding: utf8 -*-

import tensorflow as tf
import tensorlayer as tl
slim = tf.contrib.slim
from tensorflow.contrib.slim.python.slim.nets.alexnet import alexnet_v2
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_base, inception_v3, inception_v3_arg_scope
# from tensorflow.contrib.slim.python.slim.nets.resnet_v2 import resnet_v2_152
# from tensorflow.contrib.slim.python.slim.nets.vgg import vgg_16
import skimage
import skimage.io
import skimage.transform
import time, os
try:
    from data.imagenet_classes import *
except Exception as e:
    raise Exception("{} / download the file from: https://github.com/zsdonghao/tensorlayer/tree/master/example/data".format(e))
import numpy as np
"""
You will learn:
1. What is TF-Slim ?
1. How to combine TensorLayer and TF-Slim ?

Introduction of Slim    : https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim
Slim Pre-trained Models : https://github.com/tensorflow/models/tree/master/slim

With the help of SlimNetsLayer, all Slim Model can be combined into TensorLayer.
All models in the following link, end with `return net, end_points`` are available.
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim/python/slim/nets

Bugs
-----
tf.variable_scope :
        https://groups.google.com/a/tensorflow.org/forum/#!topic/discuss/RoxrU3UnbFA
load inception_v3 for prediction:
        http://stackoverflow.com/questions/39357454/restore-checkpoint-in-tensorflow-tensor-name-not-found
"""
def load_image(path):
    # load image
    img = skimage.io.imread(path)
    img = img / 255.0
    assert (0 <= img).all() and (img <= 1.0).all()
    # print "Original Image Shape: ", img.shape
    # we crop image from center
    short_edge = min(img.shape[:2])
    yy = int((img.shape[0] - short_edge) / 2)
    xx = int((img.shape[1] - short_edge) / 2)
    crop_img = img[yy: yy + short_edge, xx: xx + short_edge]
    # resize to 299, 299
    resized_img = skimage.transform.resize(crop_img, (299, 299))
    return resized_img

def print_prob(prob):
    synset = class_names
    # print prob
    pred = np.argsort(prob)[::-1]
    # Get top1 label
    top1 = synset[pred[0]]
    print("Top1: ", top1, prob[pred[0]])
    # Get top5 label
    top5 = [(synset[pred[i]], prob[pred[i]]) for i in range(5)]
    print("Top5: ", top5)
    return top1

## Alexnet_v2 / All TF-Slim nets can be merged into TensorLayer
# x = tf.placeholder(tf.float32, shape=[None, 299, 299, 3])
# net_in = tl.layers.InputLayer(x, name='input_layer')
# network = tl.layers.SlimNetsLayer(layer=net_in, slim_layer=alexnet_v2,
#                                 slim_args= {
#                                        'num_classes' : 1000,
#                                        'is_training' : True,
#                                        'dropout_keep_prob' : 0.5,
#                                        'spatial_squeeze' : True,
#                                        'scope' : 'alexnet_v2'
#                                         },
#                                     name='alexnet_v2'  # <-- the name should be the same with the ckpt model
#                                     )
# sess = tf.InteractiveSession()
# # sess.run(tf.initialize_all_variables())
# tl.layers.initialize_global_variables(sess)
# network.print_params()

## InceptionV3 / All TF-Slim nets can be merged into TensorLayer
x = tf.placeholder(tf.float32, shape=[None, 299, 299, 3])
net_in = tl.layers.InputLayer(x, name='input_layer')
with slim.arg_scope(inception_v3_arg_scope()):
    ## Alternatively, you should implement inception_v3 without TensorLayer as follow.
    # logits, end_points = inception_v3(X, num_classes=1001,
    #                                   is_training=False)
    network = tl.layers.SlimNetsLayer(layer=net_in, slim_layer=inception_v3,
                                    slim_args= {
                                             'num_classes' : 1001,
                                             'is_training' : False,
                                            #  'dropout_keep_prob' : 0.8,       # for training
                                            #  'min_depth' : 16,
                                            #  'depth_multiplier' : 1.0,
                                            #  'prediction_fn' : slim.softmax,
                                            #  'spatial_squeeze' : True,
                                            #  'reuse' : None,
                                            #  'scope' : 'InceptionV3'
                                            },
                                        name='InceptionV3'  # <-- the name should be the same with the ckpt model
                                        )

sess = tf.InteractiveSession()

network.print_params(False)

saver = tf.train.Saver()
if not os.path.isfile("inception_v3.ckpt"):
    print("Please download inception_v3 ckpt from : https://github.com/tensorflow/models/tree/master/slim#Pretrained")
    exit()
try:    # TF12+
    saver.restore(sess, "./inception_v3.ckpt")
except: # TF11
    saver.restore(sess, "inception_v3.ckpt")
print("Model Restored")

from scipy.misc import imread, imresize
y = network.outputs
probs = tf.nn.softmax(y)
img1 = load_image("data/puzzle.jpeg") # test data in github: https://github.com/zsdonghao/tensorlayer/tree/master/example/data
img1 = img1.reshape((1, 299, 299, 3))

start_time = time.time()
prob = sess.run(probs, feed_dict= {x : img1})
print("End time : %.5ss" % (time.time() - start_time))
print_prob(prob[0][1:]) # Note : as it have 1001 outputs, the 1st output is nothing

## You can save the model into npz file
# tl.files.save_npz(network.all_params, name='model_inceptionV3.npz')

#
<|endoftext|>


<commit_before><commit_msg>se corrigio funcion _build<commit_after><|endoftext|>


<commit_before>import unittest
import os
import random
import string

import plivo

random_letter = lambda: random.choice(string.ascii_letters)
random_name = lambda: ''.join(random_letter() for i in range(8))

try:
    from auth_secrets import AUTH_ID, AUTH_TOKEN
except ImportError:
    AUTH_ID, AUTH_TOKEN = os.getenv("AUTH_ID"), os.getenv("AUTH_TOKEN")
    if not (AUTH_ID and AUTH_TOKEN):
        raise Exception("Create a auth_secrets.py file or set AUTH_ID "
                        "and AUTH_TOKEN as environ values.")

class PlivoTestCase(unittest.TestCase):
    def setUp(self):
        auth_id, auth_token = AUTH_ID, AUTH_TOKEN
        self.client = plivo.RestAPI(auth_id, auth_token)

class TestAccounts(PlivoTestCase):
    def test_get_account(self):
        response = self.client.get_account()
        self.assertEqual(200, response[0])
        valid_keys = ["account_type", "address", "auth_id", "auto_recharge",
                      "cash_credits", "city", "created", "enabled"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_get_subaccounts(self):
        response = self.client.get_subaccounts()
        self.assertEqual(200, response[0])
        valid_keys = ["meta", "api_id", "objects"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_subaccount_crud(self):

        response = self.client.create_subaccount(dict(name=random_name(),
                                                 enabled=True))
        self.assertEqual(201, response[0])
        valid_keys = ["auth_id", "api_id", "auth_token"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)
        auth_id = json_response["auth_id"]
        response = self.client.get_subaccount(dict(subauth_id=auth_id))
        self.assertEqual(200, response[0])
        response = self.client.delete_subaccount(dict(subauth_id=auth_id))
        self.assertEqual(204, response[0])

class TestApplication(PlivoTestCase):
    def test_get_applications(self):
        response = self.client.get_applications()
        self.assertEqual(200, response[0])
        valid_keys = ["objects", "api_id", "meta"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_application_crud(self):
        name = random_name()
        params = dict(answer_url="http://plivo.com/",
                      app_name=name)
        response = self.client.create_application(params)
        self.assertEqual(201, response[0])
        app_id = response[1]['app_id']
        response = self.client.get_application({"app_id": app_id})
        self.assertEqual(200, response[0])
        self.assertEqual(name, response[1]["app_name"])
        response = self.client.delete_application(dict(app_id=app_id))
        self.assertEqual(204, response[0])

class TestNumbers(PlivoTestCase):
    def test_get_numbers(self):
        response = self.client.get_numbers()
        self.assertEqual(200, response[0])
        valid_keys = ["meta", "api_id", "objects"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

if __name__ == "__main__":
    unittest.main()
<commit_msg>Added test for search_number.<commit_after>import unittest
import os
import random
import string

import plivo

random_letter = lambda: random.choice(string.ascii_letters)
random_name = lambda: ''.join(random_letter() for i in range(8))

try:
    from auth_secrets import AUTH_ID, AUTH_TOKEN
except ImportError:
    AUTH_ID, AUTH_TOKEN = os.getenv("AUTH_ID"), os.getenv("AUTH_TOKEN")
    if not (AUTH_ID and AUTH_TOKEN):
        raise Exception("Create a auth_secrets.py file or set AUTH_ID "
                        "and AUTH_TOKEN as environ values.")

class PlivoTestCase(unittest.TestCase):
    def setUp(self):
        auth_id, auth_token = AUTH_ID, AUTH_TOKEN
        self.client = plivo.RestAPI(auth_id, auth_token)

class TestAccounts(PlivoTestCase):
    def test_get_account(self):
        response = self.client.get_account()
        self.assertEqual(200, response[0])
        valid_keys = ["account_type", "address", "auth_id", "auto_recharge",
                      "cash_credits", "city", "created", "enabled"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_get_subaccounts(self):
        response = self.client.get_subaccounts()
        self.assertEqual(200, response[0])
        valid_keys = ["meta", "api_id", "objects"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_subaccount_crud(self):

        response = self.client.create_subaccount(dict(name=random_name(),
                                                 enabled=True))
        self.assertEqual(201, response[0])
        valid_keys = ["auth_id", "api_id", "auth_token"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)
        auth_id = json_response["auth_id"]
        response = self.client.get_subaccount(dict(subauth_id=auth_id))
        self.assertEqual(200, response[0])
        response = self.client.delete_subaccount(dict(subauth_id=auth_id))
        self.assertEqual(204, response[0])

class TestApplication(PlivoTestCase):
    def test_get_applications(self):
        response = self.client.get_applications()
        self.assertEqual(200, response[0])
        valid_keys = ["objects", "api_id", "meta"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_application_crud(self):
        name = random_name()
        params = dict(answer_url="http://plivo.com/",
                      app_name=name)
        response = self.client.create_application(params)
        self.assertEqual(201, response[0])
        app_id = response[1]['app_id']
        response = self.client.get_application({"app_id": app_id})
        self.assertEqual(200, response[0])
        self.assertEqual(name, response[1]["app_name"])
        response = self.client.delete_application(dict(app_id=app_id))
        self.assertEqual(204, response[0])

class TestNumbers(PlivoTestCase):
    def test_get_numbers(self):
        response = self.client.get_numbers()
        self.assertEqual(200, response[0])
        valid_keys = ["meta", "api_id", "objects"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

    def test_search_numbers(self):
        response = self.client.search_numbers(dict(country_code="004"))
        self.assertEqual(200, response[0])
        valid_keys = ["meta", "api_id", "objects"]
        json_response = response[1]
        for key in valid_keys:
            self.assertTrue(key in json_response)

if __name__ == "__main__":
    unittest.main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2012-2022 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

""":mod:`openquake.hazardlib.calc.hazard_curve` implements
:func:`calc_hazard_curves`. Here is an example of a classical PSHA
parallel calculator computing the hazard curves per each realization in less
than 20 lines of code:

.. code-block:: python

   import sys
   from openquake.commonlib import logs
   from openquake.calculators.base import calculators

   def main(job_ini):
       with logs.init('job', job_ini) as log:
           calc = calculators(log.get_oqparam(), log.calc_id)
           calc.run(individual_rlzs='true', shutdown=True)
           print('The hazard curves are in %s::/hcurves-rlzs'
                % calc.datastore.filename)

   if __name__ == '__main__':
       main(sys.argv[1])  # path to a job.ini file

NB: the implementation in the engine is smarter and more
efficient. Here we start a parallel computation per each realization,
the engine manages all the realizations at once.
"""

import operator
import numpy
from openquake.baselib.performance import Monitor
from openquake.baselib.parallel import sequential_apply
from openquake.baselib.general import DictArray, groupby
from openquake.hazardlib.probability_map import ProbabilityMap, ProbabilityCurve
from openquake.hazardlib.gsim.base import ContextMaker, PmapMaker
from openquake.hazardlib.calc.filters import SourceFilter
from openquake.hazardlib.sourceconverter import SourceGroup
from openquake.hazardlib.tom import PoissonTOM, FatedTOM

def _cluster(sids, imtls, tom, gsims, pmap):
    """
    Computes the probability map in case of a cluster group
    """
    for nocc in range(0, 50):
        ocr = tom.occurrence_rate
        prob_n_occ = tom.get_probability_n_occurrences(ocr, nocc)
        if nocc == 0:
            pmapclu = pmap.new(numpy.full(pmap.shape, prob_n_occ))
        else:
            pmapclu.array += (1.-pmap.array)**nocc * prob_n_occ
    return ~pmapclu

def classical(group, sitecol, cmaker, pmap=None):
    """
    Compute the hazard curves for a set of sources belonging to the same
    tectonic region type for all the GSIMs associated to that TRT.
    The arguments are the same as in :func:`calc_hazard_curves`, except
    for ``gsims``, which is a list of GSIM instances.

    :returns:
        a dictionary with keys pmap, source_data, rup_data, extra
    """
    not_passed_pmap = pmap is None
    src_filter = SourceFilter(sitecol, cmaker.maximum_distance)
    cluster = getattr(group, 'cluster', None)
    rup_indep = getattr(group, 'rup_interdep', None) != 'mutex'
    trts = set()
    for src in group:
        if not src.num_ruptures:
            # src.num_ruptures may not be set, so it is set here
            src.num_ruptures = src.count_ruptures()
        # set the proper TOM in case of a cluster
        if cluster:
            src.temporal_occurrence_model = FatedTOM(time_span=1)
        trts.add(src.tectonic_region_type)
    [trt] = trts  # there must be a single tectonic region type
    if cmaker.trt != '*':
        assert trt == cmaker.trt, (trt, cmaker.trt)
    try:
        cmaker.tom = group.temporal_occurrence_model
    except AttributeError:  # got a list of sources, not a group
        time_span = cmaker.investigation_time  # None for nonparametric
        cmaker.tom = PoissonTOM(time_span) if time_span else None
    if cluster:
        cmaker.tom = FatedTOM(time_span=1)
    if not_passed_pmap:
        pmap = ProbabilityMap(
            sitecol.sids, cmaker.imtls.size, len(cmaker.gsims))
        pmap.fill(rup_indep)

    dic = PmapMaker(cmaker, src_filter, group).make(pmap)
    if getattr(group, 'src_interdep', None) != 'mutex' and rup_indep:
        pmap.array[:] = 1. - pmap.array
    if cluster:
        tom = getattr(group, 'temporal_occurrence_model')
        pmap.array[:] = _cluster(sitecol.sids, cmaker.imtls, tom, cmaker.gsims,
                                 pmap).array
    return dic

# not used in the engine, only in tests and possibly notebooks
def calc_hazard_curves(
        groups, srcfilter, imtls, gsim_by_trt, truncation_level=99.,
        apply=sequential_apply, reqv=None, **kwargs):
    """
    Compute hazard curves on a list of sites, given a set of seismic source
    groups and a dictionary of ground shaking intensity models (one per
    tectonic region type).

    Probability of ground motion exceedance is computed in different ways
    depending if the sources are independent or mutually exclusive.

    :param groups:
        A sequence of groups of seismic sources objects (instances of
        of :class:`~openquake.hazardlib.source.base.BaseSeismicSource`).
    :param srcfilter:
        A source filter over the site collection or the site collection itself
    :param imtls:
        Dictionary mapping intensity measure type strings
        to lists of intensity measure levels.
    :param gsim_by_trt:
        Dictionary mapping tectonic region types (members
        of :class:`openquake.hazardlib.const.TRT`) to
        :class:`~openquake.hazardlib.gsim.base.GMPE` or
        :class:`~openquake.hazardlib.gsim.base.IPE` objects.
    :param truncation_level:
        Float, number of standard deviations for truncation of the intensity
        distribution.
    :param apply:
        apply function to use (default sequential_apply)
    :param reqv:
        If not None, an instance of RjbEquivalent
    :returns:
        An array of size N, where N is the number of sites, which elements
        are records with fields given by the intensity measure types; the
        size of each field is given by the number of levels in ``imtls``.
    """
    # This is ensuring backward compatibility i.e. processing a list of
    # sources
    if not isinstance(groups[0], SourceGroup):  # sent a list of sources
        odic = groupby(groups, operator.attrgetter('tectonic_region_type'))
        groups = [SourceGroup(trt, odic[trt], 'src_group', 'indep', 'indep')
                  for trt in odic]
    idx = 0
    span = None
    for i, grp in enumerate(groups):
        for src in grp:
            tom = getattr(src, 'temporal_occurrence_model', None)
            if tom:
                span = tom.time_span
            src.weight = src.count_ruptures()
            src.grp_id = i
            src.id = idx
            idx += 1
    imtls = DictArray(imtls)
    shift_hypo = kwargs['shift_hypo'] if 'shift_hypo' in kwargs else False
    param = dict(imtls=imtls, truncation_level=truncation_level, reqv=reqv,
                 cluster=grp.cluster, shift_hypo=shift_hypo,
                 investigation_time=kwargs.get('investigation_time', span))
    # Processing groups with homogeneous tectonic region
    mon = Monitor()
    sitecol = getattr(srcfilter, 'sitecol', srcfilter)
    pmap = ProbabilityMap(sitecol.sids, imtls.size, 1).fill(0)
    for group in groups:
        trt = group.trt
        if sitecol is not srcfilter:
            param['maximum_distance'] = srcfilter.integration_distance(trt)
        cmaker = ContextMaker(trt, [gsim_by_trt[trt]], param, mon)
        if group.atomic:  # do not split
            it = [classical(group, sitecol, cmaker)]
        else:  # split the group and apply `classical` in parallel
            it = apply(
                classical, (group.sources, sitecol, cmaker),
                weight=operator.attrgetter('weight'))
        for dic in it:
            pmap.array[:] = 1. - (1.-pmap.array) * (1. - dic['pmap'].array)
    return pmap.convert(imtls, len(sitecol.complete))

# called in adv-manual/developing.rst and in SingleSiteOptTestCase
def calc_hazard_curve(site1, src, gsims, oqparam, monitor=Monitor()):
    """
    :param site1: site collection with a single site
    :param src: a seismic source object
    :param gsims: a list of GSIM objects
    :param oqparam: an object with attributes .maximum_distance, .imtls
    :param monitor: a Monitor instance (optional)
    :returns: a ProbabilityCurve object
    """
    assert len(site1) == 1, site1
    trt = src.tectonic_region_type
    cmaker = ContextMaker(trt, gsims, vars(oqparam), monitor)
    cmaker.tom = src.temporal_occurrence_model
    srcfilter = SourceFilter(site1, oqparam.maximum_distance)
    pmap = ProbabilityMap(site1.sids, oqparam.imtls.size, 1).fill(1)
    PmapMaker(cmaker, srcfilter, [src]).make(pmap)
    pmap.array[:] = 1. - pmap.array
    if not pmap:  # filtered away
        zero = numpy.zeros((oqparam.imtls.size, len(gsims)))
        return ProbabilityCurve(zero)
    return ProbabilityCurve(pmap.array[0])
<commit_msg>Indentation<commit_after># -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2012-2022 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

""":mod:`openquake.hazardlib.calc.hazard_curve` implements
:func:`calc_hazard_curves`. Here is an example of a classical PSHA
parallel calculator computing the hazard curves per each realization in less
than 20 lines of code:

.. code-block:: python

   import sys
   from openquake.commonlib import logs
   from openquake.calculators.base import calculators

   def main(job_ini):
       with logs.init('job', job_ini) as log:
           calc = calculators(log.get_oqparam(), log.calc_id)
           calc.run(individual_rlzs='true', shutdown=True)
           print('The hazard curves are in %s::/hcurves-rlzs'
                % calc.datastore.filename)

   if __name__ == '__main__':
       main(sys.argv[1])  # path to a job.ini file

NB: the implementation in the engine is smarter and more
efficient. Here we start a parallel computation per each realization,
the engine manages all the realizations at once.
"""

import operator
import numpy
from openquake.baselib.performance import Monitor
from openquake.baselib.parallel import sequential_apply
from openquake.baselib.general import DictArray, groupby
from openquake.hazardlib.probability_map import ProbabilityMap, ProbabilityCurve
from openquake.hazardlib.gsim.base import ContextMaker, PmapMaker
from openquake.hazardlib.calc.filters import SourceFilter
from openquake.hazardlib.sourceconverter import SourceGroup
from openquake.hazardlib.tom import PoissonTOM, FatedTOM

def _cluster(sids, imtls, tom, gsims, pmap):
    """
    Computes the probability map in case of a cluster group
    """
    for nocc in range(0, 50):
        ocr = tom.occurrence_rate
        prob_n_occ = tom.get_probability_n_occurrences(ocr, nocc)
        if nocc == 0:
            pmapclu = pmap.new(numpy.full(pmap.shape, prob_n_occ))
        else:
            pmapclu.array += (1.-pmap.array)**nocc * prob_n_occ
    return ~pmapclu

def classical(group, sitecol, cmaker, pmap=None):
    """
    Compute the hazard curves for a set of sources belonging to the same
    tectonic region type for all the GSIMs associated to that TRT.
    The arguments are the same as in :func:`calc_hazard_curves`, except
    for ``gsims``, which is a list of GSIM instances.

    :returns:
        a dictionary with keys pmap, source_data, rup_data, extra
    """
    not_passed_pmap = pmap is None
    src_filter = SourceFilter(sitecol, cmaker.maximum_distance)
    cluster = getattr(group, 'cluster', None)
    rup_indep = getattr(group, 'rup_interdep', None) != 'mutex'
    trts = set()
    for src in group:
        if not src.num_ruptures:
            # src.num_ruptures may not be set, so it is set here
            src.num_ruptures = src.count_ruptures()
        # set the proper TOM in case of a cluster
        if cluster:
            src.temporal_occurrence_model = FatedTOM(time_span=1)
        trts.add(src.tectonic_region_type)
    [trt] = trts  # there must be a single tectonic region type
    if cmaker.trt != '*':
        assert trt == cmaker.trt, (trt, cmaker.trt)
    try:
        cmaker.tom = group.temporal_occurrence_model
    except AttributeError:  # got a list of sources, not a group
        time_span = cmaker.investigation_time  # None for nonparametric
        cmaker.tom = PoissonTOM(time_span) if time_span else None
    if cluster:
        cmaker.tom = FatedTOM(time_span=1)
    if not_passed_pmap:
        pmap = ProbabilityMap(
            sitecol.sids, cmaker.imtls.size, len(cmaker.gsims))
        pmap.fill(rup_indep)

    dic = PmapMaker(cmaker, src_filter, group).make(pmap)
    if getattr(group, 'src_interdep', None) != 'mutex' and rup_indep:
        pmap.array[:] = 1. - pmap.array
    if cluster:
        pmap.array[:] = _cluster(sitecol.sids,
                                 cmaker.imtls,
                                 getattr(group, 'temporal_occurrence_model'),
                                 cmaker.gsims,
                                 pmap).array
    return dic

# not used in the engine, only in tests and possibly notebooks
def calc_hazard_curves(
        groups, srcfilter, imtls, gsim_by_trt, truncation_level=99.,
        apply=sequential_apply, reqv=None, **kwargs):
    """
    Compute hazard curves on a list of sites, given a set of seismic source
    groups and a dictionary of ground shaking intensity models (one per
    tectonic region type).

    Probability of ground motion exceedance is computed in different ways
    depending if the sources are independent or mutually exclusive.

    :param groups:
        A sequence of groups of seismic sources objects (instances of
        of :class:`~openquake.hazardlib.source.base.BaseSeismicSource`).
    :param srcfilter:
        A source filter over the site collection or the site collection itself
    :param imtls:
        Dictionary mapping intensity measure type strings
        to lists of intensity measure levels.
    :param gsim_by_trt:
        Dictionary mapping tectonic region types (members
        of :class:`openquake.hazardlib.const.TRT`) to
        :class:`~openquake.hazardlib.gsim.base.GMPE` or
        :class:`~openquake.hazardlib.gsim.base.IPE` objects.
    :param truncation_level:
        Float, number of standard deviations for truncation of the intensity
        distribution.
    :param apply:
        apply function to use (default sequential_apply)
    :param reqv:
        If not None, an instance of RjbEquivalent
    :returns:
        An array of size N, where N is the number of sites, which elements
        are records with fields given by the intensity measure types; the
        size of each field is given by the number of levels in ``imtls``.
    """
    # This is ensuring backward compatibility i.e. processing a list of
    # sources
    if not isinstance(groups[0], SourceGroup):  # sent a list of sources
        odic = groupby(groups, operator.attrgetter('tectonic_region_type'))
        groups = [SourceGroup(trt, odic[trt], 'src_group', 'indep', 'indep')
                  for trt in odic]
    idx = 0
    span = None
    for i, grp in enumerate(groups):
        for src in grp:
            tom = getattr(src, 'temporal_occurrence_model', None)
            if tom:
                span = tom.time_span
            src.weight = src.count_ruptures()
            src.grp_id = i
            src.id = idx
            idx += 1
    imtls = DictArray(imtls)
    shift_hypo = kwargs['shift_hypo'] if 'shift_hypo' in kwargs else False
    param = dict(imtls=imtls, truncation_level=truncation_level, reqv=reqv,
                 cluster=grp.cluster, shift_hypo=shift_hypo,
                 investigation_time=kwargs.get('investigation_time', span))
    # Processing groups with homogeneous tectonic region
    mon = Monitor()
    sitecol = getattr(srcfilter, 'sitecol', srcfilter)
    pmap = ProbabilityMap(sitecol.sids, imtls.size, 1).fill(0)
    for group in groups:
        trt = group.trt
        if sitecol is not srcfilter:
            param['maximum_distance'] = srcfilter.integration_distance(trt)
        cmaker = ContextMaker(trt, [gsim_by_trt[trt]], param, mon)
        if group.atomic:  # do not split
            it = [classical(group, sitecol, cmaker)]
        else:  # split the group and apply `classical` in parallel
            it = apply(
                classical, (group.sources, sitecol, cmaker),
                weight=operator.attrgetter('weight'))
        for dic in it:
            pmap.array[:] = 1. - (1.-pmap.array) * (1. - dic['pmap'].array)
    return pmap.convert(imtls, len(sitecol.complete))

# called in adv-manual/developing.rst and in SingleSiteOptTestCase
def calc_hazard_curve(site1, src, gsims, oqparam, monitor=Monitor()):
    """
    :param site1: site collection with a single site
    :param src: a seismic source object
    :param gsims: a list of GSIM objects
    :param oqparam: an object with attributes .maximum_distance, .imtls
    :param monitor: a Monitor instance (optional)
    :returns: a ProbabilityCurve object
    """
    assert len(site1) == 1, site1
    trt = src.tectonic_region_type
    cmaker = ContextMaker(trt, gsims, vars(oqparam), monitor)
    cmaker.tom = src.temporal_occurrence_model
    srcfilter = SourceFilter(site1, oqparam.maximum_distance)
    pmap = ProbabilityMap(site1.sids, oqparam.imtls.size, 1).fill(1)
    PmapMaker(cmaker, srcfilter, [src]).make(pmap)
    pmap.array[:] = 1. - pmap.array
    if not pmap:  # filtered away
        zero = numpy.zeros((oqparam.imtls.size, len(gsims)))
        return ProbabilityCurve(zero)
    return ProbabilityCurve(pmap.array[0])
<|endoftext|>


<commit_before><commit_msg>Minor edits to analyser<commit_after><|endoftext|>


<commit_before>from __future__ import unicode_literals

import pytest

from stag import render, render_html
from stag.tags import *

def test_basic():
    assert render_basic(div({'id': 'main'}, p("Hello"))) == '

Hello

'
    assert render_basic(div(p("Hello"), id='main')) == '

Hello

'

def test_render():
    """
    Tests the `render()` function.
    """
    assert render_html(div(), doctype='') == render_basic(div())
    assert render_html(div()) == '<!DOCTYPE html>\n

'

def test_attributes():
    """
    Tests attributes being correctly rendered on elements.
    """
    # We have to test against both because we can't guarantee the order of the attributes
    outputs = ['

', '

']
    assert render_basic(div({'id': 'main', 'style': 'display:none'})) in outputs
    assert render_basic(div(id='main', style='display:none')) in outputs

def test_classes():
    """
    Tests the `classes` helper attribute on elements.
    """
    assert render_basic(div({'class': 'main'})) == render_basic(div(class_='main')) == '

'
    assert render_basic(div(classes=['content', 'wide'])) == '

'

def test_self_closing():
    """
    Tests to make sure self-closing tags properly raise a ValueError when children are inserted.
    """
    assert render_basic(img(class_='main')) == ''
    with pytest.raises(ValueError):
        img(p())

def test_integration():
    assert render_html(html(head(), body())) == '<!DOCTYPE html>\n'

def render_basic(tag):
    return render(tag)
<commit_msg>Update tests with newlines (no indent test yet)<commit_after>from __future__ import unicode_literals

import pytest

from stag import render, render_html
from stag.tags import *

# TODO: Clean this up somehow?

def test_basic():
    assert render_basic(div({'id': 'main'}, p("Hello"))) == '
\n
\nHello\n
\n
'
    assert render_basic(div(p("Hello"), id='main')) == '
\n
\nHello\n
\n
'

def test_render():
    """
    Tests the `render()` function.
    """
    assert render_html(div(), doctype='') == render_basic(div())
    assert render_html(div()) == '<!DOCTYPE html>\n
\n
'

def test_attributes():
    """
    Tests attributes being correctly rendered on elements.
    """
    # We have to test against both because we can't guarantee the order of the attributes
    outputs = ['
\n
', '
\n
']
    assert render_basic(div({'id': 'main', 'style': 'display:none'})) in outputs
    assert render_basic(div(id='main', style='display:none')) in outputs

def test_classes():
    """
    Tests the `classes` helper attribute on elements.
    """
    assert render_basic(div({'class': 'main'})) == render_basic(div(class_='main')) == '
\n
'
    assert render_basic(div(classes=['content', 'wide'])) == '
\n
'

def test_self_closing():
    """
    Tests to make sure self-closing tags properly raise a ValueError when children are inserted.
    """
    assert render_basic(img(class_='main')) == ''
    with pytest.raises(ValueError):
        img(p())

def test_integration():
    assert render_html(html(head(), body())) == '<!DOCTYPE html>\n\n\n\n\n\n'

def render_basic(tag):
    return render(tag)
<|endoftext|>


<commit_before>import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from django.core.management.base import BaseCommand
from os import chdir, getcwd
from subprocess import Popen, PIPE
from os.path import split, dirname, join, abspath
import os.path
import re
from optparse import make_option

CURRENT_PATH =  abspath(dirname(__file__))
AUTOTEST_PATH = abspath(join(CURRENT_PATH, '..'))

def absolute_path(path):

	return os.path.abspath(os.path.normpath(path))

class LoggingEventHandler(FileSystemEventHandler):

	def __init__(self, *args, **options):
		self.quick = options.get('quick', False)
		self.app_path = options.get('app_path', False)
		self.current_app = ''
		self.project_path = self.app_path.split(os.sep)

	def run_test_suite(self):

		chdir(self.app_path)
		test_command = ['python','manage.py', 'autotestrunner']
		if self.quick is True:
			test_command.append(self.current_app)
		result = Popen(test_command, stdout=PIPE, stderr=PIPE, close_fds=True).communicate()

		title = ''
		content = ''
		for line in result:
			split_lines = line.split('\n')
			for l in split_lines:
				if l.startswith('Ran'):
					title = l
				if l.startswith('OK') or l.startswith('FAIL'):
					content = l

		print line # Display the test suite results in the terminal
		chdir(AUTOTEST_PATH)
		os.system('chmod u+rwx notify.sh')
		os.system('./notify.sh "{0}" "{1}" '.format(title, content))

	def on_modified(self, event):
		super(LoggingEventHandler, self).on_modified(event)
		path_to_file, filename = split(event.src_path)
		valid_test = re.compile('(?:^|[\\b_\\.-])[Tt]ests?.py$') # extended from nose

		if valid_test.search(filename):

			path_to_file_list = path_to_file.split(os.sep)
			current_app_path = list(set(path_to_file_list) - set(self.project_path))
			self.current_app = ".".join(current_app_path)

			self.run_test_suite()

class Command(BaseCommand):
	option_list = BaseCommand.option_list + (
		make_option('--quick', default=False ,dest="quick", action="store_true",
					help='Runs the tests only for the application you are currently working on'),
		)
	help = 'Runs the test suite when a tests file is saved'

	requires_model_validation = False

	def handle(self, *args, **options):
		quick = options.get('quick', False)
		app_path = absolute_path(os.getcwd())

		handler = LoggingEventHandler(quick=quick, app_path=app_path)

		app_path = absolute_path(getcwd())

		observer = Observer()
		observer.schedule(handler, path=app_path, recursive=True)
		observer.start()
		try:
			while True:
				time.sleep(1)
		except KeyboardInterrupt:
			observer.stop()
		observer.join()

<commit_msg>Fixed duplication in the autotest command<commit_after>import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from django.core.management.base import BaseCommand
from os import chdir, getcwd
from subprocess import Popen, PIPE
from os.path import split, dirname, join, abspath
import os.path
import re
from optparse import make_option

CURRENT_PATH =  abspath(dirname(__file__))
AUTOTEST_PATH = abspath(join(CURRENT_PATH, '..'))

def absolute_path(path):

	return os.path.abspath(os.path.normpath(path))

class LoggingEventHandler(FileSystemEventHandler):

	def __init__(self, *args, **options):
		self.quick = options.get('quick', False)
		self.app_path = options.get('app_path', False)
		self.current_app = ''
		self.project_path = self.app_path.split(os.sep)

	def run_test_suite(self):

		chdir(self.app_path)
		test_command = ['python','manage.py', 'autotestrunner']
		if self.quick is True:
			test_command.append(self.current_app)
		result = Popen(test_command, stdout=PIPE, stderr=PIPE, close_fds=True).communicate()

		title = ''
		content = ''
		for line in result:
			split_lines = line.split('\n')
			for l in split_lines:
				if l.startswith('Ran'):
					title = l
				if l.startswith('OK') or l.startswith('FAIL'):
					content = l

		print line # Display the test suite results in the terminal
		chdir(AUTOTEST_PATH)
		os.system('chmod u+rwx notify.sh')
		os.system('./notify.sh "{0}" "{1}" '.format(title, content))

	def on_modified(self, event):
		super(LoggingEventHandler, self).on_modified(event)
		path_to_file, filename = split(event.src_path)
		valid_test = re.compile('(?:^|[\\b_\\.-])[Tt]ests?.py$') # extended from nose

		if valid_test.search(filename):

			path_to_file_list = path_to_file.split(os.sep)
			current_app_path = list(set(path_to_file_list) - set(self.project_path))
			self.current_app = ".".join(current_app_path)

			self.run_test_suite()

class Command(BaseCommand):
	option_list = BaseCommand.option_list + (
		make_option('--quick', default=False ,dest="quick", action="store_true",
					help='Runs the tests only for the application you are currently working on'),
		)
	help = 'Runs the test suite when a tests file is saved'

	requires_model_validation = False

	def handle(self, *args, **options):
		quick = options.get('quick', False)
		app_path = absolute_path(getcwd())

		handler = LoggingEventHandler(quick=quick, app_path=app_path)

		observer = Observer()
		observer.schedule(handler, path=app_path, recursive=True)
		observer.start()
		try:
			while True:
				time.sleep(1)
		except KeyboardInterrupt:
			observer.stop()
		observer.join()

<|endoftext|>


<commit_before><commit_msg>Bumped version to 1.1.3<commit_after><|endoftext|>


<commit_before>from __future__ import unicode_literals

from django.contrib import messages
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DeleteView

from ...product.models import Product, ProductImage, Stock, ProductAttribute
from ..utils import paginate
from ..views import StaffMemberOnlyMixin, staff_member_required
from .forms import (ProductClassForm, get_product_form,
                    get_product_cls_by_name, get_variant_form,
                    ProductImageForm, get_verbose_name, StockForm,
                    get_variant_cls, ProductAttributeForm,
                    AttributeChoiceValueFormset, VariantAttributesForm,
                    VariantsBulkDeleteForm, StockBulkDeleteForm)

@staff_member_required
def product_list(request):
    products = Product.objects.prefetch_related('images')
    form = ProductClassForm(request.POST or None)
    if form.is_valid():
        product_cls = form.cleaned_data['product_cls']
        return redirect('dashboard:product-add', product_cls=product_cls)
    products, paginator = paginate(products, 30, request.GET.get('page'))
    ctx = {'products': products, 'form': form, 'paginator': paginator}
    return TemplateResponse(request, 'dashboard/product/list.html', ctx)

@staff_member_required
def product_details(request, pk=None, product_cls=None):
    creating = pk is None
    initial = {}
    if creating:
        product = get_product_cls_by_name(product_cls)()
        title = _('Add new %s') % get_verbose_name(product)
    else:
        product = get_object_or_404(
            Product.objects.select_subclasses().prefetch_related(
                'images', 'variants'), pk=pk)
        title = product.name
    attributes = product.attributes.all()
    images = product.images.all()
    variants = product.variants.select_subclasses()
    stock_items = Stock.objects.filter(variant__in=variants)

    variant_choices = [(variant.pk, variant.name) for variant in variants]
    stock_choices = [(item.pk, item.pk) for item in stock_items]

    form_cls = get_product_form(product)
    form = form_cls(instance=product, initial=initial)
    variants_delete_form = VariantsBulkDeleteForm(choices=variant_choices)
    stock_delete_form = StockBulkDeleteForm(choices=stock_choices)

    if 'product-form' in request.POST:
        form = form_cls(request.POST, instance=product)
        product = save_product_form(request, form, creating)
        if creating and product:
            return redirect('dashboard:product-update', pk=product.pk)

    if 'variants-bulk-delete-form' in request.POST:
        variants_delete_form = VariantsBulkDeleteForm(request.POST, choices=variant_choices)
        if variants_delete_form.is_valid():
            variants_delete_form.delete()
            success_url = request.POST['success_url']
            return redirect(success_url)

    if 'stock-bulk-delete-form' in request.POST:
        stock_delete_form = StockBulkDeleteForm(request.POST, choices=stock_choices)
        if stock_delete_form.is_valid():
            stock_delete_form.delete()
            success_url = request.POST['success_url']
            return redirect(success_url)

    ctx = {
        'attributes': attributes, 'title': title, 'product': product,
        'images': images, 'product_form': form, 'stock_items': stock_items,
        'variants': variants, 'variants_delete_form': variants_delete_form,
        'stock_delete_form': stock_delete_form}
    if pk:
        images_reorder_url = reverse_lazy('dashboard:product-images-reorder',
                                          kwargs={'product_pk': pk})
        ctx['images_reorder_url'] = images_reorder_url
    return TemplateResponse(request, 'dashboard/product/product_form.html', ctx)

def save_product_form(request, form, creating):
    product = None
    if form.is_valid():
        product = form.save()
        if creating:
            msg = _('Added product %s') % product
        else:
            msg = _('Updated product %s') % product
        messages.success(request, msg)
    else:
        if form.errors:
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    return product

class ProductDeleteView(StaffMemberOnlyMixin, DeleteView):
    model = Product
    template_name = 'dashboard/product/product_confirm_delete.html'
    success_url = reverse_lazy('dashboard:products')

    def post(self, request, *args, **kwargs):
        result = self.delete(request, *args, **kwargs)
        messages.success(request, _('Deleted product %s') % self.object)
        return result

@staff_member_required
def stock_edit(request, product_pk, stock_pk=None):
    product = get_object_or_404(Product, pk=product_pk)
    if stock_pk:
        stock = get_object_or_404(Stock, pk=stock_pk)
    else:
        stock = Stock()
    form = StockForm(request.POST or None, instance=stock, product=product)
    if product.variants.exists():
        if form.is_valid():
            form.save()
            messages.success(request, _('Saved stock'))
            success_url = request.POST['success_url']
            return redirect(success_url)
        else:
            if form.errors:
                messages.error(request, _('Your submitted data was not valid - '
                                          'please correct the errors below'))
    else:
        messages.error(request, _(
            'You have to add at least one variant before you can add stock'))
    ctx = {'product': product, 'stock': stock, 'form': form}
    return TemplateResponse(request, 'dashboard/product/stock_form.html', ctx)

@staff_member_required
def stock_delete(request, product_pk, stock_pk):
    product = get_object_or_404(Product, pk=product_pk)
    stock = get_object_or_404(Stock, pk=stock_pk)
    if request.method == 'POST':
        stock.delete()
        messages.success(request, _('Deleted stock'))
        success_url = request.POST['success_url']
        return redirect(success_url)
    ctx = {'product': product, 'stock': stock}
    return TemplateResponse(
        request, 'dashboard/product/stock_confirm_delete.html', ctx)

@staff_member_required
def product_image_edit(request, product_pk, img_pk=None):
    product = get_object_or_404(Product, pk=product_pk)
    if img_pk:
        product_image = get_object_or_404(product.images, pk=img_pk)
    else:
        product_image = ProductImage(product=product)
    form = ProductImageForm(request.POST or None, request.FILES or None,
                            instance=product_image)
    if form.is_valid():
        product_image = form.save()
        if img_pk:
            msg = _('Updated image %s') % product_image.image.name
        else:
            msg = _('Added image %s') % product_image.image.name
        messages.success(request, msg)
        success_url = request.POST['success_url']
        return redirect(success_url)
    else:
        if form.errors:
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    ctx = {'product': product, 'product_image': product_image,
           'form': form}
    return TemplateResponse(
        request, 'dashboard/product/product_image_form.html', ctx)

@staff_member_required
def product_image_delete(request, product_pk, img_pk):
    product = get_object_or_404(Product, pk=product_pk)
    product_image = get_object_or_404(product.images, pk=img_pk)
    if request.method == 'POST':
        product_image.delete()
        messages.success(
            request, _('Deleted image %s') % product_image.image.name)
        success_url = request.POST['success_url']
        return redirect(success_url)
    ctx = {'product': product, 'product_image': product_image}
    return TemplateResponse(
        request, 'dashboard/product/product_image_confirm_delete.html', ctx)

@staff_member_required
def variant_edit(request, product_pk, variant_pk=None):
    product = get_object_or_404(Product.objects.select_subclasses(),
                                pk=product_pk)
    variant_cls = get_variant_cls(product)
    form_initial = {}
    if variant_pk:
        variant = get_object_or_404(product.variants.select_subclasses(),
                                    pk=variant_pk)
    else:
        variant = variant_cls(product=product)

    form_cls = get_variant_form(product)
    form = form_cls(request.POST or None, instance=variant,
                    initial=form_initial)
    attributes_form = VariantAttributesForm(request.POST or None,
                                            instance=variant)
    forms = [form, attributes_form]

    if all([f.is_valid() for f in forms]):
        form.save()
        attributes_form.save()
        if variant_pk:
            msg = _('Updated variant %s') % variant.name
        else:
            msg = _('Added variant %s') % variant.name
        messages.success(request, msg)
        success_url = request.POST['success_url']
        return redirect(success_url)
    else:
        if any([f.errors for f in forms]):
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    ctx = {'product': product, 'variant': variant,
           'form': form, 'attributes_form': attributes_form}
    return TemplateResponse(request, 'dashboard/product/variant_form.html', ctx)

@staff_member_required
def variant_delete(request, product_pk, variant_pk):
    product = get_object_or_404(Product, pk=product_pk)
    variant = get_object_or_404(product.variants, pk=variant_pk)
    is_only_variant = product.variants.count() == 1
    if request.method == 'POST':
        variant.delete()
        messages.success(request, _('Deleted variant %s') % variant.name)
        success_url = request.POST['success_url']
        return redirect(success_url)
    ctx = {'product': product, 'variant': variant,
           'is_only_variant': is_only_variant}
    return TemplateResponse(
        request, 'dashboard/product/product_variant_confirm_delete.html', ctx)

@staff_member_required
def attribute_list(request):
    attributes = ProductAttribute.objects.all()
    ctx = {'attributes': attributes}
    return TemplateResponse(request, 'dashboard/product/attributes/list.html',
                            ctx)

@staff_member_required
def attribute_edit(request, pk=None):
    if pk:
        attribute = get_object_or_404(ProductAttribute, pk=pk)
        title = attribute.display
    else:
        attribute = ProductAttribute()
        title = _('Add new attribute')
    form = ProductAttributeForm(request.POST or None, instance=attribute)
    formset = AttributeChoiceValueFormset(request.POST or None,
                                          request.FILES or None,
                                          instance=attribute)
    if form.is_valid() and formset.is_valid():
        attribute = form.save()
        formset.save()
        msg = _('Updated attribute') if pk else _('Added attribute')
        messages.success(request, msg)
        return redirect('dashboard:product-attribute-update', pk=attribute.pk)
    else:
        if form.errors or formset.errors:
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    ctx = {'attribute': attribute, 'form': form, 'formset': formset, 'title': title}
    return TemplateResponse(request, 'dashboard/product/attributes/form.html',
                            ctx)

@staff_member_required
def attribute_delete(request, pk):
    attribute = get_object_or_404(ProductAttribute, pk=pk)
    if request.method == 'POST':
        attribute.delete()
        messages.success(request, _('Deleted attribute %s' % attribute.display))
        return redirect('dashboard:product-attributes')
    ctx = {'attribute': attribute}
    return TemplateResponse(request,
                            'dashboard/product/attributes/confirm_delete.html',
                            ctx)
<commit_msg>Cosmetic changes<commit_after>from __future__ import unicode_literals

from django.contrib import messages
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DeleteView

from ...product.models import Product, ProductImage, Stock, ProductAttribute
from ..utils import paginate
from ..views import StaffMemberOnlyMixin, staff_member_required
from .forms import (ProductClassForm, get_product_form,
                    get_product_cls_by_name, get_variant_form,
                    ProductImageForm, get_verbose_name, StockForm,
                    get_variant_cls, ProductAttributeForm,
                    AttributeChoiceValueFormset, VariantAttributesForm,
                    VariantsBulkDeleteForm, StockBulkDeleteForm)

@staff_member_required
def product_list(request):
    products = Product.objects.prefetch_related('images')
    form = ProductClassForm(request.POST or None)
    if form.is_valid():
        product_cls = form.cleaned_data['product_cls']
        return redirect('dashboard:product-add', product_cls=product_cls)
    products, paginator = paginate(products, 30, request.GET.get('page'))
    ctx = {'form': form,
           'products': products,
           'paginator': paginator}
    return TemplateResponse(request, 'dashboard/product/list.html', ctx)

@staff_member_required
def product_details(request, pk=None, product_cls=None):
    creating = pk is None
    initial = {}
    if creating:
        product = get_product_cls_by_name(product_cls)()
        title = _('Add new %s') % get_verbose_name(product)
    else:
        product = get_object_or_404(
            Product.objects.select_subclasses().prefetch_related(
                'images', 'variants'), pk=pk)
        title = product.name
    attributes = product.attributes.all()
    images = product.images.all()
    variants = product.variants.select_subclasses()
    stock_items = Stock.objects.filter(variant__in=variants)

    variant_choices = [(variant.pk, variant.name) for variant in variants]
    stock_choices = [(item.pk, item.pk) for item in stock_items]

    form_cls = get_product_form(product)
    form = form_cls(instance=product, initial=initial)
    variants_delete_form = VariantsBulkDeleteForm(choices=variant_choices)
    stock_delete_form = StockBulkDeleteForm(choices=stock_choices)

    if 'product-form' in request.POST:
        form = form_cls(request.POST, instance=product)
        product = save_product_form(request, form, creating)
        if creating and product:
            return redirect('dashboard:product-update', pk=product.pk)

    if 'variants-bulk-delete-form' in request.POST:
        variants_delete_form = VariantsBulkDeleteForm(request.POST, choices=variant_choices)
        if variants_delete_form.is_valid():
            variants_delete_form.delete()
            success_url = request.POST['success_url']
            return redirect(success_url)

    if 'stock-bulk-delete-form' in request.POST:
        stock_delete_form = StockBulkDeleteForm(request.POST, choices=stock_choices)
        if stock_delete_form.is_valid():
            stock_delete_form.delete()
            success_url = request.POST['success_url']
            return redirect(success_url)

    ctx = {'attributes': attributes,
           'images': images, 'product_form': form,
           'product': product,
           'stock_delete_form': stock_delete_form,
           'stock_items': stock_items,
           'title': title,
           'variants': variants,
           'variants_delete_form': variants_delete_form}

    if pk:
        images_reorder_url = reverse_lazy('dashboard:product-images-reorder',
                                          kwargs={'product_pk': pk})
        ctx['images_reorder_url'] = images_reorder_url
    return TemplateResponse(request, 'dashboard/product/product_form.html', ctx)

def save_product_form(request, form, creating):
    product = None
    if form.is_valid():
        product = form.save()
        if creating:
            msg = _('Added product %s') % product
        else:
            msg = _('Updated product %s') % product
        messages.success(request, msg)
    else:
        if form.errors:
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    return product

class ProductDeleteView(StaffMemberOnlyMixin, DeleteView):
    model = Product
    template_name = 'dashboard/product/product_confirm_delete.html'
    success_url = reverse_lazy('dashboard:products')

    def post(self, request, *args, **kwargs):
        result = self.delete(request, *args, **kwargs)
        messages.success(request, _('Deleted product %s') % self.object)
        return result

@staff_member_required
def stock_edit(request, product_pk, stock_pk=None):
    product = get_object_or_404(Product, pk=product_pk)
    if stock_pk:
        stock = get_object_or_404(Stock, pk=stock_pk)
    else:
        stock = Stock()
    form = StockForm(request.POST or None, instance=stock, product=product)
    if product.variants.exists():
        if form.is_valid():
            form.save()
            messages.success(request, _('Saved stock'))
            success_url = request.POST['success_url']
            return redirect(success_url)
        else:
            if form.errors:
                messages.error(request, _('Your submitted data was not valid - '
                                          'please correct the errors below'))
    else:
        messages.error(request, _(
            'You have to add at least one variant before you can add stock'))
    ctx = {'form': form,
           'product': product,
           'stock': stock}
    return TemplateResponse(request, 'dashboard/product/stock_form.html', ctx)

@staff_member_required
def stock_delete(request, product_pk, stock_pk):
    product = get_object_or_404(Product, pk=product_pk)
    stock = get_object_or_404(Stock, pk=stock_pk)
    if request.method == 'POST':
        stock.delete()
        messages.success(request, _('Deleted stock'))
        success_url = request.POST['success_url']
        return redirect(success_url)
    ctx = {'product': product,
           'stock': stock}
    return TemplateResponse(
        request, 'dashboard/product/stock_confirm_delete.html', ctx)

@staff_member_required
def product_image_edit(request, product_pk, img_pk=None):
    product = get_object_or_404(Product, pk=product_pk)
    if img_pk:
        product_image = get_object_or_404(product.images, pk=img_pk)
    else:
        product_image = ProductImage(product=product)
    form = ProductImageForm(request.POST or None, request.FILES or None,
                            instance=product_image)
    if form.is_valid():
        product_image = form.save()
        if img_pk:
            msg = _('Updated image %s') % product_image.image.name
        else:
            msg = _('Added image %s') % product_image.image.name
        messages.success(request, msg)
        success_url = request.POST['success_url']
        return redirect(success_url)
    else:
        if form.errors:
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    ctx = {'form': form,
           'product': product,
           'product_image': product_image}
    return TemplateResponse(
        request, 'dashboard/product/product_image_form.html', ctx)

@staff_member_required
def product_image_delete(request, product_pk, img_pk):
    product = get_object_or_404(Product, pk=product_pk)
    product_image = get_object_or_404(product.images, pk=img_pk)
    if request.method == 'POST':
        product_image.delete()
        messages.success(
            request, _('Deleted image %s') % product_image.image.name)
        success_url = request.POST['success_url']
        return redirect(success_url)
    ctx = {'product': product, 'product_image': product_image}
    return TemplateResponse(
        request, 'dashboard/product/product_image_confirm_delete.html', ctx)

@staff_member_required
def variant_edit(request, product_pk, variant_pk=None):
    product = get_object_or_404(Product.objects.select_subclasses(),
                                pk=product_pk)
    variant_cls = get_variant_cls(product)
    form_initial = {}
    if variant_pk:
        variant = get_object_or_404(product.variants.select_subclasses(),
                                    pk=variant_pk)
    else:
        variant = variant_cls(product=product)

    form_cls = get_variant_form(product)
    form = form_cls(request.POST or None, instance=variant,
                    initial=form_initial)
    attributes_form = VariantAttributesForm(request.POST or None,
                                            instance=variant)
    forms = [form, attributes_form]

    if all([f.is_valid() for f in forms]):
        form.save()
        attributes_form.save()
        if variant_pk:
            msg = _('Updated variant %s') % variant.name
        else:
            msg = _('Added variant %s') % variant.name
        messages.success(request, msg)
        success_url = request.POST['success_url']
        return redirect(success_url)
    else:
        if any([f.errors for f in forms]):
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    ctx = {'attributes_form': attributes_form,
           'form': form,
           'product': product,
           'variant': variant}
    return TemplateResponse(request, 'dashboard/product/variant_form.html', ctx)

@staff_member_required
def variant_delete(request, product_pk, variant_pk):
    product = get_object_or_404(Product, pk=product_pk)
    variant = get_object_or_404(product.variants, pk=variant_pk)
    is_only_variant = product.variants.count() == 1
    if request.method == 'POST':
        variant.delete()
        messages.success(request, _('Deleted variant %s') % variant.name)
        success_url = request.POST['success_url']
        return redirect(success_url)
    ctx = {'is_only_variant': is_only_variant,
           'product': product,
           'variant': variant}
    return TemplateResponse(
        request, 'dashboard/product/product_variant_confirm_delete.html', ctx)

@staff_member_required
def attribute_list(request):
    attributes = ProductAttribute.objects.all()
    ctx = {'attributes': attributes}
    return TemplateResponse(request, 'dashboard/product/attributes/list.html',
                            ctx)

@staff_member_required
def attribute_edit(request, pk=None):
    if pk:
        attribute = get_object_or_404(ProductAttribute, pk=pk)
        title = attribute.display
    else:
        attribute = ProductAttribute()
        title = _('Add new attribute')
    form = ProductAttributeForm(request.POST or None, instance=attribute)
    formset = AttributeChoiceValueFormset(request.POST or None,
                                          request.FILES or None,
                                          instance=attribute)
    if form.is_valid() and formset.is_valid():
        attribute = form.save()
        formset.save()
        msg = _('Updated attribute') if pk else _('Added attribute')
        messages.success(request, msg)
        return redirect('dashboard:product-attribute-update', pk=attribute.pk)
    else:
        if form.errors or formset.errors:
            messages.error(request, _('Your submitted data was not valid - '
                                      'please correct the errors below'))
    ctx = {'attribute': attribute,
           'form': form,
           'formset': formset,
           'title': title}
    return TemplateResponse(request, 'dashboard/product/attributes/form.html',
                            ctx)

@staff_member_required
def attribute_delete(request, pk):
    attribute = get_object_or_404(ProductAttribute, pk=pk)
    if request.method == 'POST':
        attribute.delete()
        messages.success(request, _('Deleted attribute %s' % attribute.display))
        return redirect('dashboard:product-attributes')
    ctx = {'attribute': attribute}
    return TemplateResponse(request,
                            'dashboard/product/attributes/confirm_delete.html',
                            ctx)
<|endoftext|>


<commit_before># coding: utf-8
import unittest
# from unittest.mock import MagicMock
import buscacep as busca

class TestBuscaCep(unittest.TestCase):
    def setUp(self):
        pass
        # self.resp = {'bairro': 'Bela Vista', 'cep': '01310-000', 'localidade': 'São Paulo/SP', 'logradouro': 'Avenida Paulista - até 610 - lado par'}

    def test_cep_not_none(self):
        with self.assertRaises(AttributeError):
            busca.busca_cep_correios(None)

    def test_cep_is_digit(self):
        with self.assertRaises(AttributeError):
            busca.busca_cep_correios(12345678)

if __name__ == '__main__':
    unittest.main()
<commit_msg>test the service for match<commit_after># coding: utf-8
import unittest
# from unittest.mock import MagicMock
import buscacep as busca

class TestBuscaCep(unittest.TestCase):
    def setUp(self):
        self.resp = {'bairro': 'Bela Vista', 'cep': '01310-000', 'localidade': 'São Paulo/SP', 'logradouro': 'Avenida Paulista - até 610 - lado par'}

    def test_cep_not_none(self):
        with self.assertRaises(AttributeError):
            busca.busca_cep_correios(None)

    def test_cep_is_digit(self):
        with self.assertRaises(AttributeError):
            busca.busca_cep_correios(12345678)

    def test_cep_match(self):
        self.r = busca.busca_cep_correios('01310000').as_dict()
        self.resultado = set(self.resp.items()) ^ set(self.r.items())
        self.assertEquals(0, len(self.resultado))

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
'''
Utility functions for the rest_sample
'''
from __future__ import absolute_import

__proxyenabled__ = ['rest_sample']

def fix_outage():
    '''
    "Fix" the outage
    '''
    return __proxy__['rest_sample.fix_outage']()
<commit_msg>Lint.<commit_after># -*- coding: utf-8 -*-
'''
Utility functions for the rest_sample
'''
from __future__ import absolute_import

__proxyenabled__ = ['rest_sample']

def fix_outage():
    '''
    "Fix" the outage

    .. code-block:: bash

        salt 'rest-sample-proxy' rest_sample.fix_outage

    '''
    return __proxy__['rest_sample.fix_outage']()
<|endoftext|>