<commit_before>#!/usr/bin/env python
# coding=utf-8

# ROS node for publishing a /imu/data topic using the Adafruit BNO055 9DOF board.
#
# Based on Adafruits simpletest.py example.
# Author: Markus Knapp, 2017. https://direcs.de
#
#
# Copyright (c) 2015 Adafruit Industries
# Original-Author: Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import sys
import time

import rospy
import math

from std_msgs.msg import Header, Float32
from sensor_msgs.msg import Imu, Temperature

# see also http://wiki.ros.org/navigation/Tutorials/RobotSetup/Odom:
# "The nav_msgs/Odometry message stores an estimate of the position
#  and velocity of a robot in free space"
from nav_msgs.msg import Odometry

from Adafruit_BNO055 import BNO055

# sleep time for this node in seconds
sleepTime = 0.25

# initialise the node
rospy.init_node('bno055_node')

# Euler topics
pubH = rospy.Publisher('heading', Float32, queue_size=1)
pubR = rospy.Publisher('roll',    Float32, queue_size=1)
pubP = rospy.Publisher('pitch',   Float32, queue_size=1)
# Temperature
pubTemp = rospy.Publisher('temperature',   Temperature, queue_size=1)
# ROS IMU format messages
pubImu  = rospy.Publisher('imu/data', Imu, queue_size=1)

# header frame for odometry message
frame_id = 'odom' #
child_id = 'base_link' # normally the coordinate frame of the mobile base, so base_link.
seq = 0

# define temperature message
temp_msg = Temperature()
# ignore the covariance data, it is optional
temp_msg.variance = 0

# define IMU message
imu_msg = Imu()
# ignore the covariance data, it is optional
imu_msg.orientation_covariance[0]         = -1
imu_msg.angular_velocity_covariance[0]    = -1
imu_msg.linear_acceleration_covariance[0] = -1

# Create and configure the BNO sensor connection.
# Using I2C without a RST pin
bno = BNO055.BNO055()

# Initialize the BNO055 and stop if something went wrong.
if not bno.begin():
    rospy.logerr("Failed to initialize BNO055! Is the sensor connected?")

# Print system status
status, self_test, error = bno.get_system_status()
rospy.loginfo('System status:      0x{0:02X} '.format(status))

# Print self test
rospy.loginfo('Self test result:   0x{0:02X}'.format(self_test))
if self_test != 0x0F:
    rospy.logwarn('WARNING: Self test result is 0x{0:02X} instead if 0x0F!'.format(self_test))

# Print out an error if system status is in error mode.
if status == 0x01:
    rospy.logerr('System error:    {0}'.format(error))
    rospy.loginfo('See datasheet section 4.3.59 for the meaning.')

# Print BNO055 software revision and other diagnostic data.
sw, bl, accel, mag, gyro = bno.get_revision()
rospy.loginfo('Software version:   {0}'.format(sw))
rospy.loginfo('Bootloader version: {0}'.format(bl))
rospy.loginfo('Accelerometer ID:   0x{0:02X}'.format(accel))
rospy.loginfo('Magnetometer ID:    0x{0:02X}'.format(mag))
rospy.loginfo('Gyroscope ID:       0x{0:02X}\n'.format(gyro))

rospy.loginfo('Reading BNO055 data, press Ctrl-C to quit...')

while not rospy.is_shutdown():
    # define message header for IMU and temperature
    h = rospy.Header()
    h.stamp = rospy.Time.now()
    h.frame_id = frame_id  # "odom"
    h.seq = seq
    # increase sequence
    seq = seq + 1
    # add header to IMU message
    imu_msg.header = h

    # Read the Euler angles for heading, roll, pitch (all in degrees).
    heading, roll, pitch = bno.read_euler()

    # Read the calibration status, 0=uncalibrated and 3=fully calibrated.
    sys, gyro, accel, mag = bno.get_calibration_status()

    # Print everything out.
    # rospy.loginfo('Heading={0:0.2F} Roll={1:0.2F} Pitch={2:0.2F}\tSys_cal={3} Gyro_cal={4} Accel_cal={5} Mag_cal={6}'.format(heading, roll, pitch, sys, gyro, accel, mag))

    # publish Euler values
    pubH.publish(heading)
    pubR.publish(roll)
    pubP.publish(pitch)

    # Read orientation as a quaternion:
    x,y,z,w = bno.read_quaternion()
    imu_msg.orientation.x = x # is this the pose then?
    imu_msg.orientation.y = y
    imu_msg.orientation.z = z
    imu_msg.orientation.w = w
    # Print
    # rospy.loginfo('Quaternion: x={} y={} z={} w={}'.format(imu_msg.orientation.x, imu_msg.orientation.y, imu_msg.orientation.z, imu_msg.orientation.w))

    # Gyroscope data (in degrees per second):
    xg,yg,zg = bno.read_gyroscope()
    imu_msg.angular_velocity.x = xg;
    imu_msg.angular_velocity.y = yg;
    imu_msg.angular_velocity.z = zg;
    # Print
    rospy.loginfo('Gyroscope: x={} y={} z={}'.format(imu_msg.angular_velocity.x, imu_msg.angular_velocity.y, imu_msg.angular_velocity.z))

    # Accelerometer data (in meters per second squared):
    xa,ya,za = bno.read_accelerometer()
    imu_msg.linear_acceleration.x = xa;
    imu_msg.linear_acceleration.y = ya;
    imu_msg.linear_acceleration.z = za;
    # Print
    rospy.loginfo('Accelerometer: x={} y={} z={}'.format(imu_msg.linear_acceleration.x, imu_msg.linear_acceleration.y, imu_msg.linear_acceleration.z))

    # publish message
    pubImu.publish(imu_msg)

    # Read sensor temperature in degrees Celsius:
    temp = bno.read_temp()

    # Print
    # rospy.loginfo('Temperature: {}°C'.format(temp))

    # add header to temperature message
    temp_msg.header = h
    # publish message
    temp_msg.temperature = temp
    pubTemp.publish(temp_msg)

    # Other values you can optionally read:
    # Magnetometer data (in micro-Teslas):
    #x,y,z = bno.read_magnetometer()
    # Linear acceleration data (i.e. acceleration from movement, not gravity--
    # returned in meters per second squared):
    #x,y,z = bno.read_linear_acceleration()
    # Gravity acceleration data (i.e. acceleration just from gravity--returned
    # in meters per second squared):
    #x,y,z = bno.read_gravity()

    # Sleep for a second until the next reading.
    rospy.sleep(sleepTime)
<commit_msg>Added code for odomotry publisher and broadcaster<commit_after>#!/usr/bin/env python
# coding=utf-8

# ROS node for publishing a /imu/data topic using the Adafruit BNO055 9DOF board.
#
# Based on Adafruits simpletest.py example.
# Author: Markus Knapp, 2017. https://direcs.de
#
#
# Copyright (c) 2015 Adafruit Industries
# Original-Author: Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import sys
import time

import rospy
import math

from std_msgs.msg import Header, Float32
from sensor_msgs.msg import Imu, Temperature

# see also http://wiki.ros.org/navigation/Tutorials/RobotSetup/Odom:
# "The nav_msgs/Odometry message stores an estimate of the position
#  and velocity of a robot in free space"
from nav_msgs.msg import Odometry
# for the tf broadcaster
import tf

from Adafruit_BNO055 import BNO055

# sleep time for this node in seconds
sleepTime = 0.25

# initialise the node
rospy.init_node('bno055_node')

# the odometry topic
pubOdom = rospy.Publisher('odom', Odometry, queue_size=50)
# the tf broadcaster
# "any odometry source must publish information about the coordinate frame that it manages"
odomBroadcaster = tf.TransformBroadcaster() # "br" in tf_broadcaster.py

# Euler topics
pubH = rospy.Publisher('heading', Float32, queue_size=1)
pubR = rospy.Publisher('roll',    Float32, queue_size=1)
pubP = rospy.Publisher('pitch',   Float32, queue_size=1)
# Temperature
pubTemp = rospy.Publisher('temperature',   Temperature, queue_size=1)
# ROS IMU format messages
pubImu  = rospy.Publisher('imu/data', Imu, queue_size=1)

# header frame for odometry message
frame_id = 'odom' #
child_id = 'base_link' # normally the coordinate frame of the mobile base, so base_link.
seq = 0

# define temperature message
temp_msg = Temperature()
# ignore the covariance data, it is optional
temp_msg.variance = 0

# define IMU message
imu_msg = Imu()
# ignore the covariance data, it is optional
imu_msg.orientation_covariance[0]         = -1
imu_msg.angular_velocity_covariance[0]    = -1
imu_msg.linear_acceleration_covariance[0] = -1

# Create and configure the BNO sensor connection.
# Using I2C without a RST pin
bno = BNO055.BNO055()

# Initialize the BNO055 and stop if something went wrong.
if not bno.begin():
    rospy.logerr("Failed to initialize BNO055! Is the sensor connected?")

# Print system status
status, self_test, error = bno.get_system_status()
rospy.loginfo('System status:      0x{0:02X} '.format(status))

# Print self test
rospy.loginfo('Self test result:   0x{0:02X}'.format(self_test))
if self_test != 0x0F:
    rospy.logwarn('WARNING: Self test result is 0x{0:02X} instead if 0x0F!'.format(self_test))

# Print out an error if system status is in error mode.
if status == 0x01:
    rospy.logerr('System error:    {0}'.format(error))
    rospy.loginfo('See datasheet section 4.3.59 for the meaning.')

# Print BNO055 software revision and other diagnostic data.
sw, bl, accel, mag, gyro = bno.get_revision()
rospy.loginfo('Software version:   {0}'.format(sw))
rospy.loginfo('Bootloader version: {0}'.format(bl))
rospy.loginfo('Accelerometer ID:   0x{0:02X}'.format(accel))
rospy.loginfo('Magnetometer ID:    0x{0:02X}'.format(mag))
rospy.loginfo('Gyroscope ID:       0x{0:02X}\n'.format(gyro))

rospy.loginfo('Reading BNO055 data, press Ctrl-C to quit...')

while not rospy.is_shutdown():
    # define message header for IMU and temperature
    h = rospy.Header()
    h.stamp = rospy.Time.now()
    h.frame_id = frame_id  # "odom"
    h.seq = seq
    # increase sequence
    seq = seq + 1
    # add header to IMU message
    imu_msg.header = h

    # Read the Euler angles for heading, roll, pitch (all in degrees).
    heading, roll, pitch = bno.read_euler()

    # Read the calibration status, 0=uncalibrated and 3=fully calibrated.
    sys, gyro, accel, mag = bno.get_calibration_status()

    # Print everything out.
    # rospy.loginfo('Heading={0:0.2F} Roll={1:0.2F} Pitch={2:0.2F}\tSys_cal={3} Gyro_cal={4} Accel_cal={5} Mag_cal={6}'.format(heading, roll, pitch, sys, gyro, accel, mag))

    # publish Euler values
    pubH.publish(heading)
    pubR.publish(roll)
    pubP.publish(pitch)

    # Read orientation as a quaternion:
    x,y,z,w = bno.read_quaternion()
    imu_msg.orientation.x = x # is this the pose then?
    imu_msg.orientation.y = y
    imu_msg.orientation.z = z
    imu_msg.orientation.w = w
    # Print
    # rospy.loginfo('Quaternion: x={} y={} z={} w={}'.format(imu_msg.orientation.x, imu_msg.orientation.y, imu_msg.orientation.z, imu_msg.orientation.w))

    # Gyroscope data (in degrees per second):
    xg,yg,zg = bno.read_gyroscope()
    imu_msg.angular_velocity.x = xg;
    imu_msg.angular_velocity.y = yg;
    imu_msg.angular_velocity.z = zg;
    # Print
    rospy.loginfo('Gyroscope: x={} y={} z={}'.format(imu_msg.angular_velocity.x, imu_msg.angular_velocity.y, imu_msg.angular_velocity.z))

    # Accelerometer data (in meters per second squared):
    xa,ya,za = bno.read_accelerometer()
    imu_msg.linear_acceleration.x = xa;
    imu_msg.linear_acceleration.y = ya;
    imu_msg.linear_acceleration.z = za;
    # Print
    rospy.loginfo('Accelerometer: x={} y={} z={}'.format(imu_msg.linear_acceleration.x, imu_msg.linear_acceleration.y, imu_msg.linear_acceleration.z))

    # publish message
    pubImu.publish(imu_msg)

    # Read sensor temperature in degrees Celsius:
    temp = bno.read_temp()

    # Print
    # rospy.loginfo('Temperature: {}°C'.format(temp))

    # add header to temperature message
    temp_msg.header = h
    # publish message
    temp_msg.temperature = temp
    pubTemp.publish(temp_msg)

    # Other values you can optionally read:
    # Magnetometer data (in micro-Teslas):
    #x,y,z = bno.read_magnetometer()
    # Linear acceleration data (i.e. acceleration from movement, not gravity--
    # returned in meters per second squared):
    #x,y,z = bno.read_linear_acceleration()
    # Gravity acceleration data (i.e. acceleration just from gravity--returned
    # in meters per second squared):
    #x,y,z = bno.read_gravity()

    # Sleep for a second until the next reading.
    rospy.sleep(sleepTime)
<|endoftext|>


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

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = "1.0"

import sys
import os

from sphinx.ext.napoleon.docstring import NumpyDocstring

import sphinx_compas_theme

sys.path.insert(0, os.path.abspath("../src"))

# -- General configuration ------------------------------------------------

project = "COMPAS"
copyright = "Block Research Group - ETH Zurich"
author = "Tom Van Mele"

release = "0.16.8"
version = ".".join(release.split(".")[0:2])

master_doc = "index"
source_suffix = {
    ".rst": "restructuredtext",
    ".txt": "restructuredtext",
    ".md": "markdown",
}
templates_path = ["_templates", ]
exclude_patterns = ["_build", "**.ipynb_checkpoints", "_notebooks"]

pygments_style = "sphinx"
show_authors = True
add_module_names = True
language = None

# -- Extension configuration ------------------------------------------------

extensions = [
    "sphinx.ext.autodoc",
    "sphinx.ext.autosummary",
    "sphinx.ext.doctest",
    "sphinx.ext.intersphinx",
    "sphinx.ext.mathjax",
    "sphinx.ext.napoleon",
    "sphinx.ext.viewcode",
    "sphinx.ext.githubpages",
    "sphinx.ext.coverage",
    "matplotlib.sphinxext.plot_directive",
    "m2r",
    "nbsphinx",
]

# autodoc options

autodoc_mock_imports = [
    "System",
    "clr",
    "Eto",
    "Rhino",
    "Grasshopper",
    "scriptcontext",
    "rhinoscriptsyntax",
    "bpy",
    "bmesh",
    "mathutils"
]

autodoc_default_options = {
    "undoc-members": True,
    "show-inheritance": True,
}

autodoc_member_order = "groupwise"

autoclass_content = "class"

# autosummary options

autosummary_generate = True
autosummary_mock_imports = [
    "System",
    "clr",
    "Eto",
    "Rhino",
    "Grasshopper",
    "scriptcontext",
    "rhinoscriptsyntax",
    "bpy",
    "bmesh",
    "mathutils"
]

# napoleon options

napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = False
napoleon_use_rtype = False

# first, we define new methods for any new sections and add them to the class
def parse_keys_section(self, section):
    return self._format_fields("Keys", self._consume_fields())

NumpyDocstring._parse_keys_section = parse_keys_section

def parse_attributes_section(self, section):
    return self._format_fields("Attributes", self._consume_fields())

NumpyDocstring._parse_attributes_section = parse_attributes_section

def parse_class_attributes_section(self, section):
    return self._format_fields("Class Attributes", self._consume_fields())

NumpyDocstring._parse_class_attributes_section = parse_class_attributes_section

# we now patch the parse method to guarantee that the the above methods are
# assigned to the _section dict
def patched_parse(self):
    self._sections["keys"] = self._parse_keys_section
    self._sections["class attributes"] = self._parse_class_attributes_section
    self._unpatched_parse()

NumpyDocstring._unpatched_parse = NumpyDocstring._parse
NumpyDocstring._parse = patched_parse

# plot options

# plot_include_source
# plot_pre_code
# plot_basedir
# plot_formats
# plot_rcparams
# plot_apply_rcparams
# plot_working_directory

# {% has_class = false -%}
# {% for option in options -%}
# {% if option.startswith(":class:") %}
# {% has_class = true %}
# {% endif %}
# {% endfor %}

plot_template = """
{{ source_code }}

{{ only_html }}

   {% if source_link or (html_show_formats and not multi_image) %}
   (
   {%- if source_link -%}
   `Source code <{{ source_link }}>`__
   {%- endif -%}
   {%- if html_show_formats and not multi_image -%}
     {%- for img in images -%}
       {%- for fmt in img.formats -%}
         {%- if source_link or not loop.first -%}, {% endif -%}
         `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
       {%- endfor -%}
     {%- endfor -%}
   {%- endif -%}
   )
   {% endif %}

   {% for img in images %}
   {% set has_class = false %}

   .. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
      {% for option in options -%}
      {%- if option.startswith(":class:") -%}
      {%- set has_class = true -%}
      {%- if "img-fluid" not in option -%}
      {%- set option = option + " img-fluid" -%}
      {%- endif -%}
      {%- if "figure-img" not in option -%}
      {%- set option = option + " figure-img" -%}
      {%- endif -%}
      {%- endif -%}
      {{ option }}
      {% endfor %}
      {%- if not has_class -%}
      :class: figure-img img-fluid
      {%- endif %}

      {% if html_show_formats and multi_image -%}
        (
        {%- for fmt in img.formats -%}
        {%- if not loop.first -%}, {% endif -%}
        `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
        {%- endfor -%}
        )
      {%- endif -%}

      {{ caption }}
   {% endfor %}

{{ only_latex }}

   {% for img in images %}
   {% if "pdf" in img.formats -%}
   .. figure:: {{ build_dir }}/{{ img.basename }}.pdf
      {% for option in options -%}
      {{ option }}
      {% endfor %}

      {{ caption }}
   {% endif -%}
   {% endfor %}

{{ only_texinfo }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.png
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

"""

plot_html_show_source_link = False
plot_html_show_formats = False

# intersphinx options

intersphinx_mapping = {
    "python": ("https://docs.python.org/", None),
    "compas": ("https://compas-dev.github.io/compas", "https://compas-dev.github.io/compas/objects.inv"),
}

# -- Options for HTML output ----------------------------------------------

package_docs_root = "/compas/"

with open(os.path.join(os.path.dirname(__file__), "docversions.txt"), "r") as f:
    version_names = [version.strip() for version in f.readlines()]
    package_docs_versions = [(version, "{}{}".format(package_docs_root, version))
                             for version in version_names if version]

html_theme = "compas"
html_theme_path = sphinx_compas_theme.get_html_theme_path()
html_theme_options = {
    "navbar_active": "compas",
    "package_old_versions": package_docs_versions
}
html_context = {}
html_static_path = []
html_extra_path = [".nojekyll"]
html_last_updated_fmt = ""
html_copy_source = False
html_show_sourcelink = False
html_add_permalinks = ""
html_experimental_html5_writer = True
html_compact_lists = True
<commit_msg>don't parse txt as rst<commit_after># -*- coding: utf-8 -*-

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = "1.0"

import sys
import os

from sphinx.ext.napoleon.docstring import NumpyDocstring

import sphinx_compas_theme

sys.path.insert(0, os.path.abspath("../src"))

# -- General configuration ------------------------------------------------

project = "COMPAS"
copyright = "Block Research Group - ETH Zurich"
author = "Tom Van Mele"

release = "0.16.8"
version = ".".join(release.split(".")[0:2])

master_doc = "index"
source_suffix = {
    ".rst": "restructuredtext",
    ".md": "markdown",
}
templates_path = ["_templates", ]
exclude_patterns = ["_build", "**.ipynb_checkpoints", "_notebooks"]

pygments_style = "sphinx"
show_authors = True
add_module_names = True
language = None

# -- Extension configuration ------------------------------------------------

extensions = [
    "sphinx.ext.autodoc",
    "sphinx.ext.autosummary",
    "sphinx.ext.doctest",
    "sphinx.ext.intersphinx",
    "sphinx.ext.mathjax",
    "sphinx.ext.napoleon",
    "sphinx.ext.viewcode",
    "sphinx.ext.githubpages",
    "sphinx.ext.coverage",
    "matplotlib.sphinxext.plot_directive",
    "m2r",
    "nbsphinx",
]

# autodoc options

autodoc_mock_imports = [
    "System",
    "clr",
    "Eto",
    "Rhino",
    "Grasshopper",
    "scriptcontext",
    "rhinoscriptsyntax",
    "bpy",
    "bmesh",
    "mathutils"
]

autodoc_default_options = {
    "undoc-members": True,
    "show-inheritance": True,
}

autodoc_member_order = "groupwise"

autoclass_content = "class"

# autosummary options

autosummary_generate = True
autosummary_mock_imports = [
    "System",
    "clr",
    "Eto",
    "Rhino",
    "Grasshopper",
    "scriptcontext",
    "rhinoscriptsyntax",
    "bpy",
    "bmesh",
    "mathutils"
]

# napoleon options

napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = False
napoleon_use_rtype = False

# first, we define new methods for any new sections and add them to the class
def parse_keys_section(self, section):
    return self._format_fields("Keys", self._consume_fields())

NumpyDocstring._parse_keys_section = parse_keys_section

def parse_attributes_section(self, section):
    return self._format_fields("Attributes", self._consume_fields())

NumpyDocstring._parse_attributes_section = parse_attributes_section

def parse_class_attributes_section(self, section):
    return self._format_fields("Class Attributes", self._consume_fields())

NumpyDocstring._parse_class_attributes_section = parse_class_attributes_section

# we now patch the parse method to guarantee that the the above methods are
# assigned to the _section dict
def patched_parse(self):
    self._sections["keys"] = self._parse_keys_section
    self._sections["class attributes"] = self._parse_class_attributes_section
    self._unpatched_parse()

NumpyDocstring._unpatched_parse = NumpyDocstring._parse
NumpyDocstring._parse = patched_parse

# plot options

# plot_include_source
# plot_pre_code
# plot_basedir
# plot_formats
# plot_rcparams
# plot_apply_rcparams
# plot_working_directory

# {% has_class = false -%}
# {% for option in options -%}
# {% if option.startswith(":class:") %}
# {% has_class = true %}
# {% endif %}
# {% endfor %}

plot_template = """
{{ source_code }}

{{ only_html }}

   {% if source_link or (html_show_formats and not multi_image) %}
   (
   {%- if source_link -%}
   `Source code <{{ source_link }}>`__
   {%- endif -%}
   {%- if html_show_formats and not multi_image -%}
     {%- for img in images -%}
       {%- for fmt in img.formats -%}
         {%- if source_link or not loop.first -%}, {% endif -%}
         `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
       {%- endfor -%}
     {%- endfor -%}
   {%- endif -%}
   )
   {% endif %}

   {% for img in images %}
   {% set has_class = false %}

   .. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
      {% for option in options -%}
      {%- if option.startswith(":class:") -%}
      {%- set has_class = true -%}
      {%- if "img-fluid" not in option -%}
      {%- set option = option + " img-fluid" -%}
      {%- endif -%}
      {%- if "figure-img" not in option -%}
      {%- set option = option + " figure-img" -%}
      {%- endif -%}
      {%- endif -%}
      {{ option }}
      {% endfor %}
      {%- if not has_class -%}
      :class: figure-img img-fluid
      {%- endif %}

      {% if html_show_formats and multi_image -%}
        (
        {%- for fmt in img.formats -%}
        {%- if not loop.first -%}, {% endif -%}
        `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
        {%- endfor -%}
        )
      {%- endif -%}

      {{ caption }}
   {% endfor %}

{{ only_latex }}

   {% for img in images %}
   {% if "pdf" in img.formats -%}
   .. figure:: {{ build_dir }}/{{ img.basename }}.pdf
      {% for option in options -%}
      {{ option }}
      {% endfor %}

      {{ caption }}
   {% endif -%}
   {% endfor %}

{{ only_texinfo }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.png
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

"""

plot_html_show_source_link = False
plot_html_show_formats = False

# intersphinx options

intersphinx_mapping = {
    "python": ("https://docs.python.org/", None),
    "compas": ("https://compas-dev.github.io/compas", "https://compas-dev.github.io/compas/objects.inv"),
}

# -- Options for HTML output ----------------------------------------------

package_docs_root = "/compas/"

with open(os.path.join(os.path.dirname(__file__), "docversions.txt"), "r") as f:
    version_names = [version.strip() for version in f.readlines()]
    package_docs_versions = [(version, "{}{}".format(package_docs_root, version))
                             for version in version_names if version]

html_theme = "compas"
html_theme_path = sphinx_compas_theme.get_html_theme_path()
html_theme_options = {
    "navbar_active": "compas",
    "package_old_versions": package_docs_versions
}
html_context = {}
html_static_path = []
html_extra_path = [".nojekyll"]
html_last_updated_fmt = ""
html_copy_source = False
html_show_sourcelink = False
html_add_permalinks = ""
html_experimental_html5_writer = True
html_compact_lists = True
<|endoftext|>


<commit_before><commit_msg>Removed actions package.<commit_after><|endoftext|>


<commit_before># Django settings for globalizr project.
import os.path

PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    ('Oscar Bezi', 'oscar.bezi@gmail.com'),
    ('Sinan Cepel', 'cepel.sinan@gmail.com'),
    ('Andre Jia', 'ajia.117@gmail.com'),
    ('Jake Zimmerman', 'jake.zimmerman@gmail.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        # The following settings are not used with sqlite3:
        'USER': '',
        'PASSWORD': '',
        'HOST': '',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': '',                      # Set to empty string for default.
    }
}

# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/New_York'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''

# Additional locations of static files
STATICFILES_DIRS = (
    'static',
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = 'e36k*^_&uy4-azm0%06$4rnb%(36x=6y&%j@o)tsi!74$zv(*j'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'globalizr.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'globalizr.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(PROJECT_PATH, 'templates'),
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}
<commit_msg>Turned off debug.<commit_after># Django settings for globalizr project.
import os.path

PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'

DEBUG = False
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    ('Oscar Bezi', 'oscar.bezi@gmail.com'),
    ('Sinan Cepel', 'cepel.sinan@gmail.com'),
    ('Andre Jia', 'ajia.117@gmail.com'),
    ('Jake Zimmerman', 'jake.zimmerman@gmail.com'),
)

MANAGERS = ADMINS

# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ["globalizr.org", "globalizr.herokuapp.com", "localhost"]

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/New_York'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''

# Additional locations of static files
STATICFILES_DIRS = (
    'static',
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = 'e36k*^_&uy4-azm0%06$4rnb%(36x=6y&%j@o)tsi!74$zv(*j'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'globalizr.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'globalizr.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(PROJECT_PATH, 'templates'),
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}
<|endoftext|>


<commit_before>import numpy as np
from itertools import permutations

# Finds maximum value in a dict, returns key
def find_dict_max(some_dict):
    max_key = []
    max_val = -np.inf

    for k in some_dict.keys():
        if some_dict[k] > max_val:
            max_val = some_dict[k]
            max_key = k

    return max_key

# Finds minimum value in a dict, returns key
def find_dict_min(some_dict):
    min_key = []
    min_val = np.inf

    for k in some_dict.keys():
        if some_dict[k] < min_val:
            min_val = some_dict[k]
            min_key = k

    return min_key

# Returns list of keys in dict, ordered in terms of values
def sort_dict(some_dict, direction='ascending'):
    some_dict = some_dict.copy()

    if direction == 'ascending':
        find_next = find_dict_min
        reset = np.inf
    elif direction == 'descending':
        find_next = find_dict_max
        reset = -np.inf
    else:
        print("Please specify 'ascending' or 'descending'")
        return 0

    ordering = []
    for i in range(len(some_dict.keys())):
        key = find_next(some_dict)
        ordering.append(key)
        some_dict[key] = reset

    return ordering

# Voting Functions
def safe_copy(profile):
    prof = []
    for voter in profile[:]:
        temp = []
        for cand in voter[:]:
            temp.append(cand)
        prof.append(temp)

    return prof

def remove_candidate(profile, candidate):
    # Remove from profiles
    for voter in profile:
        voter.remove(candidate)

def plurality(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)

    # Count votes
    for voter in profile:
        candidates[voter[0]] += 1

    # Return winner
    social_preference = sort_dict(candidates, 'descending')

    return social_preference, candidates

def veto(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)

    # Count vetos
    for voter in profile:
        candidates[voter[-1]] += 1

    # Return winner
    social_preference = sort_dict(candidates, 'ascending')

    return social_preference, candidates

def borda(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)

    # Count score
    for voter in profile:
        for idx, cand in enumerate(voter):
            candidates[cand] += idx

    # Return winner
    social_preference = sort_dict(candidates, 'ascending')

    return social_preference, candidates

def copeland(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)
    all_names = list(candidates.keys())
    m = len(all_names)

    # Compare every pair of candidates
    for i in range(m):
        for j in range(i+1, m):
            # Find list of names for new profile
            names = profile[0][:]
            names.remove(all_names[i])
            names.remove(all_names[j])

            # Make the new profile
            prof = safe_copy(profile)
            for name in names:
                remove_candidate(prof, name)

            # Find winner
            sp, _ = plurality(prof)

            # Tally candidate wins/losses
            candidates[sp[0]] += 1
            candidates[sp[1]] -= 1

    social_preference = sort_dict(candidates, 'descending')

    return social_preference, candidates

def irv(profile):

    # Make new profile for safety
    prof = safe_copy(profile)

    # Get number of voters, alternatives
    m = len(prof[0])

    res = []
    sp = [0]
    social_preference = []
    while m > 1:
        # Find the loser
        sp, sc = plurality(prof)
        res.append(sc)
        social_preference.append(sp[-1])

        # Remove the loser from profiles
        remove_candidate(prof, sp[-1])

        # Get number of voters, alternatives
        m = len(prof[0])

    social_preference.append(sp[0])
    social_preference.reverse()

    return social_preference, res

RULES = [plurality, veto, borda, irv, copeland]

# Preference Profile
class PreferenceProfile(object):

    def __init__(self):
        # Don't do very much
        self.n = 0
        self.m = 0
        self.names = []
        self.profile = []
        self.prob = []

    def make_random_profile(self, n, m):
        # Store characteristics
        self.m = m
        self.n = n

        # Make list of names
        self.names = [format(i, '02d') for i in range(self.m)]

        # Get the profile
        self.profile = []
        for i in range(self.n):
            xn = self.names[:]
            np.random.shuffle(xn)
            self.profile.append(xn)

        # Make the probability comparison matrix
        self.prob = np.zeros([self.m, self.m])
        for voter in self.profile:
            for i, name1 in enumerate(self.names):
                for j, name2 in enumerate(self.names):
                    if voter.index(name1) > voter.index(name2):
                        self.prob[i, j] += 1.0

        self.prob /= len(self.profile)

    def set_profile(self, profile):
        # Store profile and characteristics
        self.profile = profile
        self.m = len(profile[0])
        self.n = len(profile)

        # Make list of names
        self.names = np.unique(profile[0])

        # Make the probability comparison matrix
        self.prob = np.zeros([self.m, self.m])
        for voter in self.profile:
            for i, name1 in enumerate(self.names):
                for j, name2 in enumerate(self.names):
                    if voter.index(name1) > voter.index(name2):
                        self.prob[i, j] += 1.0

        self.prob /= len(self.profile)

    def strategyproof(self, rule):
        # Check ranking as is
        sp, sc = rule(self.profile)
        winner = sp[0]

        # Create all permutations
        options = permutations(self.names)

        # Check all strategies
        for i in range(self.n):
            if self.profile[i][0] != winner:
                prof = safe_copy(self.profile)
                for strategy in options:
                    prof[i] = list(strategy)
                    sp, sc = rule(prof)
                    if self.profile[i].index(sp[0]) < \
                            self.profile[i].index(winner):
                        return False
        else:
            return True

    def unanimity(self, rule):
        # Check ranking as is
        sp, _ = rule(self.profile)

        for i, name1 in enumerate(self.names):
            for j, name2 in enumerate(self.names):
                if self.prob[i, j] == 1.0:
                    if sp.index(name1) < sp.index(name2):
                        return False
        else:
            return True<commit_msg>3.4 compatibility<commit_after>import numpy as np
from itertools import permutations

# Finds maximum value in a dict, returns key
def find_dict_max(some_dict):
    max_key = []
    max_val = -np.inf

    for k in sorted(some_dict.keys()):
        if some_dict[k] > max_val:
            max_val = some_dict[k]
            max_key = k

    return max_key

# Finds minimum value in a dict, returns key
def find_dict_min(some_dict):
    min_key = []
    min_val = np.inf

    for k in sorted(some_dict.keys()):
        if some_dict[k] < min_val:
            min_val = some_dict[k]
            min_key = k

    return min_key

# Returns list of keys in dict, ordered in terms of values
def sort_dict(some_dict, direction='ascending'):
    some_dict = some_dict.copy()

    if direction == 'ascending':
        find_next = find_dict_min
        reset = np.inf
    elif direction == 'descending':
        find_next = find_dict_max
        reset = -np.inf
    else:
        print("Please specify 'ascending' or 'descending'")
        return 0

    ordering = []
    for i in range(len(some_dict.keys())):
        key = find_next(some_dict)
        ordering.append(key)
        some_dict[key] = reset

    return ordering

# Voting Functions
def safe_copy(profile):
    prof = []
    for voter in profile[:]:
        temp = []
        for cand in voter[:]:
            temp.append(cand)
        prof.append(temp)

    return prof

def remove_candidate(profile, candidate):
    # Remove from profiles
    for voter in profile:
        voter.remove(candidate)

def plurality(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)

    # Count votes
    for voter in profile:
        candidates[voter[0]] += 1

    # Return winner
    social_preference = sort_dict(candidates, 'descending')

    return social_preference, candidates

def veto(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)

    # Count vetos
    for voter in profile:
        candidates[voter[-1]] += 1

    # Return winner
    social_preference = sort_dict(candidates, 'ascending')

    return social_preference, candidates

def borda(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)

    # Count score
    for voter in profile:
        for idx, cand in enumerate(voter):
            candidates[cand] += idx

    # Return winner
    social_preference = sort_dict(candidates, 'ascending')

    return social_preference, candidates

def copeland(profile):
    # Make dictionary
    candidates = dict.fromkeys(list(np.unique(profile[0])), 0)
    all_names = list(candidates.keys())
    m = len(all_names)

    # Compare every pair of candidates
    for i in range(m):
        for j in range(i+1, m):
            # Find list of names for new profile
            names = profile[0][:]
            names.remove(all_names[i])
            names.remove(all_names[j])

            # Make the new profile
            prof = safe_copy(profile)
            for name in names:
                remove_candidate(prof, name)

            # Find winner
            sp, _ = plurality(prof)

            # Tally candidate wins/losses
            candidates[sp[0]] += 1
            candidates[sp[1]] -= 1

    social_preference = sort_dict(candidates, 'descending')

    return social_preference, candidates

def irv(profile):

    # Make new profile for safety
    prof = safe_copy(profile)

    # Get number of voters, alternatives
    m = len(prof[0])

    res = []
    sp = [0]
    social_preference = []
    while m > 1:
        # Find the loser
        sp, sc = plurality(prof)
        res.append(sc)
        social_preference.append(sp[-1])

        # Remove the loser from profiles
        remove_candidate(prof, sp[-1])

        # Get number of voters, alternatives
        m = len(prof[0])

    social_preference.append(sp[0])
    social_preference.reverse()

    return social_preference, res

RULES = [plurality, veto, borda, irv, copeland]

# Preference Profile
class PreferenceProfile(object):

    def __init__(self):
        # Don't do very much
        self.n = 0
        self.m = 0
        self.names = []
        self.profile = []
        self.prob = []

    def make_random_profile(self, n, m):
        # Store characteristics
        self.m = m
        self.n = n

        # Make list of names
        self.names = [format(i, '02d') for i in range(self.m)]

        # Get the profile
        self.profile = []
        for i in range(self.n):
            xn = self.names[:]
            np.random.shuffle(xn)
            self.profile.append(xn)

        # Make the probability comparison matrix
        self.prob = np.zeros([self.m, self.m])
        for voter in self.profile:
            for i, name1 in enumerate(self.names):
                for j, name2 in enumerate(self.names):
                    if voter.index(name1) > voter.index(name2):
                        self.prob[i, j] += 1.0

        self.prob /= len(self.profile)

    def set_profile(self, profile):
        # Store profile and characteristics
        self.profile = profile
        self.m = len(profile[0])
        self.n = len(profile)

        # Make list of names
        self.names = np.unique(profile[0])

        # Make the probability comparison matrix
        self.prob = np.zeros([self.m, self.m])
        for voter in self.profile:
            for i, name1 in enumerate(self.names):
                for j, name2 in enumerate(self.names):
                    if voter.index(name1) > voter.index(name2):
                        self.prob[i, j] += 1.0

        self.prob /= len(self.profile)

    def strategyproof(self, rule):
        # Check ranking as is
        sp, sc = rule(self.profile)
        winner = sp[0]

        # Create all permutations
        options = permutations(self.names)

        # Check all strategies
        for i in range(self.n):
            if self.profile[i][0] != winner:
                prof = safe_copy(self.profile)
                for strategy in options:
                    prof[i] = list(strategy)
                    sp, sc = rule(prof)
                    if self.profile[i].index(sp[0]) < \
                            self.profile[i].index(winner):
                        return False
        else:
            return True

    def unanimity(self, rule):
        # Check ranking as is
        sp, _ = rule(self.profile)

        for i, name1 in enumerate(self.names):
            for j, name2 in enumerate(self.names):
                if self.prob[i, j] == 1.0:
                    if sp.index(name1) < sp.index(name2):
                        return False
        else:
            return True<|endoftext|>


<commit_before>import shelve
import os
from support_team import SupportTeam

class Database:

    def query_db(self, callable):
        directory = os.path.dirname(os.path.abspath(__file__))
        db = shelve.open(directory + "/../../database/database")
        result = callable(db)
        db.close()
        return result

    def assign_to_db(self, key, callable):
        directory = os.path.dirname(os.path.abspath(__file__))
        db = shelve.open(directory + "/../../database/database")
        db[key] = callable(db)
        db.close()

    def has_key(self, key):
        return self.query_db(lambda db: db.has_key(key))

    def keys(self):
        return self.query_db(lambda db: db.keys())

    def save(self, key, status):
        self.assign_to_db(key, lambda db: status)

    def retrieve(self, key):
        return self.query_db(lambda db: db[key])

    def __str__(self):
        def to_str(db):
            output = "database contents:\n"
            keys = db.keys()

            for key in keys:
                if "latest-media" == key:
                    output += "   %s: %s\n" % (key, db[key])
                else:
                    output += "   %s: %s\n" % (key, db[key]["status"])

            return output

        return self.query_db(to_str)
<commit_msg>removed the printing knowledge out of the database<commit_after>import shelve
import os
from support_team import SupportTeam

class Database:

    def query_db(self, callable):
        directory = os.path.dirname(os.path.abspath(__file__))
        db = shelve.open(directory + "/../../database/database")
        result = callable(db)
        db.close()
        return result

    def assign_to_db(self, key, callable):
        directory = os.path.dirname(os.path.abspath(__file__))
        db = shelve.open(directory + "/../../database/database")
        db[key] = callable(db)
        db.close()

    def has_key(self, key):
        return self.query_db(lambda db: db.has_key(key))

    def keys(self):
        return self.query_db(lambda db: db.keys())

    def save(self, key, status):
        self.assign_to_db(key, lambda db: status)

    def retrieve(self, key):
        return self.query_db(lambda db: db[key])

    def __str__(self):
        def to_str(db):
            output = "database contents:\n"
            keys = db.keys()

            for key in keys:
                output += "   %s: %s\n" % (key, db[key])

            return output

        return self.query_db(to_str)
<|endoftext|>


<commit_before>#!/usr/bin/env python
import os
import getopt
from saml2 import utils, md, samlp, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
from saml2 import BINDING_SOAP, class_name
from saml2.time_util import in_a_while
from saml2.utils import parse_attribute_map
from saml2.saml import NAME_FORMAT_URI
from saml2.sigver import pre_signature_part, sign_statement_using_xmlsec

HELP_MESSAGE = """
Usage: make_metadata [options] 1*configurationfile

Valid options:
hi:k:sv:x:
  -h            : Print this help message
  -i id         : The ID of the entities descriptor
  -k keyfile    : A file with a key to sign the metadata with
  -s            : sign the metadta
  -v            : How long, in days, the metadata is valid from the
                    time of creation
  -x            : xmlsec1 binaries to be used for the signing
"""

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

def do_sp_sso_descriptor(sp, cert, backward_map):
    desc = {
        "protocol_support_enumeration": samlp.NAMESPACE,
        "want_assertions_signed": True,
        "authn_requests_signed": False,
        "assertion_consumer_service": {
            "binding": BINDING_HTTP_POST ,
            "location": sp["url"],
            "index": 0,
            },
        "key_descriptor":{
            "key_info": {
                "x509_data": {
                    "x509_certificate": cert
                    }
                }
            },
        }

    requested_attribute = []
    if "required_attributes" in sp:
        for attr in sp["required_attributes"]:
            try:
                requested_attribute.append({
                    "is_required": "true",
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": backward_map[attr]
                })
            except KeyError:
                requested_attribute.append({
                    "is_required": "true",
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": attr
                })

    if "optional_attributes" in sp:
        for attr in sp["optional_attributes"]:
            try:
                requested_attribute.append({
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": backward_map[attr]
                })
            except KeyError:
                requested_attribute.append({
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": attr
                })

    if requested_attribute:
        desc["attribute_consuming_service"] = {
            "requested_attribute": requested_attribute,
            "service_name": {
                "lang":"en",
                "text":sp["name"],
            }
        }

    return desc

def do_idp_sso_descriptor(idp, cert):
    return {
        "protocol_support_enumeration": samlp.NAMESPACE,
        "want_authn_requests_signed": True,
        "single_sign_on_service": {
            "binding": BINDING_HTTP_REDIRECT ,
            "location": idp["url"],
            },
        "key_descriptor":{
            "key_info": {
                "x509_data": {
                    "x509_certificate": cert
                    }
                }
            },
        }

def do_aa_descriptor(aa, cert):
    return {
        "protocol_support_enumeration": samlp.NAMESPACE,
        "attribute_service": {
            "binding": BINDING_SOAP ,
            "location": aa["url"],
            },
        "key_descriptor":{
            "key_info": {
                "x509_data": {
                    "x509_certificate": cert
                    }
                }
            },
        }

def entity_descriptor(confd, valid_for):
    mycert = "".join(open(confd["cert_file"]).readlines()[1:-1])

    if "attribute_maps" in confd:
        (forward,backward) = parse_attribute_map(confd["attribute_maps"])
    else:
        backward = {}

    ed = {
        "entity_id": confd["entityid"],
    }
    if valid_for:
        ed["valid_until"] = in_a_while(hours=valid_for)

    if "organization" in confd:
        org = {}
        for prop in ["name","display_name","url"]:
            if prop in confd["organization"]:
                org["organization_%s" % prop] = confd["organization"][prop]
        ed["organization"] = org

    if "contact" in confd:
        contacts = []
        for dic in confd["contact"]:
            cont = {}
            for prop in ["given_name","sur_name","email_address",
                        "contact_type","company","telephone_number"]:
                if prop in dic:
                    cont[prop] = dic[prop]
            contacts.append(cont)
        ed["contact_person"] = contacts

    if "sp" in confd["service"]:
        # The SP
        ed["sp_sso_descriptor"] = do_sp_sso_descriptor(confd["service"]["sp"],
                                    mycert, backward)
    if "idp" in confd["service"]:
        ed["idp_sso_descriptor"] = do_idp_sso_descriptor(
                                            confd["service"]["idp"], mycert)
    if "aa" in confd["service"]:
        ed["attribute_authority_descriptor"] = do_aa_descriptor(
                                            confd["service"]["aa"], mycert)

    return ed

def entities_descriptor(eds, valid_for, name, id, sign, xmlsec, keyfile):
    d = {"entity_descriptor": eds}
    if valid_for:
        d["valid_until"] = in_a_while(hours=valid_for)
    if name:
        d["name"] = name
    if id:
        d["id"] = id

    if sign:
            d["signature"] = pre_signature_part(d["id"])

    statement = utils.make_instance(md.EntitiesDescriptor, d)
    if sign:
            statement = sign_statement_using_xmlsec("%s" % statement,
                                    class_name(statement),
                                    xmlsec, key_file=keyfile)
    return statement

def main(args):
    try:
        opts, args = getopt.getopt(args, "hi:k:sv:x:",
                        ["help", "name", "id", "keyfile", "sign",
                        "valid", "xmlsec"])
    except getopt.GetoptError, err:
        # print help information and exit:
        raise Usage(err) # will print something like "option -a not recognized"
        sys.exit(2)

    output = None
    verbose = False
    valid_for = 0
    name = ""
    id = ""
    sign = False
    xmlsec = ""
    keyfile = ""

    try:
        for o, a in opts:
            if o in ("-v", "--valid"):
                valid_for = int(a) * 24
            elif o in ("-h", "--help"):
                raise Usage(HELP_MESSAGE)
            elif o in ("-n", "--name"):
                name = a
            elif o in ("-i", "--id"):
                id = a
            elif o in ("-s", "--sign"):
                sign = True
            elif o in ("-x", "--xmlsec"):
                xmlsec = a
            elif o in ("-k", "--keyfile"):
                keyfile = a
            else:
                assert False, "unhandled option %s" % o
    except Usage, err:
        print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
        print >> sys.stderr, "\t for help use --help"
        return 2

    eds = []
    for conf in args:
        confd = eval(open(conf).read())
        eds.append(entity_descriptor(confd, valid_for))
    print entities_descriptor(eds, valid_for, name, id, sign, xmlsec, keyfile)

if __name__ == "__main__":
    import sys

    main(sys.argv[1:])
<commit_msg>added support for organization and contact person information<commit_after>#!/usr/bin/env python
import os
import getopt
from saml2 import utils, md, samlp, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
from saml2 import BINDING_SOAP, class_name
from saml2.time_util import in_a_while
from saml2.utils import parse_attribute_map
from saml2.saml import NAME_FORMAT_URI
from saml2.sigver import pre_signature_part, sign_statement_using_xmlsec

HELP_MESSAGE = """
Usage: make_metadata [options] 1*configurationfile

Valid options:
hi:k:sv:x:
  -h            : Print this help message
  -i id         : The ID of the entities descriptor
  -k keyfile    : A file with a key to sign the metadata with
  -s            : sign the metadta
  -v            : How long, in days, the metadata is valid from the
                    time of creation
  -x            : xmlsec1 binaries to be used for the signing
"""

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

DEFAULTS = {
    "want_assertions_signed": "true",
    "authn_requests_signed": "false",
}

ORG_ATTR_TRANSL = {
    "organization_name": "name",
    "organization_display_name": "display_name",
    "organization_url": "url",
}

PERSON_ATTR_TRANSL = {
    "company": "company",
    "given_name": "givenname",
    "sur_name": "surname",
    "email_address": "mail",
    "telephone_number": "phone",
}

def do_organization_info(conf, desc):
    try:
        corg =  conf["organization"]
        dorg = desc["organization"] = {}

        for (dkey, ckey) in ORG_ATTR_TRANSL.items():
            try:
                dorg[dkey] = corg[ckey]
            except KeyError:
                pass
    except KeyError:
        pass

def do_contact_person_info(conf, desc):
    try:
        corg =  conf["contact_person"]
        dorg = desc["contact_person"] = {}

        for (dkey, ckey) in PERSON_ATTR_TRANSL.items():
            try:
                dorg[dkey] = corg[ckey]
            except:
                pass
    except KeyError:
        pass

def do_sp_sso_descriptor(sp, cert, backward_map):
    desc = {
        "protocol_support_enumeration": samlp.NAMESPACE,
        "assertion_consumer_service": {
            "binding": BINDING_HTTP_POST ,
            "location": sp["url"],
            "index": 0,
            },
        "key_descriptor":{
            "key_info": {
                "x509_data": {
                    "x509_certificate": cert
                    }
                }
            },
        }

    for key in ["want_assertions_signed", "authn_requests_signed"]:
        try:
            desc[key] = "%s" % sp[key]
        except KeyError:
            desc[key] = DEFAULTS[key]

    requested_attribute = []
    if "required_attributes" in sp:
        for attr in sp["required_attributes"]:
            try:
                requested_attribute.append({
                    "is_required": "true",
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": backward_map[attr]
                })
            except KeyError:
                requested_attribute.append({
                    "is_required": "true",
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": attr
                })

    if "optional_attributes" in sp:
        for attr in sp["optional_attributes"]:
            try:
                requested_attribute.append({
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": backward_map[attr]
                })
            except KeyError:
                requested_attribute.append({
                    "friendly_name": attr,
                    "name_format": NAME_FORMAT_URI,
                    "name": attr
                })

    if requested_attribute:
        desc["attribute_consuming_service"] = {
            "requested_attribute": requested_attribute,
            "service_name": {
                "lang":"en",
                "text":sp["name"],
            }
        }

    return desc

def do_idp_sso_descriptor(idp, cert):
    return {
        "protocol_support_enumeration": samlp.NAMESPACE,
        "want_authn_requests_signed": True,
        "single_sign_on_service": {
            "binding": BINDING_HTTP_REDIRECT ,
            "location": idp["url"],
            },
        "key_descriptor":{
            "key_info": {
                "x509_data": {
                    "x509_certificate": cert
                    }
                }
            },
        }

def do_aa_descriptor(aa, cert):
    return {
        "protocol_support_enumeration": samlp.NAMESPACE,
        "attribute_service": {
            "binding": BINDING_SOAP ,
            "location": aa["url"],
            },
        "key_descriptor":{
            "key_info": {
                "x509_data": {
                    "x509_certificate": cert
                    }
                }
            },
        }

def entity_descriptor(confd, valid_for):
    mycert = "".join(open(confd["cert_file"]).readlines()[1:-1])

    if "attribute_maps" in confd:
        (forward,backward) = parse_attribute_map(confd["attribute_maps"])
    else:
        backward = {}

    ed = {
        "entity_id": confd["entityid"],
    }
    if valid_for:
        ed["valid_until"] = in_a_while(hours=valid_for)

    do_organization_info(confd, ed)
    do_contact_person_info(confd, ed)

    if "sp" in confd["service"]:
        # The SP
        ed["sp_sso_descriptor"] = do_sp_sso_descriptor(confd["service"]["sp"],
                                    mycert, backward)
    if "idp" in confd["service"]:
        ed["idp_sso_descriptor"] = do_idp_sso_descriptor(
                                            confd["service"]["idp"], mycert)
    if "aa" in confd["service"]:
        ed["attribute_authority_descriptor"] = do_aa_descriptor(
                                            confd["service"]["aa"], mycert)

    return ed

def entities_descriptor(eds, valid_for, name, id, sign, xmlsec, keyfile):
    d = {"entity_descriptor": eds}
    if valid_for:
        d["valid_until"] = in_a_while(hours=valid_for)
    if name:
        d["name"] = name
    if id:
        d["id"] = id

    if sign:
            d["signature"] = pre_signature_part(d["id"])

    statement = utils.make_instance(md.EntitiesDescriptor, d)
    if sign:
            statement = sign_statement_using_xmlsec("%s" % statement,
                                    class_name(statement),
                                    xmlsec, key_file=keyfile)
    return statement

def main(args):
    try:
        opts, args = getopt.getopt(args, "hi:k:sv:x:",
                        ["help", "name", "id", "keyfile", "sign",
                        "valid", "xmlsec"])
    except getopt.GetoptError, err:
        # print help information and exit:
        raise Usage(err) # will print something like "option -a not recognized"
        sys.exit(2)

    output = None
    verbose = False
    valid_for = 0
    name = ""
    id = ""
    sign = False
    xmlsec = ""
    keyfile = ""

    try:
        for o, a in opts:
            if o in ("-v", "--valid"):
                valid_for = int(a) * 24
            elif o in ("-h", "--help"):
                raise Usage(HELP_MESSAGE)
            elif o in ("-n", "--name"):
                name = a
            elif o in ("-i", "--id"):
                id = a
            elif o in ("-s", "--sign"):
                sign = True
            elif o in ("-x", "--xmlsec"):
                xmlsec = a
            elif o in ("-k", "--keyfile"):
                keyfile = a
            else:
                assert False, "unhandled option %s" % o
    except Usage, err:
        print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
        print >> sys.stderr, "\t for help use --help"
        return 2

    eds = []
    for conf in args:
        confd = eval(open(conf).read())
        eds.append(entity_descriptor(confd, valid_for))
    print entities_descriptor(eds, valid_for, name, id, sign, xmlsec, keyfile)

if __name__ == "__main__":
    import sys

    main(sys.argv[1:])
<|endoftext|>


<commit_before># -*- cpy-indent-level: 4; indent-tabs-mode: nil -*-
# ex: set expandtab softtabstop=4 shiftwidth=4:
#
# Copyright (C) 2008,2009,2010,2011,2013  Contributor
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Wrapper to make getting a machine simpler."""

from aquilon.exceptions_ import ArgumentError
from aquilon.aqdb.model import Cpu, LocalDisk, Machine

def create_machine(session, machine, dblocation, dbmodel, cpuname=None,
                   cpuvendor=None, cpuspeed=None, cpucount=None, memory=None,
                   serial=None, comments=None):

    # Figure out a CPU...
    dbcpu = None
    if not (cpuname or cpuvendor or cpuspeed is not None):
        if not dbmodel.machine_specs:
            raise ArgumentError("Model %s does not have machine specification "
                                "defaults, please specify --cpuvendor, "
                                "--cpuname, and --cpuspeed." % dbmodel.name)
        dbcpu = dbmodel.machine_specs.cpu
    else:
        # Was there enough on the command line to specify one?
        q = session.query(Cpu)
        if cpuname:
            q = q.filter(Cpu.name.like(cpuname.lower() + '%'))
        if cpuspeed is not None:
            q = q.filter_by(speed=cpuspeed)
        if cpuvendor:
            q = q.join('vendor').filter_by(name=cpuvendor.lower())
        cpulist = q.all()
        if not cpulist:
            raise ArgumentError("Could not find a CPU with the given "
                                "attributes.")
        if len(cpulist) == 1:
            # Found it exactly.
            dbcpu = cpulist[0]
        elif dbmodel.machine_specs:
            # Not exact, but see if the specs match the default.
            dbcpu = dbmodel.machine_specs.cpu
            if ((cpuname and not dbcpu.name.startswith(cpuname.lower()))
                    or (cpuspeed is not None and dbcpu.speed != cpuspeed)
                    or (cpuvendor and
                        dbcpu.vendor.name != cpuvendor.lower())):
                raise ArgumentError("Could not uniquely identify a CPU with "
                                    "the attributes given.")
        else:
            raise ArgumentError("Could not uniquely identify a CPU with the "
                                "attributes given.")

    if cpucount is None:
        if dbmodel.machine_specs:
            cpucount = dbmodel.machine_specs.cpu_quantity
        else:
            raise ArgumentError("Model %s does not have machine specification "
                                "defaults, please specify --cpucount." %
                                dbmodel.name)

    if memory is None:
        if dbmodel.machine_specs:
            memory = dbmodel.machine_specs.memory
        else:
            raise ArgumentError("Model %s does not have machine specification "
                                "defaults, please specify --memory (in MB)." %
                                dbmodel.name)

    dbmachine = Machine(location=dblocation, model=dbmodel, label=machine,
                        cpu=dbcpu, cpu_quantity=cpucount, memory=memory,
                        serial_no=serial, comments=comments)
    session.add(dbmachine)

    if dbmodel.machine_specs and not dbmodel.model_type.isAuroraNode() \
       and dbmodel.machine_specs.disk_type == 'local':
        specs = dbmodel.machine_specs
        dbdisk = LocalDisk(machine=dbmachine, device_name=specs.disk_name,
                           controller_type=specs.controller_type,
                           capacity=specs.disk_capacity, bootable=True)
        session.add(dbdisk)

    session.flush()
    return dbmachine
<commit_msg>fixed misleading cpu error message.<commit_after># -*- cpy-indent-level: 4; indent-tabs-mode: nil -*-
# ex: set expandtab softtabstop=4 shiftwidth=4:
#
# Copyright (C) 2008,2009,2010,2011,2013  Contributor
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Wrapper to make getting a machine simpler."""

from aquilon.exceptions_ import ArgumentError
from aquilon.aqdb.model import Cpu, LocalDisk, Machine

def create_machine(session, machine, dblocation, dbmodel, cpuname=None,
                   cpuvendor=None, cpuspeed=None, cpucount=None, memory=None,
                   serial=None, comments=None):

    # Figure out a CPU...
    dbcpu = None
    if not (cpuname or cpuvendor or cpuspeed is not None):
        if not dbmodel.machine_specs:
            raise ArgumentError("Model %s does not have machine specification "
                                "defaults, please specify --cpuvendor, "
                                "--cpuname, or --cpuspeed." % dbmodel.name)
        dbcpu = dbmodel.machine_specs.cpu
    else:
        # Was there enough on the command line to specify one?
        q = session.query(Cpu)
        if cpuname:
            q = q.filter(Cpu.name.like(cpuname.lower() + '%'))
        if cpuspeed is not None:
            q = q.filter_by(speed=cpuspeed)
        if cpuvendor:
            q = q.join('vendor').filter_by(name=cpuvendor.lower())
        cpulist = q.all()
        if not cpulist:
            raise ArgumentError("Could not find a CPU with the given "
                                "attributes.")
        if len(cpulist) == 1:
            # Found it exactly.
            dbcpu = cpulist[0]
        elif dbmodel.machine_specs:
            # Not exact, but see if the specs match the default.
            dbcpu = dbmodel.machine_specs.cpu
            if ((cpuname and not dbcpu.name.startswith(cpuname.lower()))
                    or (cpuspeed is not None and dbcpu.speed != cpuspeed)
                    or (cpuvendor and
                        dbcpu.vendor.name != cpuvendor.lower())):
                raise ArgumentError("Could not uniquely identify a CPU with "
                                    "the attributes given.")
        else:
            raise ArgumentError("Could not uniquely identify a CPU with the "
                                "attributes given.")

    if cpucount is None:
        if dbmodel.machine_specs:
            cpucount = dbmodel.machine_specs.cpu_quantity
        else:
            raise ArgumentError("Model %s does not have machine specification "
                                "defaults, please specify --cpucount." %
                                dbmodel.name)

    if memory is None:
        if dbmodel.machine_specs:
            memory = dbmodel.machine_specs.memory
        else:
            raise ArgumentError("Model %s does not have machine specification "
                                "defaults, please specify --memory (in MB)." %
                                dbmodel.name)

    dbmachine = Machine(location=dblocation, model=dbmodel, label=machine,
                        cpu=dbcpu, cpu_quantity=cpucount, memory=memory,
                        serial_no=serial, comments=comments)
    session.add(dbmachine)

    if dbmodel.machine_specs and not dbmodel.model_type.isAuroraNode() \
       and dbmodel.machine_specs.disk_type == 'local':
        specs = dbmodel.machine_specs
        dbdisk = LocalDisk(machine=dbmachine, device_name=specs.disk_name,
                           controller_type=specs.controller_type,
                           capacity=specs.disk_capacity, bootable=True)
        session.add(dbdisk)

    session.flush()
    return dbmachine
<|endoftext|>


<commit_before># Copyright 2011 James McCauley
#
# This file is part of POX.
#
# POX is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# POX 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with POX.  If not, see <http://www.gnu.org/licenses/>.

"""
This is the main OpenFlow module.

Along with libopenflow, this is the major part of the OpenFlow API in POX.
There are a number of Events, which are generally raised on core.openflow
as well as on individual switch Connections.  Many of these events have at
least some of the following properties:
 .connection - a reference to the switch connection that caused the event
 .dpid - the DPID of the switch that caused the event
 .ofp - the OpenFlow message that caused the event (from libopenflow)

One of the more complicated aspects of OpenFlow is dealing with stats
replies, which may come in multiple parts (it shouldn't be that that
difficult, really, but that hasn't stopped it from beind handled wrong
wrong more than once).  In POX, the raw events are available, but you will
generally just want to listen to the aggregate stats events which take
care of this for you and are only fired when all data is available.

NOTE: This module is usually automatically loaded by pox.py
"""

from pox.lib.revent import *
from pox.lib.util import dpidToStr
import libopenflow_01 as of
from pox.lib.packet.ethernet import ethernet

class ConnectionUp (Event):
  """
  Connection raised when the connection to an OpenFlow switch has been
  established.
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid
    self.ofp = ofp

class ConnectionDown (Event):
  """
  Connection raised when the connection to an OpenFlow switch has been
  lost.
  """
  def __init__ (self, connection):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid

class PortStatus (Event):
  """
  Fired in response to port status changes.
  added (bool) - True if fired because a port was added
  deleted (bool) - True if fired because a port was deleted
  modified (bool) - True if fired because a port was modified
  port (int) - number of port in question
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid
    self.ofp = ofp
    self.modified = ofp.reason == of.OFPPR_MODIFY
    self.added = ofp.reason == of.OFPPR_ADD
    self.deleted = ofp.reason == of.OFPPR_DELETE
    self.port = ofp.desc.port_no

class FlowRemoved (Event):
  """
  Raised when a flow entry has been removed from a flow table.
  This may either be because of a timeout or because it was removed
  explicitly.
  Properties:
  idleTimeout (bool) - True if expired because of idleness
  hardTimeout (bool) - True if expired because of hard timeout
  timeout (bool) - True if either of the above is true
  deleted (bool) - True if deleted explicitly
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid
    self.ofp = ofp
    self.idleTimeout = False
    self.hardTimeout = False
    self.deleted = False
    self.timeout = False
    if ofp.reason == of.OFPRR_IDLE_TIMEOUT:
      self.timeout = True
      self.idleTimeout = True
    elif ofp.reason == of.OFPRR_HARD_TIMEOUT:
      self.timeout = True
      self.hardTimeout = True
    elif ofp.reason == of.OFPRR_DELETE:
      self.deleted = True

class RawStatsReply (Event):
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp     # Raw ofp message(s)

class StatsReply (Event):
  """ Abstract superclass for all stats replies """
  def __init__ (self, connection, ofp, stats):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp     # Raw ofp message(s)
    self.stats = stats # Processed

class SwitchDescReceived (StatsReply):
  pass

class FlowStatsReceived (StatsReply):
  pass

class AggregateFlowStatsReceived (StatsReply):
  pass

class TableStatsReceived (StatsReply):
  pass

class PortStatsReceived (StatsReply):
  pass

class QueueStatsReceived (StatsReply):
  pass

class PacketIn (Event):
  """
  Fired in response to PacketIn events
  port (int) - number of port the packet came in on
  data (bytes) - raw packet data
  parsed (packet subclasses) - pox.lib.packet's parsed version
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp
    self.port = ofp.in_port
    self.data = ofp.data
    self._parsed = None
    self.dpid = connection.dpid

  def parse (self):
    if self._parsed is None:
      self._parsed = ethernet(self.data)
    return self._parsed

  @property
  def parsed (self):
    """
    The packet as parsed by pox.lib.packet
    """
    return self.parse()

class ErrorIn (Event):
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp
    self.xid = ofp.xid
    self.should_log = True # If this remains True, an error will be logged

  def asString (self):
    return self.ofp.show()

#    def lookup (m, v):
#      if v in m:
#        return str(m[v])
#      else:
#        return "Unknown/" + str(v)
#
#    #TODO: The show() in ofp_error actually does some clever
#    #      stuff now to stringize error messages.  Refactor that and the
#    #      (less clever) code below.
#    s = 'Type: ' + lookup(of.ofp_error_type_map, self.ofp.type)
#    s += ' Code: '
#
#    responses = {
#      of.OFPET_HELLO_FAILED    : of.ofp_hello_failed_code,
#      of.OFPET_BAD_REQUEST     : of.ofp_bad_request_code,
#      of.OFPET_BAD_ACTION      : of.ofp_bad_action_code,
#      of.OFPET_FLOW_MOD_FAILED : of.ofp_flow_mod_failed_code,
#      of.OFPET_PORT_MOD_FAILED : of.ofp_port_mod_failed_code,
#      of.OFPET_QUEUE_OP_FAILED : of.ofp_queue_op_failed_code,
#    }
#
#    if self.ofp.type in responses:
#      s += lookup(responses[self.ofp.type],self.ofp.code)
#    else:
#      s += "Unknown/" + str(self.ofp.code)
#    if self.ofp.type == of.OFPET_HELLO_FAILED:
#      s += lookup(of.ofp_hello_failed_code, self.ofp.type)
#
#    return s

class BarrierIn (Event):
  """
  Fired in response to a barrier reply
  xid (int) - XID of barrier request
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp
    self.dpid = connection.dpid
    self.xid = ofp.xid

class ConnectionIn (Event):
  def __init__ (self, connection):
    super(ConnectionIn,self).__init__()
    self.connection = connection
    self.dpid = connection.dpid
    self.nexus = None

class OpenFlowConnectionArbiter (EventMixin):
  """
  Determines which OpenFlowNexus gets the switch.
  Default implementation always just gives it to core.openflow
  """
  _eventMixin_events = set([
    ConnectionIn,
  ])
  def __init__ (self, default = False):
    """ default as False causes it to always use core.openflow """
    self._default = default
    self._fallback = None

  def getNexus (self, connection):
    e = ConnectionIn(connection)
    self.raiseEventNoErrors(e)
    if e.nexus is None:
      e.nexus = self._default
    if e.nexus is False:
      if self._fallback is None:
        try:
          from pox.core import core
          self._fallback = core.openflow
        except:
          raise RuntimeError("No OpenFlow nexus for new connection")
      e.nexus = self._fallback
    return e.nexus

class OpenFlowNexus (EventMixin):
  """
  Main point of OpenFlow interaction.

  There is usually just one instance of this class, registered as
  core.openflow.  Most OpenFlow events fire here in addition to on their
  specific connections.
  """
  _eventMixin_events = set([
    ConnectionUp,
    ConnectionDown,
    PortStatus,
    FlowRemoved,
    PacketIn,
    BarrierIn,
    ErrorIn,
    RawStatsReply,
    SwitchDescReceived,
    FlowStatsReceived,
    AggregateFlowStatsReceived,
    TableStatsReceived,
    PortStatsReceived,
    QueueStatsReceived,
    FlowRemoved,
  ])

  # Bytes to send to controller when a packet misses all flows
  miss_send_len = of.OFP_DEFAULT_MISS_SEND_LEN

  # Enable/Disable clearing of flows on switch connect
  clear_flows_on_connect = True

  def __init__ (self):
    self._connections = {} # DPID -> Connection

    from pox.core import core

    self.listenTo(core)

  def getConnection (self, dpid):
    """
    Get the Connection object associated with a DPID.
    """
    return self._connections.get(dpid, None)

  def sendToDPID (self, dpid, data):
    """
    Send data to a specific DPID.
    """
    if dpid in self._connections:
      self._connections[dpid].send(data)
      return True
    else:
      import logging
      log = logging.getLogger("openflow")
      log.warn("Couldn't send to %s because we're not connected to it!" %
               (dpidToStr(dpid),))
      return False

  def _handle_DownEvent (self, event):
    for c in self._connections.values():
      try:
        c.disconnect()
      except:
        pass

  def _connect (self, con):
    self._connections[con.dpid] = con
  def _disconnect (self, dpid):
    if dpid in self._connections:
      del self._connections[dpid]

def launch (default_arbiter=True):
  from pox.core import core
  if core.hasComponent("openflow"):
    return
  if default_arbiter:
    core.registerNew(OpenFlowConnectionArbiter)
  core.register("openflow", OpenFlowNexus())

<commit_msg>Add 'connections' property to OpenFlowNexus<commit_after># Copyright 2011 James McCauley
#
# This file is part of POX.
#
# POX is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# POX 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with POX.  If not, see <http://www.gnu.org/licenses/>.

"""
This is the main OpenFlow module.

Along with libopenflow, this is the major part of the OpenFlow API in POX.
There are a number of Events, which are generally raised on core.openflow
as well as on individual switch Connections.  Many of these events have at
least some of the following properties:
 .connection - a reference to the switch connection that caused the event
 .dpid - the DPID of the switch that caused the event
 .ofp - the OpenFlow message that caused the event (from libopenflow)

One of the more complicated aspects of OpenFlow is dealing with stats
replies, which may come in multiple parts (it shouldn't be that that
difficult, really, but that hasn't stopped it from beind handled wrong
wrong more than once).  In POX, the raw events are available, but you will
generally just want to listen to the aggregate stats events which take
care of this for you and are only fired when all data is available.

NOTE: This module is usually automatically loaded by pox.py
"""

from pox.lib.revent import *
from pox.lib.util import dpidToStr
import libopenflow_01 as of
from pox.lib.packet.ethernet import ethernet

class ConnectionUp (Event):
  """
  Connection raised when the connection to an OpenFlow switch has been
  established.
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid
    self.ofp = ofp

class ConnectionDown (Event):
  """
  Connection raised when the connection to an OpenFlow switch has been
  lost.
  """
  def __init__ (self, connection):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid

class PortStatus (Event):
  """
  Fired in response to port status changes.
  added (bool) - True if fired because a port was added
  deleted (bool) - True if fired because a port was deleted
  modified (bool) - True if fired because a port was modified
  port (int) - number of port in question
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid
    self.ofp = ofp
    self.modified = ofp.reason == of.OFPPR_MODIFY
    self.added = ofp.reason == of.OFPPR_ADD
    self.deleted = ofp.reason == of.OFPPR_DELETE
    self.port = ofp.desc.port_no

class FlowRemoved (Event):
  """
  Raised when a flow entry has been removed from a flow table.
  This may either be because of a timeout or because it was removed
  explicitly.
  Properties:
  idleTimeout (bool) - True if expired because of idleness
  hardTimeout (bool) - True if expired because of hard timeout
  timeout (bool) - True if either of the above is true
  deleted (bool) - True if deleted explicitly
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.dpid = connection.dpid
    self.ofp = ofp
    self.idleTimeout = False
    self.hardTimeout = False
    self.deleted = False
    self.timeout = False
    if ofp.reason == of.OFPRR_IDLE_TIMEOUT:
      self.timeout = True
      self.idleTimeout = True
    elif ofp.reason == of.OFPRR_HARD_TIMEOUT:
      self.timeout = True
      self.hardTimeout = True
    elif ofp.reason == of.OFPRR_DELETE:
      self.deleted = True

class RawStatsReply (Event):
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp     # Raw ofp message(s)

class StatsReply (Event):
  """ Abstract superclass for all stats replies """
  def __init__ (self, connection, ofp, stats):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp     # Raw ofp message(s)
    self.stats = stats # Processed

class SwitchDescReceived (StatsReply):
  pass

class FlowStatsReceived (StatsReply):
  pass

class AggregateFlowStatsReceived (StatsReply):
  pass

class TableStatsReceived (StatsReply):
  pass

class PortStatsReceived (StatsReply):
  pass

class QueueStatsReceived (StatsReply):
  pass

class PacketIn (Event):
  """
  Fired in response to PacketIn events
  port (int) - number of port the packet came in on
  data (bytes) - raw packet data
  parsed (packet subclasses) - pox.lib.packet's parsed version
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp
    self.port = ofp.in_port
    self.data = ofp.data
    self._parsed = None
    self.dpid = connection.dpid

  def parse (self):
    if self._parsed is None:
      self._parsed = ethernet(self.data)
    return self._parsed

  @property
  def parsed (self):
    """
    The packet as parsed by pox.lib.packet
    """
    return self.parse()

class ErrorIn (Event):
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp
    self.xid = ofp.xid
    self.should_log = True # If this remains True, an error will be logged

  def asString (self):
    return self.ofp.show()

#    def lookup (m, v):
#      if v in m:
#        return str(m[v])
#      else:
#        return "Unknown/" + str(v)
#
#    #TODO: The show() in ofp_error actually does some clever
#    #      stuff now to stringize error messages.  Refactor that and the
#    #      (less clever) code below.
#    s = 'Type: ' + lookup(of.ofp_error_type_map, self.ofp.type)
#    s += ' Code: '
#
#    responses = {
#      of.OFPET_HELLO_FAILED    : of.ofp_hello_failed_code,
#      of.OFPET_BAD_REQUEST     : of.ofp_bad_request_code,
#      of.OFPET_BAD_ACTION      : of.ofp_bad_action_code,
#      of.OFPET_FLOW_MOD_FAILED : of.ofp_flow_mod_failed_code,
#      of.OFPET_PORT_MOD_FAILED : of.ofp_port_mod_failed_code,
#      of.OFPET_QUEUE_OP_FAILED : of.ofp_queue_op_failed_code,
#    }
#
#    if self.ofp.type in responses:
#      s += lookup(responses[self.ofp.type],self.ofp.code)
#    else:
#      s += "Unknown/" + str(self.ofp.code)
#    if self.ofp.type == of.OFPET_HELLO_FAILED:
#      s += lookup(of.ofp_hello_failed_code, self.ofp.type)
#
#    return s

class BarrierIn (Event):
  """
  Fired in response to a barrier reply
  xid (int) - XID of barrier request
  """
  def __init__ (self, connection, ofp):
    Event.__init__(self)
    self.connection = connection
    self.ofp = ofp
    self.dpid = connection.dpid
    self.xid = ofp.xid

class ConnectionIn (Event):
  def __init__ (self, connection):
    super(ConnectionIn,self).__init__()
    self.connection = connection
    self.dpid = connection.dpid
    self.nexus = None

class OpenFlowConnectionArbiter (EventMixin):
  """
  Determines which OpenFlowNexus gets the switch.
  Default implementation always just gives it to core.openflow
  """
  _eventMixin_events = set([
    ConnectionIn,
  ])
  def __init__ (self, default = False):
    """ default as False causes it to always use core.openflow """
    self._default = default
    self._fallback = None

  def getNexus (self, connection):
    e = ConnectionIn(connection)
    self.raiseEventNoErrors(e)
    if e.nexus is None:
      e.nexus = self._default
    if e.nexus is False:
      if self._fallback is None:
        try:
          from pox.core import core
          self._fallback = core.openflow
        except:
          raise RuntimeError("No OpenFlow nexus for new connection")
      e.nexus = self._fallback
    return e.nexus

class OpenFlowNexus (EventMixin):
  """
  Main point of OpenFlow interaction.

  There is usually just one instance of this class, registered as
  core.openflow.  Most OpenFlow events fire here in addition to on their
  specific connections.
  """
  _eventMixin_events = set([
    ConnectionUp,
    ConnectionDown,
    PortStatus,
    FlowRemoved,
    PacketIn,
    BarrierIn,
    ErrorIn,
    RawStatsReply,
    SwitchDescReceived,
    FlowStatsReceived,
    AggregateFlowStatsReceived,
    TableStatsReceived,
    PortStatsReceived,
    QueueStatsReceived,
    FlowRemoved,
  ])

  # Bytes to send to controller when a packet misses all flows
  miss_send_len = of.OFP_DEFAULT_MISS_SEND_LEN

  # Enable/Disable clearing of flows on switch connect
  clear_flows_on_connect = True

  def __init__ (self):
    self._connections = {} # DPID -> Connection

    from pox.core import core

    self.listenTo(core)

  @property
  def connections (self):
    return self._connections.values()

  def getConnection (self, dpid):
    """
    Get the Connection object associated with a DPID.
    """
    return self._connections.get(dpid, None)

  def sendToDPID (self, dpid, data):
    """
    Send data to a specific DPID.
    """
    if dpid in self._connections:
      self._connections[dpid].send(data)
      return True
    else:
      import logging
      log = logging.getLogger("openflow")
      log.warn("Couldn't send to %s because we're not connected to it!" %
               (dpidToStr(dpid),))
      return False

  def _handle_DownEvent (self, event):
    for c in self._connections.values():
      try:
        c.disconnect()
      except:
        pass

  def _connect (self, con):
    self._connections[con.dpid] = con
  def _disconnect (self, dpid):
    if dpid in self._connections:
      del self._connections[dpid]

def launch (default_arbiter=True):
  from pox.core import core
  if core.hasComponent("openflow"):
    return
  if default_arbiter:
    core.registerNew(OpenFlowConnectionArbiter)
  core.register("openflow", OpenFlowNexus())

<|endoftext|>