<commit_before>import sys  # NOQA  # isort:skip
sys.path.insert(0, '.')  # NOQA  # isort:skip

import os
import re

import caffe_pb2
import chainer
from chainer import serializers
import chainer.links as L
from google.protobuf import text_format
import numpy as np
import pspnet

def get_chainer_model(n_class, input_size, n_blocks, pyramids, mid_stride):
    with chainer.using_config('train', True):
        model = pspnet.PSPNet(
            n_class, input_size, n_blocks, pyramids, mid_stride)
        model(np.random.rand(1, 3, input_size, input_size).astype(np.float32))
    size = 0
    for param in model.params():
        try:
            size += param.size
        except Exception as e:
            print(str(type(e)), e, param, param.name)
            exit(-1)
    print('PSPNet (chainer) size:', size)
    return model

def get_param_net(prodo_dir, param_fn, proto_fn):
    print('Loading caffe parameters...', end=' ')
    param = caffe_pb2.NetParameter()
    param.MergeFromString(open(param_fn, 'rb').read())
    print('done')

    print('Loading caffe prototxt...', end=' ')
    proto_fp = open(proto_fn).read()
    net = caffe_pb2.NetParameter()
    net = text_format.Merge(proto_fp, net)
    print('done')

    return param, net

def copy_conv(layer, config, conv, has_bias=False):
    data = np.array(layer.blobs[0].data)
    conv.W.data[:] = data.reshape(conv.W.shape)
    if has_bias:
        data = np.array(layer.blobs[1].data)
        conv.b.data[:] = data.reshape(conv.b.shape)

    # Check ksize
    assert config.convolution_param.kernel_size[0] == conv.ksize, \
        'ksize: {} != {} ({}, {}, {}, {})'.format(
            config.convolution_param.kernel_size[0], conv.ksize,
            layer.name, config, conv, conv.name)

    # Check stride
    if len(config.convolution_param.stride) == 1:
        stride = config.convolution_param.stride[0]
        stride = (stride, stride)
    assert stride == conv.stride, \
        'stride: {} != {} ({}, {}, {}, {})'.format(
            stride, conv.stride, layer.name, config, conv, conv.name)

    # Check pad
    if len(config.convolution_param.pad) == 1:
        pad = config.convolution_param.pad[0]
        pad = (pad, pad)
    elif config.convolution_param.pad == []:
        pad = (0, 0)
    assert pad == conv.pad, \
        'pad: {} != {} ({}, {}, {}, {})'.format(
            pad, conv.pad, layer.name, config, conv, conv.name)

    assert layer.convolution_param.bias_term == has_bias
    if not has_bias:
        assert conv.b is None
    if isinstance(config.convolution_param.dilation, int):
        assert isinstance(conv, L.DilatedConvolution2D)
        assert config.convolution_param.dilation == conv.dilate

    return conv

def copy_cbr(layer, config, cbr):
    if 'Convolution' in layer.type:
        cbr.conv = copy_conv(layer, config, cbr.conv)
    elif 'BN' in layer.type:
        cbr.bn.eps = config.bn_param.eps
        cbr.bn.decay = config.bn_param.momentum
        cbr.bn.gamma.data.ravel()[:] = np.array(layer.blobs[0].data).ravel()
        cbr.bn.beta.data.ravel()[:] = np.array(layer.blobs[1].data).ravel()
        cbr.bn.avg_mean.ravel()[:] = np.array(layer.blobs[2].data).ravel()
        cbr.bn.avg_var.ravel()[:] = np.array(layer.blobs[3].data).ravel()
    else:
        print('Ignored: {} ({})'.format(layer.name, layer.type))
    return cbr

def copy_head(layer, config, block):
    if layer.name.startswith('conv1_1'):
        block.cbr1_1 = copy_cbr(layer, config, block.cbr1_1)
    elif layer.name.startswith('conv1_2'):
        block.cbr1_2 = copy_cbr(layer, config, block.cbr1_2)
    elif layer.name.startswith('conv1_3'):
        block.cbr1_3 = copy_cbr(layer, config, block.cbr1_3)
    else:
        print('Ignored: {} ({})'.format(layer.name, layer.type))
    return block

def copy_bottleneck(layer, config, block):
    if 'reduce' in layer.name:
        block.cbr1 = copy_cbr(layer, config, block.cbr1)
    elif '3x3' in layer.name:
        block.cbr2 = copy_cbr(layer, config, block.cbr2)
    elif 'increase' in layer.name:
        block.cbr3 = copy_cbr(layer, config, block.cbr3)
    elif 'proj' in layer.name:
        block.cbr4 = copy_cbr(layer, config, block.cbr4)
    else:
        print('Ignored: {} ({})'.format(layer.name, layer.type))
    return block

def copy_resblock(layer, config, block):
    if '/' in layer.name:
        layer.name = layer.name.split('/')[0]
    i = int(layer.name.split('_')[1]) - 1
    block._children[i] = copy_bottleneck(layer, config, block[i])
    return block

def copy_ppm_module(layer, config, block):
    ret = re.search('pool([0-9]+)', layer.name)
    if ret is None:
        raise ValueError('Error in copy_ppm_module:'
                         '{}, {}, {}'.format(layer.name, config, block))
    i = int(ret.groups()[0])
    i = {1: 3,
         2: 2,
         3: 1,
         6: 0}[i]
    block._children[i] = copy_cbr(layer, config, block[i])
    return block

def transfer(model, param, net):
    name_config = dict([(l.name, l) for l in net.layer])
    for layer in param.layer:
        if layer.name not in name_config:
            continue
        config = name_config[layer.name]
        if layer.name.startswith('conv1'):
            model.trunk = copy_head(layer, config, model.trunk)
        elif layer.name.startswith('conv2'):
            model.trunk.res2 = copy_resblock(layer, config, model.trunk.res2)
        elif layer.name.startswith('conv3'):
            model.trunk.res3 = copy_resblock(layer, config, model.trunk.res3)
        elif layer.name.startswith('conv4'):
            model.trunk.res4 = copy_resblock(layer, config, model.trunk.res4)
        elif layer.name.startswith('conv5') \
                and 'pool' not in layer.name \
                and 'conv5_4' not in layer.name:
            model.trunk.res5 = copy_resblock(layer, config, model.trunk.res5)
        elif layer.name.startswith('conv5_3') and 'pool' in layer.name:
            model.ppm = copy_ppm_module(layer, config, model.ppm)
        elif layer.name.startswith('conv5_4'):
            model.cbr_main = copy_cbr(layer, config, model.cbr_main)
        elif layer.name.startswith('conv6'):
            model.out_main = copy_conv(
                layer, config, model.out_main, has_bias=True)
        else:
            print('Ignored: {} ({})'.format(layer.name, layer.type))
    return model

if __name__ == '__main__':
    proto_dir = 'weights'

    if not os.path.exists(os.path.join(proto_dir, 'pspnet101_VOC2012.caffemodel')):
        print('Please download pspnet101_VOC2012.caffemodel from here: '
              'https://drive.google.com/open?id=0BzaU285cX7TCNVhETE5vVUdMYk0 '
              'and put it into weights/ dir.')
        exit()
    if not os.path.exists(os.path.join(proto_dir, 'pspnet101_cityscapes.caffemodel')):
        print('Please download pspnet101_cityscapes.caffemodel from here: '
              'https://drive.google.com/open?id=0BzaU285cX7TCT1M3TmNfNjlUeEU '
              'and put it into weights/ dir.')
        exit()
    if not os.path.exists(os.path.join(proto_dir, 'pspnet50_ADE20K.caffemodel')):
        print('Please download pspnet50_ADE20K.caffemodel from here: '
              'https://drive.google.com/open?id=0BzaU285cX7TCN1R3QnUwQ0hoMTA '
              'and put it into weights/ dir.')
        exit()

    # Num of parameters of models for...
    # VOC2012: 65708501 (train: 70524906)
    # Cityscapes: 65707475
    # ADE20K: 46782550

    settings = {
        'voc2012': {
            'proto_fn': 'pspnet101_VOC2012_473.prototxt',
            'param_fn': 'pspnet101_VOC2012.caffemodel',
            'n_class': 21,
            'input_size': 473,
            'n_blocks': [3, 4, 23, 3],
            'feat_size': 60,
            'mid_stride': True,
            'pyramids': [6, 3, 2, 1],
        },
        'cityscapes': {
            'proto_fn': 'pspnet101_cityscapes_713.prototxt',
            'param_fn': 'pspnet101_cityscapes.caffemodel',
            'n_class': 19,
            'input_size': 713,
            'n_blocks': [3, 4, 23, 3],
            'feat_size': 90,
            'mid_stride': True,
            'pyramids': [6, 3, 2, 1],
        },
        'ade20k': {
            'proto_fn': 'pspnet50_ADE20K_473.prototxt',
            'param_fn': 'pspnet50_ADE20K.caffemodel',
            'n_class': 150,
            'input_size': 473,
            'n_blocks': [3, 4, 6, 3],
            'feat_size': 60,
            'mid_stride': False,
            'pyramids': [6, 3, 2, 1],
        }
    }

    for dataset_name in ['voc2012', 'cityscapes', 'ade20k']:
        proto_fn = settings[dataset_name]['proto_fn']
        param_fn = settings[dataset_name]['param_fn']
        n_class = settings[dataset_name]['n_class']
        input_size = settings[dataset_name]['input_size']
        n_blocks = settings[dataset_name]['n_blocks']
        pyramids = settings[dataset_name]['pyramids']
        mid_stride = settings[dataset_name]['mid_stride']

        name = os.path.splitext(proto_fn)[0]
        param_fn = os.path.join(proto_dir, param_fn)
        proto_fn = os.path.join(proto_dir, proto_fn)

        model = get_chainer_model(
            n_class, input_size, n_blocks, pyramids, mid_stride)
        param, net = get_param_net(proto_dir, param_fn, proto_fn)
        model = transfer(model, param, net)

        serializers.save_npz(
            'weights/{}_reference.npz'.format(name), model)
        print('weights/{}_reference.npz'.format(name), 'saved')
<commit_msg>Fix import<commit_after>import sys  # NOQA  # isort:skip
sys.path.insert(0, '.')  # NOQA  # isort:skip

import os
import re

import caffe_pb2
import chainer
import chainer.links as L
from chainer import serializers
from chainercv.links import PSPNet
from google.protobuf import text_format
import numpy as np

def get_chainer_model(n_class, input_size, n_blocks, pyramids, mid_stride):
    with chainer.using_config('train', True):
        model = PSPNet(
            n_class, input_size, n_blocks, pyramids, mid_stride)
        model(np.random.rand(1, 3, input_size, input_size).astype(np.float32))
    size = 0
    for param in model.params():
        try:
            size += param.size
        except Exception as e:
            print(str(type(e)), e, param, param.name)
            exit(-1)
    print('PSPNet (chainer) size:', size)
    return model

def get_param_net(prodo_dir, param_fn, proto_fn):
    print('Loading caffe parameters...', end=' ')
    param = caffe_pb2.NetParameter()
    param.MergeFromString(open(param_fn, 'rb').read())
    print('done')

    print('Loading caffe prototxt...', end=' ')
    proto_fp = open(proto_fn).read()
    net = caffe_pb2.NetParameter()
    net = text_format.Merge(proto_fp, net)
    print('done')

    return param, net

def copy_conv(layer, config, conv, has_bias=False):
    data = np.array(layer.blobs[0].data)
    conv.W.data[:] = data.reshape(conv.W.shape)
    if has_bias:
        data = np.array(layer.blobs[1].data)
        conv.b.data[:] = data.reshape(conv.b.shape)

    # Check ksize
    assert config.convolution_param.kernel_size[0] == conv.ksize, \
        'ksize: {} != {} ({}, {}, {}, {})'.format(
            config.convolution_param.kernel_size[0], conv.ksize,
            layer.name, config, conv, conv.name)

    # Check stride
    if len(config.convolution_param.stride) == 1:
        stride = config.convolution_param.stride[0]
        stride = (stride, stride)
    assert stride == conv.stride, \
        'stride: {} != {} ({}, {}, {}, {})'.format(
            stride, conv.stride, layer.name, config, conv, conv.name)

    # Check pad
    if len(config.convolution_param.pad) == 1:
        pad = config.convolution_param.pad[0]
        pad = (pad, pad)
    elif config.convolution_param.pad == []:
        pad = (0, 0)
    assert pad == conv.pad, \
        'pad: {} != {} ({}, {}, {}, {})'.format(
            pad, conv.pad, layer.name, config, conv, conv.name)

    assert layer.convolution_param.bias_term == has_bias
    if not has_bias:
        assert conv.b is None
    if isinstance(config.convolution_param.dilation, int):
        assert isinstance(conv, L.DilatedConvolution2D)
        assert config.convolution_param.dilation == conv.dilate

    return conv

def copy_cbr(layer, config, cbr):
    if 'Convolution' in layer.type:
        cbr.conv = copy_conv(layer, config, cbr.conv)
    elif 'BN' in layer.type:
        cbr.bn.eps = config.bn_param.eps
        cbr.bn.decay = config.bn_param.momentum
        cbr.bn.gamma.data.ravel()[:] = np.array(layer.blobs[0].data).ravel()
        cbr.bn.beta.data.ravel()[:] = np.array(layer.blobs[1].data).ravel()
        cbr.bn.avg_mean.ravel()[:] = np.array(layer.blobs[2].data).ravel()
        cbr.bn.avg_var.ravel()[:] = np.array(layer.blobs[3].data).ravel()
    else:
        print('Ignored: {} ({})'.format(layer.name, layer.type))
    return cbr

def copy_head(layer, config, block):
    if layer.name.startswith('conv1_1'):
        block.cbr1_1 = copy_cbr(layer, config, block.cbr1_1)
    elif layer.name.startswith('conv1_2'):
        block.cbr1_2 = copy_cbr(layer, config, block.cbr1_2)
    elif layer.name.startswith('conv1_3'):
        block.cbr1_3 = copy_cbr(layer, config, block.cbr1_3)
    else:
        print('Ignored: {} ({})'.format(layer.name, layer.type))
    return block

def copy_bottleneck(layer, config, block):
    if 'reduce' in layer.name:
        block.cbr1 = copy_cbr(layer, config, block.cbr1)
    elif '3x3' in layer.name:
        block.cbr2 = copy_cbr(layer, config, block.cbr2)
    elif 'increase' in layer.name:
        block.cbr3 = copy_cbr(layer, config, block.cbr3)
    elif 'proj' in layer.name:
        block.cbr4 = copy_cbr(layer, config, block.cbr4)
    else:
        print('Ignored: {} ({})'.format(layer.name, layer.type))
    return block

def copy_resblock(layer, config, block):
    if '/' in layer.name:
        layer.name = layer.name.split('/')[0]
    i = int(layer.name.split('_')[1]) - 1
    block._children[i] = copy_bottleneck(layer, config, block[i])
    return block

def copy_ppm_module(layer, config, block):
    ret = re.search('pool([0-9]+)', layer.name)
    if ret is None:
        raise ValueError('Error in copy_ppm_module:'
                         '{}, {}, {}'.format(layer.name, config, block))
    i = int(ret.groups()[0])
    i = {1: 3,
         2: 2,
         3: 1,
         6: 0}[i]
    block._children[i] = copy_cbr(layer, config, block[i])
    return block

def transfer(model, param, net):
    name_config = dict([(l.name, l) for l in net.layer])
    for layer in param.layer:
        if layer.name not in name_config:
            continue
        config = name_config[layer.name]
        if layer.name.startswith('conv1'):
            model.trunk = copy_head(layer, config, model.trunk)
        elif layer.name.startswith('conv2'):
            model.trunk.res2 = copy_resblock(layer, config, model.trunk.res2)
        elif layer.name.startswith('conv3'):
            model.trunk.res3 = copy_resblock(layer, config, model.trunk.res3)
        elif layer.name.startswith('conv4'):
            model.trunk.res4 = copy_resblock(layer, config, model.trunk.res4)
        elif layer.name.startswith('conv5') \
                and 'pool' not in layer.name \
                and 'conv5_4' not in layer.name:
            model.trunk.res5 = copy_resblock(layer, config, model.trunk.res5)
        elif layer.name.startswith('conv5_3') and 'pool' in layer.name:
            model.ppm = copy_ppm_module(layer, config, model.ppm)
        elif layer.name.startswith('conv5_4'):
            model.cbr_main = copy_cbr(layer, config, model.cbr_main)
        elif layer.name.startswith('conv6'):
            model.out_main = copy_conv(
                layer, config, model.out_main, has_bias=True)
        else:
            print('Ignored: {} ({})'.format(layer.name, layer.type))
    return model

if __name__ == '__main__':
    proto_dir = 'weights'

    if not os.path.exists(
            os.path.join(proto_dir, 'pspnet101_VOC2012.caffemodel')):
        print('Please download pspnet101_VOC2012.caffemodel from here: '
              'https://drive.google.com/open?id=0BzaU285cX7TCNVhETE5vVUdMYk0 '
              'and put it into weights/ dir.')
        exit()
    if not os.path.exists(
            os.path.join(proto_dir, 'pspnet101_cityscapes.caffemodel')):
        print('Please download pspnet101_cityscapes.caffemodel from here: '
              'https://drive.google.com/open?id=0BzaU285cX7TCT1M3TmNfNjlUeEU '
              'and put it into weights/ dir.')
        exit()
    if not os.path.exists(
            os.path.join(proto_dir, 'pspnet50_ADE20K.caffemodel')):
        print('Please download pspnet50_ADE20K.caffemodel from here: '
              'https://drive.google.com/open?id=0BzaU285cX7TCN1R3QnUwQ0hoMTA '
              'and put it into weights/ dir.')
        exit()

    # Num of parameters of models for...
    # VOC2012: 65708501 (train: 70524906)
    # Cityscapes: 65707475
    # ADE20K: 46782550

    settings = {
        'voc2012': {
            'proto_fn': 'pspnet101_VOC2012_473.prototxt',
            'param_fn': 'pspnet101_VOC2012.caffemodel',
            'n_class': 21,
            'input_size': 473,
            'n_blocks': [3, 4, 23, 3],
            'feat_size': 60,
            'mid_stride': True,
            'pyramids': [6, 3, 2, 1],
        },
        'cityscapes': {
            'proto_fn': 'pspnet101_cityscapes_713.prototxt',
            'param_fn': 'pspnet101_cityscapes.caffemodel',
            'n_class': 19,
            'input_size': 713,
            'n_blocks': [3, 4, 23, 3],
            'feat_size': 90,
            'mid_stride': True,
            'pyramids': [6, 3, 2, 1],
        },
        'ade20k': {
            'proto_fn': 'pspnet50_ADE20K_473.prototxt',
            'param_fn': 'pspnet50_ADE20K.caffemodel',
            'n_class': 150,
            'input_size': 473,
            'n_blocks': [3, 4, 6, 3],
            'feat_size': 60,
            'mid_stride': False,
            'pyramids': [6, 3, 2, 1],
        }
    }

    for dataset_name in ['voc2012', 'cityscapes', 'ade20k']:
        proto_fn = settings[dataset_name]['proto_fn']
        param_fn = settings[dataset_name]['param_fn']
        n_class = settings[dataset_name]['n_class']
        input_size = settings[dataset_name]['input_size']
        n_blocks = settings[dataset_name]['n_blocks']
        pyramids = settings[dataset_name]['pyramids']
        mid_stride = settings[dataset_name]['mid_stride']

        name = os.path.splitext(proto_fn)[0]
        param_fn = os.path.join(proto_dir, param_fn)
        proto_fn = os.path.join(proto_dir, proto_fn)

        model = get_chainer_model(
            n_class, input_size, n_blocks, pyramids, mid_stride)
        param, net = get_param_net(proto_dir, param_fn, proto_fn)
        model = transfer(model, param, net)

        serializers.save_npz(
            'weights/{}_reference.npz'.format(name), model)
        print('weights/{}_reference.npz'.format(name), 'saved')
<|endoftext|>


<commit_before>import time
import random
import opc
import colorsys
import sys
from PIL import Image,ImageFont,ImageDraw

# config stuff
screen_width = 32*2
screen_height = 16
target_address = '10.0.5.184:7890'
frame_delay = 0.03
font = ImageFont.truetype("/Library/Fonts/comic.ttf",14)
make_rainbows = True

# if argv
def get_text():
	if sys.argv[1]:
		return sys.argv[1]
	else:
		return "HACKER SCHOOL, NEVER GRADUATE!"

#rainbow bg
def rainbow_bg(x,total):
	# hue, lightness, saturation to rgb
	vals = colorsys.hls_to_rgb(round(float(x)/total,2),0.05,1)
	return (int(vals[0]*255),int(vals[1]*255),int(vals[2]*255))

my_text = get_text()
message_width, message_height = font.getsize(my_text)

im = Image.new("RGB",(screen_width,screen_height),"black")
draw = ImageDraw.Draw(im)

total_width = message_width + screen_width

client = opc.Client(target_address)

while True:
	for i in range(total_width):
		if make_rainbows:
			bg = rainbow_bg(i,message_width)
		else:
			bg = (0,0,0)

		im.paste(bg, (0,0,screen_width,screen_height))
		draw.text((64-i,0), my_text, font=font)
		all_pixels = []
		pixels = im.load()
		img_width,img_height = im.size
		for y in range(screen_height):
			for x in range(screen_width):
				all_pixels.append(pixels[x,y])
		client.put_pixels(all_pixels, channel=0)
		#print i
		time.sleep(frame_delay)

<commit_msg>scroller repeats, woo<commit_after># coding=UTF-8
# Hacker School LED Display

import time
import random
import opc
import colorsys
import sys
from PIL import Image,ImageFont,ImageDraw

# config stuff
screen_width = 32*2
screen_height = 16
target_address = '10.0.5.184:7890'
frame_delay = 0.02
font = ImageFont.truetype("/Library/Fonts/Arial.ttf",14)
make_rainbows = False

# if argv
def get_text():
	if len(sys.argv) > 1:
		return sys.argv[1]+"   "
	else:
		return "Hello, Hacker School!   "

#rainbow bg
def rainbow_bg(x,total):
	# hue, lightness, saturation to rgb
	vals = colorsys.hls_to_rgb(round(float(x)/total,2),0.05,1)
	return (int(vals[0]*255),int(vals[1]*255),int(vals[2]*255))

def generate_img():
	all_pixels = []
	img_width,img_height = im.size
	for y in range(screen_height):
		for x in range(screen_width):
			all_pixels.append(pixels[x,y])
	return all_pixels

my_text = get_text() + "   " + get_text()
message_width, message_height = font.getsize(my_text)

im = Image.new("RGB",(screen_width,screen_height),"black")
draw = ImageDraw.Draw(im)
msg_width = int(message_width / 2)
total_width = message_width + screen_width

client = opc.Client(target_address)

print "Screen Width: %s Message Width: %s, Total Width: %s" % (screen_width,message_width,total_width)

xOffset = 0
while True:
	# bg stuff
	if make_rainbows:
		rainbow_bg(xOffset,total_width)
	else:
		bg = (0,0,0)

	# Loop drawing one frame
	if xOffset > (msg_width + screen_width):
		xOffset -= msg_width
	else:
		xOffset += 1

	print "Iteration: %s Drawing Offset: %s" % (xOffset,screen_width-xOffset)

	im.paste(bg,(0,0,screen_width,screen_height))

	draw.text((screen_width-xOffset,0), my_text, font=font)

	all_pixels = []
	pixels = im.load()

	client.put_pixels(generate_img(), channel=0)
	time.sleep(frame_delay)

<|endoftext|>


<commit_before><commit_msg>Remove help string in the DEFINE_dict docstring example.<commit_after><|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#   myplotspec.text.py
#
#   Copyright (C) 2015 Karl T Debiec
#   All rights reserved.
#
#   This software may be modified and distributed under the terms of the
#   BSD license. See the LICENSE file for details.
"""
Functions for formatting text.

.. todo:
  - Resolve inconsistencies in how positions are determined, without
    conflicting with matplotlib's style. Most likely, x and y should
    retain their matplotlib behavior, being proportions when used with
    figures and coordinates when used with subplots. Text functions
    below should support xpro and ypro that are always proportions, xabs
    and yabs that are always absolute coordinates, for subplots xcrd and
    ycrd in subplot coordinates, and finally left, right, top, and
    bottom in inches.
"""
################################### MODULES ###################################
from __future__ import absolute_import,division,print_function,unicode_literals
################################## FUNCTIONS ##################################
def set_title(figure_or_subplot, title=None, title_fp=None, *args,
    **kwargs):
    """
    Draws a title on a Figure or subplot.

    Arguments:
      figure_or_subplot (Figure, Axes): Object on which to draw title
      title (str): Title text
      title_fp (str, dict, FontProperties): Title font
      top (float): Distance between top of figure and title (inches);
        Figure title only
      title_kw (dict): Keyword arguments passed to ``Figure.suptitle()``
        or ``Axes.set_title()``

    Returns:
      (*Text*): Title

    .. todo:
        - If top is negative, use distance from highest subplot
    """
    import matplotlib
    from . import get_font, multi_kw, FP_KEYS

    title_kw = kwargs.pop("title_kw", {})

    title_fp_2 = multi_kw(["title_fp"] + FP_KEYS, title_kw)
    if title_fp_2 is not None:
        title_kw["fontproperties"] = get_font(title_fp_2)
    elif title_fp   is not None:
        title_kw["fontproperties"] = get_font(title_fp)

    if isinstance(figure_or_subplot, matplotlib.figure.Figure):
        figure = figure_or_subplot

        title_2 = multi_kw(["title", "t"], title_kw)
        if title_2 is not None:
            title_kw["t"] = title_2
        elif title   is not None:
            title_kw["t"] = title
        elif len(args) >= 1:
            title_kw["t"] = args[0]
        else:
            return None

        if "top" in title_kw:
            top           = title_kw.pop
            fig_height    = figure.get_figheight()
            title_kw["y"] = (fig_height - top) / fig_height

        return figure.suptitle(**title_kw)

    elif isinstance(figure_or_subplot, matplotlib.axes.Axes):
        subplot = figure_or_subplot

        title_2 = multi_kw(["title", "label"], title_kw)
        if title_2 is not None:
            title_kw["label"] = title_2
        elif title   is not None:
            title_kw["label"] = title
        elif len(args) >= 1:
            title_kw["label"] = args[0]
        else:
            return None

        return subplot.set_title(**title_kw)

def set_shared_xlabel(figure_or_subplots, xlabel=None, xlabel_fp=None,
    label_fp=None, *args, **kwargs):
    """
    Draws an x axis label shared by multiple subplots.

    The horizontal position of the shared x label is (by default) the
    center of the selected subplots, and the vertical position is a
    specified distance from the bottom of the figure.

    Arguments:
      figure_or_subplots (Figure, OrderedDict): Subplots to use to
        calculate label horizontal position; if Figure, all subplots
        present on figure are used
      xlabel (str): Label text
      [x]label_fp (str, dict, FontProperties): Label font
      xlabel_kw (dict): Keyword arguments passed to :func:`set_text`
      bottom (float): Distance between bottom of figure and label
        (inches); if negative, distance between bottommost plot and
        label
      top (float): Distance between top of figure and label; if
        negative, distance between topmost subplot and label; overrides
        ``bottom``
      x (float): X position within figure (proportion 0.0-1.0); default
        = center of selected subplots
      y (float): Y position within figure (proportion 0.0-1.0);
        overrides ``bottom`` and ``top``

    Returns:
      (*Text*): X axis label
    """
    import matplotlib
    from . import get_edges, get_font, multi_kw, FP_KEYS

    label_kw = kwargs.pop("xlabel_kw", {})

    label_fp_2 = multi_kw(["xlabel_fp", "label_fp"] + FP_KEYS, label_kw)
    if label_fp_2 is not None:
        label_kw["fontproperties"] = get_font(label_fp_2)
    elif xlabel_fp is not None:
        label_kw["fontproperties"] = get_font(xlabel_fp)
    elif label_fp is not None:
        label_kw["fontproperties"] = get_font(label_fp)

    label_2 = multi_kw(["xlabel", "label", "s"], label_kw)
    if label_2 is not None:
        label_kw["s"] = label_2
    elif xlabel is not None:
        label_kw["s"] = xlabel
    elif len(args) >= 1:
        label_kw["s"] = args[0]
    else:
        return None

    if isinstance(figure_or_subplots, matplotlib.figure.Figure):
        figure = figure_or_subplots
        edges  = get_edges(figure)
    elif isinstance(figure_or_subplots, dict):
        subplots = figure_or_subplots
        figure   = subplots.values()[0].get_figure()
        edges    = get_edges(subplots)

    if "x" not in label_kw:
        label_kw["x"] = (edges["left"] + edges["right"]) / 2.0
    if "y" not in label_kw:
        fig_height = figure.get_figheight()
        if "top" in label_kw:
            top = label_kw.pop("top")
            if top >= 0:
                label_kw["y"] = (fig_height - top) / fig_height
            else:
                label_kw["y"] = (((edges["top"] * fig_height) + top)
                              / fig_height)
        elif "bottom" in label_kw:
            bottom = label_kw.pop("bottom")
            if bottom >= 0:
                label_kw["y"] = bottom / fig_height
            else:
                label_kw["y"] = (((edges["bottom"] * fig_height) + bottom)
                              / fig_height)
        else:
            label_kw["y"] = edges["bottom"] / 2

    return set_text(figure, text_kw = label_kw, **kwargs)

def set_shared_ylabel(figure_or_subplots, ylabel=None, ylabel_fp=None,
    label_fp=None, *args, **kwargs):
    """
    Draws a y-axis label shared by multiple subplots.

    The vertical position of the shared y label is (by default) the
    center of the selected subplots, and the horizontal position is a
    specified distance from the left edge of the figure.

    Arguments:
      figure_or_subplots (Figure, OrderedDict): Subplots to use to
        calculate label vertical position; if Figure, all subplots
        present on figure are used
      ylabel (str): Label text
      [y]label_fp (str, dict, FontProperties): Label font
      ylabel_kw (dict): Keyword arguments passed to :func:`set_text`
      left (float): Distance between left side of figure and label; if
        negative, distance between leftmost plot and label
      right (float): Distance between right side of figure and label; if
        negative, distance between rightmost plot and label; overrides
        ``left``
      x (float): X position within figure (proportion 0.0-1.0);
        overrides ``left`` and ``right``
      y (float): Y position within figure (proportion 0.0-1.0); default
        = center of selected subplots

    Returns:
      (*Text*): Y axis label
    """
    import matplotlib
    from . import get_edges, get_font, multi_kw, FP_KEYS

    label_kw = kwargs.pop("ylabel_kw", {})

    label_fp_2 = multi_kw(["ylabel_fp", "label_fp"] + FP_KEYS, label_kw)
    if label_fp_2 is not None:
        label_kw["fontproperties"] = get_font(label_fp_2)
    elif ylabel_fp is not None:
        label_kw["fontproperties"] = get_font(ylabel_fp)
    elif label_fp   is not None:
        label_kw["fontproperties"] = get_font(label_fp)

    label_2 = multi_kw(["ylabel", "label", "s"], label_kw)
    if label_2 is not None:
        label_kw["s"] = label_2
    elif ylabel is not None:
        label_kw["s"] = ylabel
    elif len(args) >= 1:
        label_kw["s"] = args[0]
    else:
        return None

    if isinstance(figure_or_subplots, matplotlib.figure.Figure):
        figure = figure_or_subplots
        edges  = get_edges(figure)
    elif isinstance(figure_or_subplots, dict):
        subplots = figure_or_subplots
        figure   = subplots.values()[0].get_figure()
        edges    = get_edges(subplots)

    if "x" not in label_kw:
        fig_width = figure.get_figwidth()
        if "right" in label_kw:
            right = label_kw.pop("right")
            if right < 0:
                label_kw["x"] = (edges["right"] - right) / fig_width
            else:
                label_kw["x"] = (fig_width - right) / fig_width
        else:
            left = label_kw.pop("left", -0.5)
            if left < 0:
                label_kw["x"] = (edges["left"] + left) / fig_width
            else:
                label_kw["x"] = left / fig_width

    if "y" not in label_kw:
        label_kw["y"] = (edges["bottom"] + edges["top"]) / 2.0

    return set_text(figure, text_kw = label_kw, **kwargs)

def set_inset(subplot, inset=None, inset_fp=None, *args, **kwargs):
    """
    Draws a text inset on a subplot.

    Arguments:
      subplot (Axes): Subplot on which to draw inset
      inset (str): Inset text
      inset_fp (str, dict, FontProperties): Inset font
      inset_kw (dict): Keyword arguments passed to :func:`set_text`
      xpro (float): X position within subplot (proportion 0.0-1.0)
      ypro (float): Y position within subplot (proportion 0.0-1.0)
      x (float): X position within subplot (subplot coordinate);
        overrides ``xpro``
      y (float): Y position within subplot (subplot coordinate),
        overrides ``ypro``

    Returns:
      (*Text*): Inset text
    """
    from . import get_font, multi_kw, FP_KEYS

    inset_kw = kwargs.pop("inset_kw", {})

    inset_fp_2 = multi_kw(["inset_fp"] + FP_KEYS, inset_kw)
    if inset_fp_2 is not None:
        inset_kw["fontproperties"] = get_font(inset_fp_2)
    elif inset_fp   is not None:
        inset_kw["fontproperties"] = get_font(inset_fp)

    if "ha" not in inset_kw:
        inset_kw["ha"] = "left"

    if "va" not in inset_kw:
        inset_kw["va"] = "top"

    inset_2 = multi_kw(["inset", "s"], inset_kw)
    if inset_2 is not None:
        inset_kw["s"] = inset_2
    elif inset is not None:
        inset_kw["s"] = inset_2
    elif len(args) >= 1:
        inset_kw["s"] = args[0]
    else:
        return None

    if "x" not in inset_kw:
        xmin, xmax = subplot.get_xbound()
        xpro = inset_kw.pop("xpro", 0.05)
        if subplot.xaxis_inverted():
            inset_kw["x"] = xmin + (1 - xpro) * (xmax - xmin)
        else:
            inset_kw["x"] = xmin +      xpro  * (xmax - xmin)

    if "y" not in inset_kw:
        ymin, ymax = subplot.get_ybound()
        ypro = inset_kw.pop("ypro", 0.95)
        if subplot.yaxis_inverted():
            inset_kw["y"] = ymin + (1 - ypro) * (ymax - ymin)
        else:
            inset_kw["y"] = ymax +      ypro  * (ymax - ymin)

    return set_text(subplot, test_kw = inset_kw, **kwargs)

def set_text(figure_or_subplot, s=None, x=None, y=None, text=None,
    fp=None, *args, **kwargs):
    """
    Prints text on a figure or subplot.

    Arguments:
      figure_or_subplot (Figure, Axes): Object on which to draw
      text (str): Text
      fp (str, dict, FontProperties): Text font
      text_kw (dict): Keyword arguments passed to ``text()``

    Returns:
      (*Text*): Text
    """
    from . import get_font, multi_kw, FP_KEYS

    text_kw = kwargs.pop("text_kw", {}).copy()

    fp_2 = multi_kw(["fp"] + FP_KEYS, text_kw)
    if fp_2 is not None:
        text_kw["fontproperties"] = get_font(fp_2)
    elif fp is not None:
        text_kw["fontproperties"] = get_font(fp)

    text_2 = multi_kw(["text", "s"], text_kw)
    if text_2 is not None:
        text_kw["s"] = text_2
    elif s is not None:
        text_kw["s"] = s
    elif text is not None:
        text_kw["s"] = text
    elif len(args) >= 1:
        text_kw["s"] = args[0]
    else:
        return None
    if x is not None and not "x" in text_kw:
        text_kw["x"] = x
    if y is not None and not "y" in text_kw:
        text_kw["y"] = y

    return figure_or_subplot.text(**text_kw)
<commit_msg>Support for outline of text annotation<commit_after># -*- coding: utf-8 -*-
#   myplotspec.text.py
#
#   Copyright (C) 2015 Karl T Debiec
#   All rights reserved.
#
#   This software may be modified and distributed under the terms of the
#   BSD license. See the LICENSE file for details.
"""
Functions for formatting text.

.. todo:
  - Resolve inconsistencies in how positions are determined, without
    conflicting with matplotlib's style. Most likely, x and y should
    retain their matplotlib behavior, being proportions when used with
    figures and coordinates when used with subplots. Text functions
    below should support xpro and ypro that are always proportions, xabs
    and yabs that are always absolute coordinates, for subplots xcrd and
    ycrd in subplot coordinates, and finally left, right, top, and
    bottom in inches.
"""
################################### MODULES ###################################
from __future__ import absolute_import,division,print_function,unicode_literals
################################## FUNCTIONS ##################################
def set_title(figure_or_subplot, title=None, title_fp=None, *args,
    **kwargs):
    """
    Draws a title on a Figure or subplot.

    Arguments:
      figure_or_subplot (Figure, Axes): Object on which to draw title
      title (str): Title text
      title_fp (str, dict, FontProperties): Title font
      top (float): Distance between top of figure and title (inches);
        Figure title only
      title_kw (dict): Keyword arguments passed to ``Figure.suptitle()``
        or ``Axes.set_title()``

    Returns:
      (*Text*): Title

    .. todo:
        - If top is negative, use distance from highest subplot
    """
    import matplotlib
    from . import get_font, multi_kw, FP_KEYS

    title_kw = kwargs.pop("title_kw", {})

    title_fp_2 = multi_kw(["title_fp"] + FP_KEYS, title_kw)
    if title_fp_2 is not None:
        title_kw["fontproperties"] = get_font(title_fp_2)
    elif title_fp   is not None:
        title_kw["fontproperties"] = get_font(title_fp)

    if isinstance(figure_or_subplot, matplotlib.figure.Figure):
        figure = figure_or_subplot

        title_2 = multi_kw(["title", "t"], title_kw)
        if title_2 is not None:
            title_kw["t"] = title_2
        elif title   is not None:
            title_kw["t"] = title
        elif len(args) >= 1:
            title_kw["t"] = args[0]
        else:
            return None

        if "top" in title_kw:
            top           = title_kw.pop
            fig_height    = figure.get_figheight()
            title_kw["y"] = (fig_height - top) / fig_height

        return figure.suptitle(**title_kw)

    elif isinstance(figure_or_subplot, matplotlib.axes.Axes):
        subplot = figure_or_subplot

        title_2 = multi_kw(["title", "label"], title_kw)
        if title_2 is not None:
            title_kw["label"] = title_2
        elif title   is not None:
            title_kw["label"] = title
        elif len(args) >= 1:
            title_kw["label"] = args[0]
        else:
            return None

        return subplot.set_title(**title_kw)

def set_shared_xlabel(figure_or_subplots, xlabel=None, xlabel_fp=None,
    label_fp=None, *args, **kwargs):
    """
    Draws an x axis label shared by multiple subplots.

    The horizontal position of the shared x label is (by default) the
    center of the selected subplots, and the vertical position is a
    specified distance from the bottom of the figure.

    Arguments:
      figure_or_subplots (Figure, OrderedDict): Subplots to use to
        calculate label horizontal position; if Figure, all subplots
        present on figure are used
      xlabel (str): Label text
      [x]label_fp (str, dict, FontProperties): Label font
      xlabel_kw (dict): Keyword arguments passed to :func:`set_text`
      bottom (float): Distance between bottom of figure and label
        (inches); if negative, distance between bottommost plot and
        label
      top (float): Distance between top of figure and label; if
        negative, distance between topmost subplot and label; overrides
        ``bottom``
      x (float): X position within figure (proportion 0.0-1.0); default
        = center of selected subplots
      y (float): Y position within figure (proportion 0.0-1.0);
        overrides ``bottom`` and ``top``

    Returns:
      (*Text*): X axis label
    """
    import matplotlib
    from . import get_edges, get_font, multi_kw, FP_KEYS

    label_kw = kwargs.pop("xlabel_kw", {})

    label_fp_2 = multi_kw(["xlabel_fp", "label_fp"] + FP_KEYS, label_kw)
    if label_fp_2 is not None:
        label_kw["fontproperties"] = get_font(label_fp_2)
    elif xlabel_fp is not None:
        label_kw["fontproperties"] = get_font(xlabel_fp)
    elif label_fp is not None:
        label_kw["fontproperties"] = get_font(label_fp)

    label_2 = multi_kw(["xlabel", "label", "s"], label_kw)
    if label_2 is not None:
        label_kw["s"] = label_2
    elif xlabel is not None:
        label_kw["s"] = xlabel
    elif len(args) >= 1:
        label_kw["s"] = args[0]
    else:
        return None

    if isinstance(figure_or_subplots, matplotlib.figure.Figure):
        figure = figure_or_subplots
        edges  = get_edges(figure)
    elif isinstance(figure_or_subplots, dict):
        subplots = figure_or_subplots
        figure   = subplots.values()[0].get_figure()
        edges    = get_edges(subplots)

    if "x" not in label_kw:
        label_kw["x"] = (edges["left"] + edges["right"]) / 2.0
    if "y" not in label_kw:
        fig_height = figure.get_figheight()
        if "top" in label_kw:
            top = label_kw.pop("top")
            if top >= 0:
                label_kw["y"] = (fig_height - top) / fig_height
            else:
                label_kw["y"] = (((edges["top"] * fig_height) + top)
                              / fig_height)
        elif "bottom" in label_kw:
            bottom = label_kw.pop("bottom")
            if bottom >= 0:
                label_kw["y"] = bottom / fig_height
            else:
                label_kw["y"] = (((edges["bottom"] * fig_height) + bottom)
                              / fig_height)
        else:
            label_kw["y"] = edges["bottom"] / 2

    return set_text(figure, text_kw = label_kw, **kwargs)

def set_shared_ylabel(figure_or_subplots, ylabel=None, ylabel_fp=None,
    label_fp=None, *args, **kwargs):
    """
    Draws a y-axis label shared by multiple subplots.

    The vertical position of the shared y label is (by default) the
    center of the selected subplots, and the horizontal position is a
    specified distance from the left edge of the figure.

    Arguments:
      figure_or_subplots (Figure, OrderedDict): Subplots to use to
        calculate label vertical position; if Figure, all subplots
        present on figure are used
      ylabel (str): Label text
      [y]label_fp (str, dict, FontProperties): Label font
      ylabel_kw (dict): Keyword arguments passed to :func:`set_text`
      left (float): Distance between left side of figure and label; if
        negative, distance between leftmost plot and label
      right (float): Distance between right side of figure and label; if
        negative, distance between rightmost plot and label; overrides
        ``left``
      x (float): X position within figure (proportion 0.0-1.0);
        overrides ``left`` and ``right``
      y (float): Y position within figure (proportion 0.0-1.0); default
        = center of selected subplots

    Returns:
      (*Text*): Y axis label
    """
    import matplotlib
    from . import get_edges, get_font, multi_kw, FP_KEYS

    label_kw = kwargs.pop("ylabel_kw", {})

    label_fp_2 = multi_kw(["ylabel_fp", "label_fp"] + FP_KEYS, label_kw)
    if label_fp_2 is not None:
        label_kw["fontproperties"] = get_font(label_fp_2)
    elif ylabel_fp is not None:
        label_kw["fontproperties"] = get_font(ylabel_fp)
    elif label_fp   is not None:
        label_kw["fontproperties"] = get_font(label_fp)

    label_2 = multi_kw(["ylabel", "label", "s"], label_kw)
    if label_2 is not None:
        label_kw["s"] = label_2
    elif ylabel is not None:
        label_kw["s"] = ylabel
    elif len(args) >= 1:
        label_kw["s"] = args[0]
    else:
        return None

    if isinstance(figure_or_subplots, matplotlib.figure.Figure):
        figure = figure_or_subplots
        edges  = get_edges(figure)
    elif isinstance(figure_or_subplots, dict):
        subplots = figure_or_subplots
        figure   = subplots.values()[0].get_figure()
        edges    = get_edges(subplots)

    if "x" not in label_kw:
        fig_width = figure.get_figwidth()
        if "right" in label_kw:
            right = label_kw.pop("right")
            if right < 0:
                label_kw["x"] = (edges["right"] - right) / fig_width
            else:
                label_kw["x"] = (fig_width - right) / fig_width
        else:
            left = label_kw.pop("left", -0.5)
            if left < 0:
                label_kw["x"] = (edges["left"] + left) / fig_width
            else:
                label_kw["x"] = left / fig_width

    if "y" not in label_kw:
        label_kw["y"] = (edges["bottom"] + edges["top"]) / 2.0

    return set_text(figure, text_kw = label_kw, **kwargs)

def set_inset(subplot, inset=None, inset_fp=None, *args, **kwargs):
    """
    Draws a text inset on a subplot.

    Arguments:
      subplot (Axes): Subplot on which to draw inset
      inset (str): Inset text
      inset_fp (str, dict, FontProperties): Inset font
      inset_kw (dict): Keyword arguments passed to :func:`set_text`
      xpro (float): X position within subplot (proportion 0.0-1.0)
      ypro (float): Y position within subplot (proportion 0.0-1.0)
      x (float): X position within subplot (subplot coordinate);
        overrides ``xpro``
      y (float): Y position within subplot (subplot coordinate),
        overrides ``ypro``

    Returns:
      (*Text*): Inset text
    """
    from . import get_font, multi_kw, FP_KEYS

    inset_kw = kwargs.pop("inset_kw", {})

    inset_fp_2 = multi_kw(["inset_fp"] + FP_KEYS, inset_kw)
    if inset_fp_2 is not None:
        inset_kw["fontproperties"] = get_font(inset_fp_2)
    elif inset_fp   is not None:
        inset_kw["fontproperties"] = get_font(inset_fp)

    if "ha" not in inset_kw:
        inset_kw["ha"] = "left"

    if "va" not in inset_kw:
        inset_kw["va"] = "top"

    inset_2 = multi_kw(["inset", "s"], inset_kw)
    if inset_2 is not None:
        inset_kw["s"] = inset_2
    elif inset is not None:
        inset_kw["s"] = inset_2
    elif len(args) >= 1:
        inset_kw["s"] = args[0]
    else:
        return None

    if "x" not in inset_kw:
        xmin, xmax = subplot.get_xbound()
        xpro = inset_kw.pop("xpro", 0.05)
        if subplot.xaxis_inverted():
            inset_kw["x"] = xmin + (1 - xpro) * (xmax - xmin)
        else:
            inset_kw["x"] = xmin +      xpro  * (xmax - xmin)

    if "y" not in inset_kw:
        ymin, ymax = subplot.get_ybound()
        ypro = inset_kw.pop("ypro", 0.95)
        if subplot.yaxis_inverted():
            inset_kw["y"] = ymin + (1 - ypro) * (ymax - ymin)
        else:
            inset_kw["y"] = ymax +      ypro  * (ymax - ymin)

    return set_text(subplot, test_kw = inset_kw, **kwargs)

def set_text(figure_or_subplot, s=None, x=None, y=None, text=None, fp=None,
    border_lw=None, *args, **kwargs):
    """
    Prints text on a figure or subplot.

    Arguments:
      figure_or_subplot (Figure, Axes): Object on which to draw
      text (str): Text
      fp (str, dict, FontProperties): Text font
      text_kw (dict): Keyword arguments passed to ``text()``

    Returns:
      (*Text*): Text
    """
    from  matplotlib import patheffects
    from . import get_font, multi_kw, FP_KEYS

    text_kw = kwargs.pop("text_kw", {}).copy()

    fp_2 = multi_kw(["fp"] + FP_KEYS, text_kw)
    if fp_2 is not None:
        text_kw["fontproperties"] = get_font(fp_2)
    elif fp is not None:
        text_kw["fontproperties"] = get_font(fp)

    text_2 = multi_kw(["text", "s"], text_kw)
    if text_2 is not None:
        text_kw["s"] = text_2
    elif s is not None:
        text_kw["s"] = s
    elif text is not None:
        text_kw["s"] = text
    elif len(args) >= 1:
        text_kw["s"] = args[0]
    else:
        return None
    if x is not None and not "x" in text_kw:
        text_kw["x"] = x
    if y is not None and not "y" in text_kw:
        text_kw["y"] = y

    text = figure_or_subplot.text(**text_kw)
    if border_lw is not None:
        text.set_path_effects([patheffects.Stroke(linewidth=border_lw,
          foreground="w"), patheffects.Normal()])
    return text
<|endoftext|>


<commit_before><commit_msg>Fix example fedmsg config.<commit_after><|endoftext|>


<commit_before>from django import forms
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.contrib import admin
from django.contrib.auth.models import User, Group

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

from messages.models import Message

class MessageAdminForm(forms.ModelForm):
    """
    Custom AdminForm to enable messages to groups and all users.
    """
    recipient = forms.ModelChoiceField(
        label=_('Recipient'), queryset=User.objects.all(), required=True)

    group = forms.ChoiceField(label=_('group'), required=False,
        help_text=_('Creates the message optionally for all users or a group of users.'))

    def __init__(self, *args, **kwargs):
        super(MessageAdminForm, self).__init__(*args, **kwargs)
        self.fields['group'].choices = self._get_group_choices()

    def _get_group_choices(self):
        return [('', u'---------'), ('all', _('All users'))] + \
            [(group.pk, group.name) for group in Group.objects.all()]

    class Meta:
        model = Message

class MessageAdmin(admin.ModelAdmin):
    form = MessageAdminForm
    fieldsets = (
        (None, {
            'fields': (
                'sender',
                ('recipient', 'group'),
            ),
        }),
        (_('Message'), {
            'fields': (
                'parent_msg',
                'subject', 'body',
            ),
            'classes': ('monospace' ),
        }),
        (_('Date/time'), {
            'fields': (
                'sent_at', 'read_at', 'replied_at',
                'sender_deleted_at', 'recipient_deleted_at',
            ),
            'classes': ('collapse', 'wide'),
        }),
    )
    list_display = ('subject', 'sender', 'recipient', 'sent_at', 'read_at')
    list_filter = ('sent_at', 'sender', 'recipient')
    search_fields = ('subject', 'body')

    def save_model(self, request, obj, form, change):
        """
        Saves the message for the recipient and looks in the form instance
        for other possible recipients. Prevents duplication by excludin the
        original recipient from the list of optional recipients.

        When changing an existing message and choosing optional recipients,
        the message is effectively resent to those users.
        """
        obj.save()

        if notification:
            # Getting the appropriate notice labels for the sender and recipients.
            if obj.parent_msg is None:
                sender_label = 'messages_sent'
                recipients_label = 'messages_received'
            else:
                sender_label = 'messages_replied'
                recipients_label = 'messages_reply_received'

            # Notification for the sender.
            notification.send([obj.sender], sender_label, {'message': obj,})

        if form.cleaned_data['group'] == 'all':
            # send to all users
            recipients = User.objects.exclude(pk=obj.recipient.pk)
        else:
            # send to a group of users
            recipients = []
            group = form.cleaned_data['group']
            if group:
                group = Group.objects.get(pk=group)
                recipients.extend(
                    list(group.user_set.exclude(pk=obj.recipient.pk)))
        # create messages for all found recipients
        for user in recipients:
            obj.pk = None
            obj.recipient = user
            obj.save()

            if notification:
                # Notification for the recipient.
                notification.send([user], recipients_label, {'message' : obj,})

admin.site.register(Message, MessageAdmin)
<commit_msg>Using ugettext_lazy instead of gettext_lazy<commit_after>from django import forms
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.contrib import admin
from django.contrib.auth.models import User, Group

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

from messages.models import Message

class MessageAdminForm(forms.ModelForm):
    """
    Custom AdminForm to enable messages to groups and all users.
    """
    recipient = forms.ModelChoiceField(
        label=_('Recipient'), queryset=User.objects.all(), required=True)

    group = forms.ChoiceField(label=_('group'), required=False,
        help_text=_('Creates the message optionally for all users or a group of users.'))

    def __init__(self, *args, **kwargs):
        super(MessageAdminForm, self).__init__(*args, **kwargs)
        self.fields['group'].choices = self._get_group_choices()

    def _get_group_choices(self):
        return [('', u'---------'), ('all', _('All users'))] + \
            [(group.pk, group.name) for group in Group.objects.all()]

    class Meta:
        model = Message

class MessageAdmin(admin.ModelAdmin):
    form = MessageAdminForm
    fieldsets = (
        (None, {
            'fields': (
                'sender',
                ('recipient', 'group'),
            ),
        }),
        (_('Message'), {
            'fields': (
                'parent_msg',
                'subject', 'body',
            ),
            'classes': ('monospace' ),
        }),
        (_('Date/time'), {
            'fields': (
                'sent_at', 'read_at', 'replied_at',
                'sender_deleted_at', 'recipient_deleted_at',
            ),
            'classes': ('collapse', 'wide'),
        }),
    )
    list_display = ('subject', 'sender', 'recipient', 'sent_at', 'read_at')
    list_filter = ('sent_at', 'sender', 'recipient')
    search_fields = ('subject', 'body')

    def save_model(self, request, obj, form, change):
        """
        Saves the message for the recipient and looks in the form instance
        for other possible recipients. Prevents duplication by excludin the
        original recipient from the list of optional recipients.

        When changing an existing message and choosing optional recipients,
        the message is effectively resent to those users.
        """
        obj.save()

        if notification:
            # Getting the appropriate notice labels for the sender and recipients.
            if obj.parent_msg is None:
                sender_label = 'messages_sent'
                recipients_label = 'messages_received'
            else:
                sender_label = 'messages_replied'
                recipients_label = 'messages_reply_received'

            # Notification for the sender.
            notification.send([obj.sender], sender_label, {'message': obj,})

        if form.cleaned_data['group'] == 'all':
            # send to all users
            recipients = User.objects.exclude(pk=obj.recipient.pk)
        else:
            # send to a group of users
            recipients = []
            group = form.cleaned_data['group']
            if group:
                group = Group.objects.get(pk=group)
                recipients.extend(
                    list(group.user_set.exclude(pk=obj.recipient.pk)))
        # create messages for all found recipients
        for user in recipients:
            obj.pk = None
            obj.recipient = user
            obj.save()

            if notification:
                # Notification for the recipient.
                notification.send([user], recipients_label, {'message' : obj,})

admin.site.register(Message, MessageAdmin)
<|endoftext|>


<commit_before><commit_msg>Added a module for creating bypass overhead graphs.<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# fixture - remote presence
# 2014 AKA MEDIA SYSTEM

from handlers.BaseHandler import BaseHandler
import logging
import datetime
from bson import json_util
import tornado
from tornado import gen
import ResponseObject
import requests
import groups

class FixtureHandler(BaseHandler):

    """Accept a file (CSV) with accelerometer samples in it"""
    def __init__(self, *args, **kwargs):
        BaseHandler.__init__(self,  *args, **kwargs)

    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def post(self):

        logging.debug('hit the fixture endpoint')
        if self.isAuth():
            logging.info('we are authenticated and ready to debug data')
            # timestamp = datetime.datetime.utcnow()
            logging.info(self.request.files['fixture_payload'][0]['body'])
            for line in self.request.files['fixture_payload'][0]['body'].split('\n'):
                entries = line.split(',')
                if len(entries) % 4 == 0: # sanity check to make sure we are dealing with a full deck, so to speak
                    self.process(entries)

            ''' here is an example line of payload:
            1398221223683,-5.5385894775390625,-0.2913665771484375,7.8047637939453125
            that is: UTC timestamp in millis, X, Y, and Z.
            X, Y, and Z are in meters per second per second, so when lying on a table, Z=-9.8
            so in general, each axis can vary from 11 to -11.
            Map this to the (0,255) range for RGB Neopixel values.

            for line in fixture_payload[0]['body']:
                vars = line.split(',')
                look at the timestamp, vars[0]
                if the timestamp is more than INTERVAL from last update sent:
                    # this means we have been motionless for longer than INTERVAL, so we should send (thisTimestamp-lastTimestamp)/INTERVAL duplicate updates
                    # so the neopixel reports the right amount of motionlessness
                    updateSpark(last_scaledX, last_scaledY, last_scaledZ)
                else:
                    # we are up-to-date, send this one out
                    scaledX = map(vars[0])
                    scaledY = map(vars[1])
                    scaledZ = map(vars[2])
                    updateSpark(scaledX, scaledY, scaledZ)
                    last_scaledX = map(vars[0])
                    last_scaledY = map(vars[1])
                    last_scaledZ = map(vars[2])
            '''
        else:
            self.write('Something is wack in FixtureHandler, self.isAuth wasnt True.')

    def mapVals(val, inMin, inMax, outMin, outMax):
        toRet = float(outMin + (float(outMax - outMin) * (float(val - inMin) / float(inMax - inMin))))
        # return clamp(toRet, outMin, outMax)
        return toRet

    def process(self, entries):
        logging.info(entries)
        l = len(entries)/4
        logging.info('there are %s entries to parse' % l)
        for i in reversed(range(l)):
            logging.info('i is %s' % i)
            # thisTime = entries[i*4-4]
            thisX = self.mapVals(entries[i*4-3], -11.0, 11.0, 0.0, 255)
            thisY = self.mapVals(entries[i*4-2], -11.0, 11.0, 0.0, 255)
            thisZ = self.mapVals(entries[i*4-1], -11.0, 11.0, 0.0, 255)
            logging.info('mapped x is %s' % thisX)
            logging.info('mapped y is %s' % thisY)
            logging.info('mapped z is %s' % thisZ)
            seq = (thisX, thisY, thisZ)
            toSend = ','.join(seq)
            logging.info('about to try to send %s ' % toSend)
            self.updateSpark(toSend)

    def updateSpark(self, textData):
        logging.info('trying to send the spark %s' % textData)
        payment = {'access_token':groups.keylist['spark_token'],'args':textData}
        url = groups.url
        q = requests.post(url,data=payment)
        logging.info(q.url)
        logging.info(q.text)
        logging.info(q.status_code)<commit_msg>simplifying spark core side of things because it is a dumb little guy<commit_after>#!/usr/bin/env python
# fixture - remote presence
# 2014 AKA MEDIA SYSTEM

from handlers.BaseHandler import BaseHandler
import logging
import datetime
from bson import json_util
import tornado
from tornado import gen
import ResponseObject
import requests
import groups

class FixtureHandler(BaseHandler):

    """Accept a file (CSV) with accelerometer samples in it"""
    def __init__(self, *args, **kwargs):
        BaseHandler.__init__(self,  *args, **kwargs)

    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def post(self):

        logging.debug('hit the fixture endpoint')
        if self.isAuth():
            logging.info('we are authenticated and ready to debug data')
            # timestamp = datetime.datetime.utcnow()
            logging.info(self.request.files['fixture_payload'][0]['body'])
            for line in self.request.files['fixture_payload'][0]['body'].split('\n'):
                entries = line.split(',')
                if len(entries) % 4 == 0: # sanity check to make sure we are dealing with a full deck, so to speak
                    self.process(entries)

            ''' here is an example line of payload:
            1398221223683,-5.5385894775390625,-0.2913665771484375,7.8047637939453125
            that is: UTC timestamp in millis, X, Y, and Z.
            X, Y, and Z are in meters per second per second, so when lying on a table, Z=-9.8
            so in general, each axis can vary from 11 to -11.
            Map this to the (0,255) range for RGB Neopixel values.

            for line in fixture_payload[0]['body']:
                vars = line.split(',')
                look at the timestamp, vars[0]
                if the timestamp is more than INTERVAL from last update sent:
                    # this means we have been motionless for longer than INTERVAL, so we should send (thisTimestamp-lastTimestamp)/INTERVAL duplicate updates
                    # so the neopixel reports the right amount of motionlessness
                    updateSpark(last_scaledX, last_scaledY, last_scaledZ)
                else:
                    # we are up-to-date, send this one out
                    scaledX = map(vars[0])
                    scaledY = map(vars[1])
                    scaledZ = map(vars[2])
                    updateSpark(scaledX, scaledY, scaledZ)
                    last_scaledX = map(vars[0])
                    last_scaledY = map(vars[1])
                    last_scaledZ = map(vars[2])
            '''
        else:
            self.write('Something is wack in FixtureHandler, self.isAuth wasnt True.')

    def mapVals(val, inMin, inMax, outMin, outMax):
        toRet = float(outMin + (float(outMax - outMin) * (float(val - inMin) / float(inMax - inMin))))
        # return clamp(toRet, outMin, outMax)
        return toRet

    def process(self, entries):
        logging.info(entries)
        l = len(entries)/4
        logging.info('there are %s entries to parse' % l)
        if l==1:
            thisX = self.mapVals(entries[1], -11.0, 11.0, 0, 255)
            thisX = self.mapVals(entries[1], -11.0, 11.0, 0, 255)
            thisX = self.mapVals(entries[1], -11.0, 11.0, 0, 255)
            logging.info('mapped x is %s' % thisX)
            logging.info('mapped y is %s' % thisY)
            logging.info('mapped z is %s' % thisZ)
            seq = (thisX, thisY, thisZ)
            toSend = ','.join(seq)
            logging.info('about to try to send %s ' % toSend)
            self.updateSpark(toSend)

        for i in reversed(range(l)):
            logging.info('i is %s' % i)
            # thisTime = entries[i*4-4]
            thisX = self.mapVals(entries[i*4-3], -11.0, 11.0, 0.0, 255)
            thisY = self.mapVals(entries[i*4-2], -11.0, 11.0, 0.0, 255)
            thisZ = self.mapVals(entries[i*4-1], -11.0, 11.0, 0.0, 255)
            logging.info('mapped x is %s' % thisX)
            logging.info('mapped y is %s' % thisY)
            logging.info('mapped z is %s' % thisZ)
            seq = (thisX, thisY, thisZ)
            toSend = ','.join(seq)
            logging.info('about to try to send %s ' % toSend)
            self.updateSpark(toSend)

    def updateSpark(self, textData):
        logging.info('trying to send the spark %s' % textData)
        payment = {'access_token':groups.keylist['spark_token'],'args':textData}
        url = groups.url
        q = requests.post(url,data=payment)
        logging.info(q.url)
        logging.info(q.text)
        logging.info(q.status_code)<|endoftext|>


<commit_before># Copyright Hybrid Logic Ltd.  See LICENSE file for details.
"""
Tools for running commands.
"""

<commit_msg>First pass at twisted process runner.<commit_after># Copyright Hybrid Logic Ltd.  See LICENSE file for details.
"""
Tools for running commands.
"""
import sys
import os

from characteristic import attributes

from twisted.internet.error import ConnectionDone
from twisted.internet.endpoints import ProcessEndpoint, connectProtocol
from twisted.internet.defer import Deferred

from twisted.protocols.basic import LineOnlyReceiver

@attributes([
    "deferred",
    "output",
])
class CommandProtocol(LineOnlyReceiver, object):
    """
    Protocol that logs the lines of a remote command.

    :ivar Deferred deferred: Deferred to fire when the command finishes
        If the command finished succesfuly, will fire with ``None``.
        Otherwise, errbacks with the reason.
    :ivar file-like output: For logging.
    """
    delimiter = b'\n'

    def connectionMade(self):
        self.transport.disconnecting = False

    def connectionLost(self, reason):
        if reason.check(ConnectionDone):
            self.deferred.callback(None)
        else:
            self.deferred.errback(reason)

    def lineReceived(self, line):
        self.output.write(line + "\n")

def run(reactor, command, **kwargs):
    endpoint = ProcessEndpoint(reactor, command[0], command, env=os.environ)
    protocol_done = Deferred()
    protocol = CommandProtocol(deferred=protocol_done, output=sys.stdout)

    connected = connectProtocol(endpoint, protocol)

    def unregister_killer(result, trigger_id):
        reactor.removeSystemEventTrigger(trigger_id)
        return result

    def register_killer(_):
        trigger_id = reactor.addSystemEventTrigger(
            'before', 'shutdown', protocol.transport.signalProcess, 'TERM')
        protocol_done.addBoth(unregister_killer, trigger_id)
        pass

    connected.addCallback(register_killer)
    connected.addCallback(lambda _: protocol_done)
    return connected
<|endoftext|>


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

import rospy
import time
from std_msgs.msg import Bool
from sub_trajectory.msg import StabilityMode
import smach, smach_ros
from diagnostic_msgs.msg import DiagnosticArray, DiagnosticStatus

import gate
import path
import dice
import slots

class StartState(smach.State):
	def __init__(self):
		smach.State.__init__(self, outcomes=['GO'])
		self.waiting = True
		rospy.Subscriber("/start", Bool, self.go)

	def go(self, msg):
		self.waiting = False

	def execute(self, userdata):
		while self.waiting and not self.preempt_requested():
			time.sleep(0.1)

		return 'GO'

class StopState(smach.State):
	def __init__(self):
		smach.State.__init__(self, outcomes=['DONE', 'RESTART'],
							input_keys=['depth'])
		self.stabilityPub = rospy.Publisher("/thrusters/depthMode", StabilityMode, queue_size=1)
		self.stabilityMsg = StabilityMode()
		self.waiting = True
		rospy.Subscriber("/start", Bool, self.button)

	def button(self, msg):
		self.waiting=False

	def execute(self, userdata):
		self.stabilityMsg.target.z=userdata.depth
		self.stabilityMsg.mode = StabilityMode.position
		self.stabilityPub.publish(self.stabilityMsg)

		while self.waiting and not self.preempt_requested():
			time.sleep(0.1)

		return 'RESTART'

class SafetyState(smach.State):
	def __init__(self):
		smach.State.__init__(self, outcomes=['ABORT', 'RECOVERED', 'PREEMPTED', 'ESTOP'])
		self.critError = False
		self.estop = False
		rospy.Subscriber("/leak", Bool, self.leakCb)
		rospy.Subscriber("/diagnostics", DiagnosticArray, self.depthStatus)

	def leakCb(self, msg):
		if msg.data:
			self.critError = True

	def depthStatus(self, msg):
		thrusterErrors = 0
		for status in msg.status:
			if status.name == 'DepthDisconnect':
				if status.message == 'true':
					self.critError = True
			elif 'Thruster_' in status.name and status.level != 0:
				thrusterErrors += 1
		if thrusterErrors > 7:
			self.estop = True
		elif thrusterErrors > 1:
			self.critError = True

	def execute(self, userdata):
		while not self.critError and not self.estop and not self.preempt_requested():
			time.sleep(0.1)

		if self.preempt_requested():
			return 'PREEMPTED'
		elif self.estop:
			return 'ESTOP'
		else:
			return 'ABORT'

def safetyWrap(task):
	def safety_outcome(outcome_map):
		if outcome_map['SAFETY'] != 'PREEMPTED':
			return outcome_map['SAFETY']
		else:
			return outcome_map["TASK"]

	def safety_term(outcome_map):
		return True

	safetyState = SafetyState()
	sm_wrapper = smach.Concurrence(list(task.get_registered_outcomes()) + ['ABORT', 'RECOVERED','ESTOP'],
									default_outcome='ABORT',
									outcome_cb=safety_outcome,
									child_termination_cb=safety_term)

	with sm_wrapper:
		smach.Concurrence.add("SAFETY", SafetyState())
		smach.Concurrence.add("TASK", task)

	return sm_wrapper

def main():
	rospy.init_node('hippo_sm')
	rospy.loginfo("State Machine has started.")

	mission_sm = smach.StateMachine(outcomes=['DONE'])
	mission_sm.userdata.abort_depth = -10
	mission_sm.userdata.stop_depth = 1

	with mission_sm:

		smach.StateMachine.add('START', safetyWrap(StartState()), transitions={'GO':'GATE', 'ABORT':'ABORT', 'RECOVERED': 'START', 'ESTOP': 'START'})

		task_gate = safetyWrap(gate.makeTask())
		task_path1 = safetyWrap(path.makeTask())
		task_dice = safetyWrap(dice.makeTask())
		task_path2 = safetyWrap(path.makeTask())
		task_slots = safetyWrap(slots.makeTask())

		smach.StateMachine.add('GATE', task_gate, transitions={'DONE':'PATH1', 'ABORT':'ABORT', 'RECOVERED':'GATE', 'ESTOP': 'START'})
		smach.StateMachine.add('PATH1', task_path1, transitions={'DONE':'DICE', 'ABORT':'ABORT', 'RECOVERED':'PATH1', 'ESTOP': 'START'})
		smach.StateMachine.add('DICE', task_dice, transitions={'DONE':'PATH2', 'ABORT':'ABORT', 'RECOVERED':'DICE', 'ESTOP': 'START'})
		smach.StateMachine.add('PATH2', task_path2, transitions={'DONE':'SLOTS', 'ABORT':'ABORT', 'RECOVERED':'PATH2', 'ESTOP': 'START'})
		smach.StateMachine.add('SLOTS', task_slots, transitions={'DONE':'STOP', 'ABORT':'ABORT', 'RECOVERED':'SLOTS', 'ESTOP': 'START'})

		smach.StateMachine.add('STOP', safetyWrap(StopState()), transitions={'RESTART':'START', 'DONE':'DONE', 'ABORT':'ABORT', 'RECOVERED':'STOP', 'ESTOP':'START'}, remapping={'depth':'stop_depth'})
		smach.StateMachine.add('ABORT', StopState(), transitions={'RESTART':'START', 'DONE':'DONE'}, remapping={'depth':'abort_depth'})

	sis = smach_ros.IntrospectionServer("sm_server", mission_sm, "/MISSION")
	sis.start()
	result = mission_sm.execute()
	rospy.loginfo(result)
	rospy.spin()
	sis.stop()

if __name__ == '__main__':
	main()
<commit_msg>Fixed premature preempts<commit_after>#!/usr/bin/env python

import rospy
import time
from std_msgs.msg import Bool
from sub_trajectory.msg import StabilityMode
import smach, smach_ros
from diagnostic_msgs.msg import DiagnosticArray, DiagnosticStatus

import gate
import path
import dice
import slots

class StartState(smach.State):
	def __init__(self):
		smach.State.__init__(self, outcomes=['GO', 'PREEMPTED'])
		self.waiting = True
		rospy.Subscriber("/start", Bool, self.go)

	def go(self, msg):
		self.waiting = False

	def execute(self, userdata):
		self.waiting = True
		while self.waiting and not self.preempt_requested():
			time.sleep(0.1)

		if self.preempt_requested():
			self.service_preempt()
			return 'PREEMPTED'

		return 'GO'

class StopState(smach.State):
	def __init__(self):
		smach.State.__init__(self, outcomes=['DONE', 'RESTART', 'PREEMPTED'],
							input_keys=['depth'])
		self.stabilityPub = rospy.Publisher("/thrusters/depthMode", StabilityMode, queue_size=1)
		self.stabilityMsg = StabilityMode()
		self.waiting = True
		rospy.Subscriber("/start", Bool, self.button)

	def button(self, msg):
		self.waiting=False

	def execute(self, userdata):
		self.waiting = True
		self.stabilityMsg.target.z=userdata.depth
		self.stabilityMsg.mode = StabilityMode.position
		self.stabilityPub.publish(self.stabilityMsg)

		while self.waiting and not self.preempt_requested():
			time.sleep(0.1)

		if self.preempt_requested():
			self.service_preempt()
			return 'PREEMPTED'

		return 'RESTART'

class SafetyState(smach.State):
	def __init__(self):
		smach.State.__init__(self, outcomes=['ABORT', 'RECOVERED', 'PREEMPTED', 'ESTOP'])
		self.critError = False
		self.estop = False
		rospy.Subscriber("/leak", Bool, self.leakCb)
		rospy.Subscriber("/diagnostics", DiagnosticArray, self.depthStatus)

	def leakCb(self, msg):
		if msg.data:
			self.critError = True

	def depthStatus(self, msg):
		self.estop = False
		thrusterErrors = 0
		for status in msg.status:
			if status.name == 'DepthDisconnect':
				if status.message == 'true':
					self.critError = True
			elif 'Thruster_' in status.name and status.level != 0:
				thrusterErrors += 1
		if thrusterErrors > 7:
			self.estop = True
			rospy.logwarn("ESTOP PROBABLY ON")
		elif thrusterErrors > 1:
			rospy.logwarn("THRUSTERS PROBABLY BUSTED")
			self.critError = True

	def execute(self, userdata):
		while not self.critError and not self.estop and not self.preempt_requested():
			time.sleep(0.1)

		if self.preempt_requested():
			self.service_preempt()
			return 'PREEMPTED'
		elif self.estop:
			self.estop = False
			return 'ESTOP'
		else:
			self.critError = False
			return 'ABORT'

def safetyWrap(task):
	def safety_outcome(outcome_map):
		rospy.logerr(outcome_map)
		if outcome_map['SAFETY'] != 'PREEMPTED':
			return outcome_map['SAFETY']
		elif outcome_map['TASK'] is not None:
			return outcome_map['TASK']
		else:
			return 'ABORT'

	def safety_term(outcome_map):
		return True

	safetyState = SafetyState()
	outcomes = list(task.get_registered_outcomes()) + list(safetyState.get_registered_outcomes())
	outcomes[:] = [x for x in outcomes if x != 'PREEMPTED']

	sm_wrapper = smach.Concurrence(outcomes,
					default_outcome='ABORT',
					outcome_cb=safety_outcome,
					child_termination_cb=safety_term)

	with sm_wrapper:
		smach.Concurrence.add("SAFETY", SafetyState())
		smach.Concurrence.add("TASK", task)

	return sm_wrapper

def main():
	rospy.init_node('hippo_sm')
	rospy.loginfo("State Machine has started.")

	mission_sm = smach.StateMachine(outcomes=['DONE'])
	mission_sm.userdata.abort_depth = -10
	mission_sm.userdata.stop_depth = 1

	with mission_sm:

		smach.StateMachine.add('START', safetyWrap(StartState()), transitions={'GO':'GATE', 'ABORT':'ABORT', 'RECOVERED': 'START', 'ESTOP': 'START'})

		task_gate = safetyWrap(gate.makeTask())
		task_path1 = safetyWrap(path.makeTask())
		task_dice = safetyWrap(dice.makeTask())
		task_path2 = safetyWrap(path.makeTask())
		task_slots = safetyWrap(slots.makeTask())

		smach.StateMachine.add('GATE', task_gate, transitions={'DONE':'STOP', 'ABORT':'ABORT', 'RECOVERED':'GATE', 'ESTOP': 'START'})
		smach.StateMachine.add('PATH1', task_path1, transitions={'DONE':'DICE', 'ABORT':'ABORT', 'RECOVERED':'PATH1', 'ESTOP': 'START'})
		smach.StateMachine.add('DICE', task_dice, transitions={'DONE':'PATH2', 'ABORT':'ABORT', 'RECOVERED':'DICE', 'ESTOP': 'START'})
		smach.StateMachine.add('PATH2', task_path2, transitions={'DONE':'SLOTS', 'ABORT':'ABORT', 'RECOVERED':'PATH2', 'ESTOP': 'START'})
		smach.StateMachine.add('SLOTS', task_slots, transitions={'DONE':'STOP', 'ABORT':'ABORT', 'RECOVERED':'SLOTS', 'ESTOP': 'START'})

		smach.StateMachine.add('STOP', safetyWrap(StopState()), transitions={'RESTART':'START', 'DONE':'DONE', 'ABORT':'ABORT', 'RECOVERED':'STOP', 'ESTOP':'START'}, remapping={'depth':'stop_depth'})
		smach.StateMachine.add('ABORT', StopState(), transitions={'RESTART':'START', 'DONE':'DONE', 'PREEMPTED':'DONE'}, remapping={'depth':'abort_depth'})

	sis = smach_ros.IntrospectionServer("sm_server", mission_sm, "/MISSION")
	sis.start()
	result = mission_sm.execute()
	rospy.loginfo(result)
	rospy.spin()
	sis.stop()

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