<commit_before># Copyright 2020 The TensorFlow Authors
#
# 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
#
#    https://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.
"""OpenGL rasterization backend for TF Graphics."""

import tensorflow as tf

from tensorflow_graphics.rendering import framebuffer as fb
from tensorflow_graphics.util import export_api
from tensorflow_graphics.util import shape

# pylint: disable=g-import-not-at-top
try:
  from tensorflow_graphics.rendering.opengl import gen_rasterizer_op as render_ops
except ImportError:
  import os
  dir_path = os.path.dirname(os.path.abspath(__file__))
  render_ops = tf.load_op_library(os.path.join(dir_path, "rasterizer_op.so"))
# pylint: enable=g-import-not-at-top

def _dim_value(dim):
  return 1 if dim is None else tf.compat.v1.dimension_value(dim)

# Empty vertex shader; all the work happens in the geometry shader.
vertex_shader = """
#version 430
void main() { }
"""

# Geometry shader that projects the vertices of visible triangles onto the image
# plane.
geometry_shader = """
#version 430

uniform mat4 view_projection_matrix;

layout(points) in;
layout(triangle_strip, max_vertices=3) out;

out layout(location = 0) vec2 barycentric_coordinates;
out layout(location = 1) float triangle_index;

layout(binding=0) buffer triangular_mesh { float mesh_buffer[]; };

vec3 get_vertex_position(int vertex_index) {
  // Triangles are packed as 3 consecuitve vertices, each with 3 coordinates.
  int offset = gl_PrimitiveIDIn * 9 + vertex_index * 3;
  return vec3(mesh_buffer[offset], mesh_buffer[offset + 1],
    mesh_buffer[offset + 2]);
}

void main() {
  vec3 positions[3] = {get_vertex_position(0), get_vertex_position(1),
                        get_vertex_position(2)};
  vec4 projected_vertices[3] = {
                            view_projection_matrix * vec4(positions[0], 1.0),
                            view_projection_matrix * vec4(positions[1], 1.0),
                            view_projection_matrix * vec4(positions[2], 1.0)};

  for (int i = 0; i < 3; ++i) {
    // gl_Position is a pre-defined size 4 output variable.
    gl_Position = projected_vertices[i];
    barycentric_coordinates = vec2(i==0 ? 1.0 : 0.0, i==1 ? 1.0 : 0.0);
    triangle_index = gl_PrimitiveIDIn;

    EmitVertex();
  }
  EndPrimitive();
}
"""

# Fragment shader that packs barycentric coordinates, and triangle index.
fragment_shader = """
#version 430

in layout(location = 0) vec2 barycentric_coordinates;
in layout(location = 1) float triangle_index;

out vec4 output_color;

void main() {
  output_color = vec4(round(triangle_index), barycentric_coordinates, 1.0);
}
"""

def rasterize(vertices,
              triangles,
              view_projection_matrices,
              image_size,
              name=None):
  """Rasterizes the scene.

    This rasterizer estimates which triangle is associated with each pixel using
    OpenGL.

  Note:
    In the following, A1 to An are optional batch dimensions which must be
    broadcast compatible for inputs `vertices` and `view_projection_matrices`.

  Args:
    vertices: A tensor of shape `[batch, num_vertices, 3]` containing batches
      vertices, each defined by a 3D point.
    triangles: A tensor of shape `[num_triangles, 3]` each associated with 3
      vertices from `scene_vertices`
    view_projection_matrices: A tensor of shape `[batch, 4, 4]` containing
      batches of view projection matrices
    image_size: An tuple of integers (width, height) containing the dimensions
      in pixels of the rasterized image.
    name: A name for this op. Defaults to 'rasterization_backend_rasterize'.

  Returns:
    A Framebuffer containing the rasterized values: barycentrics, triangle_id,
    foreground_mask, vertex_ids. Returned Tensors have shape
    [batch, num_layers, height, width, channels]
    Note: triangle_id contains the triangle id value for each pixel in the
    output image. For pixels within the mesh, this is the integer value in the
    range [0, num_vertices] from triangles. For vertices outside the mesh this
    is 0; 0 can either indicate belonging to triangle 0, or being outside the
    mesh. This ensures all returned triangle ids will validly index into the
    vertex array, enabling the use of tf.gather with indices from this tensor.
    The barycentric coordinates can be used to determine pixel validity instead.
    See framebuffer.py for a description of the Framebuffer fields.
  """
  with tf.compat.v1.name_scope(name, "rasterization_backend_rasterize",
                               (vertices, triangles, view_projection_matrices)):
    vertices = tf.convert_to_tensor(value=vertices)
    triangles = tf.convert_to_tensor(value=triangles)
    view_projection_matrices = tf.convert_to_tensor(
        value=view_projection_matrices)

    shape.check_static(
        tensor=vertices,
        tensor_name="vertices",
        has_rank=3,
        has_dim_equals=((-1, 3)))
    shape.check_static(
        tensor=triangles,
        tensor_name="triangles",
        has_rank=2,
        has_dim_equals=((-1, 3)))
    shape.check_static(
        tensor=view_projection_matrices,
        tensor_name="view_projection_matrices",
        has_rank=3,
        has_dim_equals=((-1, 4), (-2, 4)))
    shape.compare_batch_dimensions(
        tensors=(vertices, view_projection_matrices),
        tensor_names=("vertices", "view_projection_matrices"),
        last_axes=(-3, -3),
        broadcast_compatible=True)

    geometry = tf.gather(vertices, triangles, axis=-2)

    # Extract batch size in order to make sure it is preserved after `gather`
    # operation.
    batch_size = _dim_value(vertices.shape[0])

    rasterized = render_ops.rasterize(
        num_points=geometry.shape[-3],
        alpha_clear=0.0,
        enable_cull_face=True,
        variable_names=("view_projection_matrix", "triangular_mesh"),
        variable_kinds=("mat", "buffer"),
        variable_values=(view_projection_matrices,
                         tf.reshape(geometry, shape=[batch_size, -1])),
        output_resolution=image_size,
        vertex_shader=vertex_shader,
        geometry_shader=geometry_shader,
        fragment_shader=fragment_shader)

    triangle_index = tf.cast(rasterized[..., 0], tf.int32)
    # Slicing of the tensor will result in all batch dimensions being
    # `None` for tensorflow graph mode, therefore we have to fix it in order to
    # have explicit shape.
    width, height = image_size
    triangle_index = tf.reshape(triangle_index, [batch_size, height, width, 1])
    barycentric_coordinates = rasterized[..., 1:3]
    barycentric_coordinates = tf.concat(
        (barycentric_coordinates, 1.0 - barycentric_coordinates[..., 0:1] -
         barycentric_coordinates[..., 1:2]),
        axis=-1)
    mask = tf.cast(rasterized[..., 3], tf.int32)
    mask = tf.reshape(mask, [batch_size, height, width, 1])

    vertex_ids = tf.gather(triangles, triangle_index[..., 0], batch_dims=0)

    return fb.Framebuffer(
        foreground_mask=mask,
        triangle_id=triangle_index,
        vertex_ids=vertex_ids,
        barycentrics=fb.RasterizedAttribute(
            value=barycentric_coordinates, d_dx=None, d_dy=None))

# API contains all public functions and classes.
__all__ = export_api.get_functions_and_classes()
<commit_msg>Unit test to check that differentiable barycentrics are equal to non-differentiable ones. Also make sure we mask both barycentric coordinates the same way.<commit_after># Copyright 2020 The TensorFlow Authors
#
# 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
#
#    https://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.
"""OpenGL rasterization backend for TF Graphics."""

import tensorflow as tf

from tensorflow_graphics.rendering import framebuffer as fb
from tensorflow_graphics.util import export_api
from tensorflow_graphics.util import shape

# pylint: disable=g-import-not-at-top
try:
  from tensorflow_graphics.rendering.opengl import gen_rasterizer_op as render_ops
except ImportError:
  import os
  dir_path = os.path.dirname(os.path.abspath(__file__))
  render_ops = tf.load_op_library(os.path.join(dir_path, "rasterizer_op.so"))
# pylint: enable=g-import-not-at-top

def _dim_value(dim):
  return 1 if dim is None else tf.compat.v1.dimension_value(dim)

# Empty vertex shader; all the work happens in the geometry shader.
vertex_shader = """
#version 430
void main() { }
"""

# Geometry shader that projects the vertices of visible triangles onto the image
# plane.
geometry_shader = """
#version 430

uniform mat4 view_projection_matrix;

layout(points) in;
layout(triangle_strip, max_vertices=3) out;

out layout(location = 0) vec2 barycentric_coordinates;
out layout(location = 1) float triangle_index;

layout(binding=0) buffer triangular_mesh { float mesh_buffer[]; };

vec3 get_vertex_position(int vertex_index) {
  // Triangles are packed as 3 consecuitve vertices, each with 3 coordinates.
  int offset = gl_PrimitiveIDIn * 9 + vertex_index * 3;
  return vec3(mesh_buffer[offset], mesh_buffer[offset + 1],
    mesh_buffer[offset + 2]);
}

void main() {
  vec3 positions[3] = {get_vertex_position(0), get_vertex_position(1),
                        get_vertex_position(2)};
  vec4 projected_vertices[3] = {
                            view_projection_matrix * vec4(positions[0], 1.0),
                            view_projection_matrix * vec4(positions[1], 1.0),
                            view_projection_matrix * vec4(positions[2], 1.0)};

  for (int i = 0; i < 3; ++i) {
    // gl_Position is a pre-defined size 4 output variable.
    gl_Position = projected_vertices[i];
    barycentric_coordinates = vec2(i==0 ? 1.0 : 0.0, i==1 ? 1.0 : 0.0);
    triangle_index = gl_PrimitiveIDIn;

    EmitVertex();
  }
  EndPrimitive();
}
"""

# Fragment shader that packs barycentric coordinates, and triangle index.
fragment_shader = """
#version 430

in layout(location = 0) vec2 barycentric_coordinates;
in layout(location = 1) float triangle_index;

out vec4 output_color;

void main() {
  output_color = vec4(round(triangle_index), barycentric_coordinates, 1.0);
}
"""

def rasterize(vertices,
              triangles,
              view_projection_matrices,
              image_size,
              name=None):
  """Rasterizes the scene.

    This rasterizer estimates which triangle is associated with each pixel using
    OpenGL.

  Note:
    In the following, A1 to An are optional batch dimensions which must be
    broadcast compatible for inputs `vertices` and `view_projection_matrices`.

  Args:
    vertices: A tensor of shape `[batch, num_vertices, 3]` containing batches
      vertices, each defined by a 3D point.
    triangles: A tensor of shape `[num_triangles, 3]` each associated with 3
      vertices from `scene_vertices`
    view_projection_matrices: A tensor of shape `[batch, 4, 4]` containing
      batches of view projection matrices
    image_size: An tuple of integers (width, height) containing the dimensions
      in pixels of the rasterized image.
    name: A name for this op. Defaults to 'rasterization_backend_rasterize'.

  Returns:
    A Framebuffer containing the rasterized values: barycentrics, triangle_id,
    foreground_mask, vertex_ids. Returned Tensors have shape
    [batch, num_layers, height, width, channels]
    Note: triangle_id contains the triangle id value for each pixel in the
    output image. For pixels within the mesh, this is the integer value in the
    range [0, num_vertices] from triangles. For vertices outside the mesh this
    is 0; 0 can either indicate belonging to triangle 0, or being outside the
    mesh. This ensures all returned triangle ids will validly index into the
    vertex array, enabling the use of tf.gather with indices from this tensor.
    The barycentric coordinates can be used to determine pixel validity instead.
    See framebuffer.py for a description of the Framebuffer fields.
  """
  with tf.compat.v1.name_scope(name, "rasterization_backend_rasterize",
                               (vertices, triangles, view_projection_matrices)):
    vertices = tf.convert_to_tensor(value=vertices)
    triangles = tf.convert_to_tensor(value=triangles)
    view_projection_matrices = tf.convert_to_tensor(
        value=view_projection_matrices)

    shape.check_static(
        tensor=vertices,
        tensor_name="vertices",
        has_rank=3,
        has_dim_equals=((-1, 3)))
    shape.check_static(
        tensor=triangles,
        tensor_name="triangles",
        has_rank=2,
        has_dim_equals=((-1, 3)))
    shape.check_static(
        tensor=view_projection_matrices,
        tensor_name="view_projection_matrices",
        has_rank=3,
        has_dim_equals=((-1, 4), (-2, 4)))
    shape.compare_batch_dimensions(
        tensors=(vertices, view_projection_matrices),
        tensor_names=("vertices", "view_projection_matrices"),
        last_axes=(-3, -3),
        broadcast_compatible=True)

    geometry = tf.gather(vertices, triangles, axis=-2)

    # Extract batch size in order to make sure it is preserved after `gather`
    # operation.
    batch_size = _dim_value(vertices.shape[0])

    rasterized = render_ops.rasterize(
        num_points=geometry.shape[-3],
        alpha_clear=0.0,
        enable_cull_face=True,
        variable_names=("view_projection_matrix", "triangular_mesh"),
        variable_kinds=("mat", "buffer"),
        variable_values=(view_projection_matrices,
                         tf.reshape(geometry, shape=[batch_size, -1])),
        output_resolution=image_size,
        vertex_shader=vertex_shader,
        geometry_shader=geometry_shader,
        fragment_shader=fragment_shader)

    triangle_index = tf.cast(rasterized[..., 0], tf.int32)
    # Slicing of the tensor will result in all batch dimensions being
    # `None` for tensorflow graph mode, therefore we have to fix it in order to
    # have explicit shape.
    width, height = image_size
    triangle_index = tf.reshape(triangle_index, [batch_size, height, width, 1])
    barycentric_coordinates = rasterized[..., 1:3]
    barycentric_coordinates = tf.concat(
        (barycentric_coordinates, 1.0 - barycentric_coordinates[..., 0:1] -
         barycentric_coordinates[..., 1:2]),
        axis=-1)
    mask = tf.cast(rasterized[..., 3], tf.int32)
    mask = tf.reshape(mask, [batch_size, height, width, 1])

    barycentric_coordinates = tf.cast(mask,
                                      tf.float32) * barycentric_coordinates
    vertex_ids = tf.gather(triangles, triangle_index[..., 0], batch_dims=0)

    return fb.Framebuffer(
        foreground_mask=mask,
        triangle_id=triangle_index,
        vertex_ids=vertex_ids,
        barycentrics=fb.RasterizedAttribute(
            value=barycentric_coordinates, d_dx=None, d_dy=None))

# API contains all public functions and classes.
__all__ = export_api.get_functions_and_classes()
<|endoftext|>


<commit_before>from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.views.generic.simple import direct_to_template

from registration.views import activate
from registration.views import register

from accounts.forms import RegistrationForm

urlpatterns = patterns('',

       url(r'^register/$',
           register,
           {'backend': "accounts.backends.DjangoPackagesRegistrationBackend",
           'form_class': RegistrationForm},
           name='registration_register'),
       url(r'^activate/complete/$',
           direct_to_template,
           {'template': 'registration/activation_complete.html'},
           name='registration_activation_complete'),
       url(r'^activate/(?P<activation_key>\w+)/$',
           activate,
           {'backend': "accounts.backends.StockRegistrationBackend"},
           name='registration_activate'),
       url(r'^register/complete/$',
           direct_to_template,
           {'template': 'registration/registration_complete.html'},
           name='registration_complete'),
       url(r'^register/closed/$',
           direct_to_template,
           {'template': 'registration/registration_closed.html'},
           name='registration_disallowed'),
       (r'', include('registration.auth_urls')),
)<commit_msg>Pointing the activation link to the DjangoPackagesRegistrationBackend backend<commit_after>from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.views.generic.simple import direct_to_template

from registration.views import activate
from registration.views import register

from accounts.forms import RegistrationForm

urlpatterns = patterns('',

       url(r'^register/$',
           register,
           {'backend': "accounts.backends.DjangoPackagesRegistrationBackend",
           'form_class': RegistrationForm},
           name='registration_register'),
       url(r'^activate/complete/$',
           direct_to_template,
           {'template': 'registration/activation_complete.html'},
           name='registration_activation_complete'),
       url(r'^activate/(?P<activation_key>\w+)/$',
           activate,
           {'backend': "accounts.backends.DjangoPackagesRegistrationBackend"},
           name='registration_activate'),
       url(r'^register/complete/$',
           direct_to_template,
           {'template': 'registration/registration_complete.html'},
           name='registration_complete'),
       url(r'^register/closed/$',
           direct_to_template,
           {'template': 'registration/registration_closed.html'},
           name='registration_disallowed'),
       (r'', include('registration.auth_urls')),
)<|endoftext|>


<commit_before>######################################################################
# Copyright (C) 2011,2012,2014 Jaakko Luttinen
#
# This file is licensed under Version 3.0 of the GNU General Public
# License. See LICENSE for a text of the license.
######################################################################

######################################################################
# This file is part of BayesPy.
#
# BayesPy is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# BayesPy 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 BayesPy.  If not, see <http://www.gnu.org/licenses/>.
######################################################################

import itertools
import numpy as np
import scipy as sp
import scipy.linalg.decomp_cholesky as decomp
import scipy.linalg as linalg
import scipy.special as special
import scipy.spatial.distance as distance

from bayespy.utils import utils

from .expfamily import ExponentialFamily, \
                       ExponentialFamilyDistribution, \
                       useconstructor

from .categorical import Categorical, \
                         CategoricalStatistics

class MixtureDistribution(ExponentialFamilyDistribution):

    def __init__(self, distribution, cluster_plate):
        self.distribution = distribution
        self.cluster_plate = cluster_plate
        self.ndims = distribution.ndims
        self.ndims_parents = distribution.ndims_parents

    def compute_message_to_parent(self, parent, index, u, *u_parents):

        if index == 0:

            # Shape(phi)    = [Nn,..,K,..,N0,Dd,..,D0]
            # Shape(L)      = [Nn,..,K,..,N0]
            # Shape(u)      = [Nn,..,N0,Dd,..,D0]
            # Shape(result) = [Nn,..,N0,K]

            # Compute g:
            # Shape(g)      = [Nn,..,K,..,N0]
            g = self.distribution.compute_cgf_from_parents(*(u_parents[1:]))
            # Reshape(g):
            # Shape(g)      = [Nn,..,N0,K]
            g = utils.moveaxis(g, self.cluster_plate, -1)

            # Compute phi:
            # Shape(phi)    = [Nn,..,K,..,N0,Dd,..,D0]
            phi = self.distribution.compute_phi_from_parents(*(u_parents[1:]))
            # Reshape phi:
            # Shape(phi)    = [Nn,..,N0,K,Dd,..,D0]
            for ind in range(len(phi)):
                phi[ind] = utils.moveaxis(phi[ind],
                                          self.cluster_plate-self.distribution.ndims[ind],
                                          -1-self.distribution.ndims[ind])

            # Reshape u:
            # Shape(u)      = [Nn,..,N0,1,Dd,..,D0]
            u_self = list()
            for ind in range(len(u)):
                u_self.append(np.expand_dims(u[ind],
                                             axis=(-1-self.distribution.ndims[ind])))

            # Compute logpdf:
            # Shape(L)      = [Nn,..,N0,K]
            L = self.distribution.compute_logpdf(u_self, phi, g, 0)

            # Sum over other than the cluster dimensions? No!
            # Hmm.. I think the message passing method will do
            # that automatically

            return [L]

        elif index >= 1:

            # Parent index for the distribution used for the
            # mixture.
            index = index - 1

            # Reshape u:
            # Shape(u)      = [Nn,..1,..,N0,Dd,..,D0]
            u_self = list()
            for ind in range(len(u)):
                if self.cluster_plate < 0:
                    cluster_axis = self.cluster_plate - self.distribution.ndims[ind]
                else:
                    cluster_axis = self.cluster_plate
                u_self.append(np.expand_dims(u[ind], axis=cluster_axis))

            # Message from the mixed distribution
            m = self.distribution.compute_message_to_parent(parent,
                                                        index,
                                                        u_self,
                                                        *(u_parents[1:]))

            # Weigh the messages with the responsibilities
            for i in range(len(m)):

                # Shape(m)      = [Nn,..,K,..,N0,Dd,..,D0]
                # Shape(p)      = [Nn,..,N0,K]
                # Shape(result) = [Nn,..,K,..,N0,Dd,..,D0]

                # Number of axes for the variable dimensions for
                # the parent message.
                D = self.distribution.ndims_parents[index][i]

                # Responsibilities for clusters are the first
                # parent's first moment:
                # Shape(p)      = [Nn,..,N0,K]
                p = u_parents[0][0]
                # Move the cluster axis to the proper place:
                # Shape(p)      = [Nn,..,K,..,N0]
                p = utils.moveaxis(p, -1, self.cluster_plate)
                # Add axes for variable dimensions to the contributions
                # Shape(p)      = [Nn,..,K,..,N0,1,..,1]
                p = utils.add_trailing_axes(p, D)

                if self.cluster_plate < 0:
                    # Add the variable dimensions
                    cluster_axis = self.cluster_plate - D

                # Add axis for clusters:
                # Shape(m)      = [Nn,..,1,..,N0,Dd,..,D0]
                #m[i] = np.expand_dims(m[i], axis=cluster_axis)

                #
                # TODO: You could do summing here already so that
                # you wouldn't compute huge matrices as
                # intermediate result. Use einsum.

                # Compute the message contributions for each
                # cluster:
                # Shape(result) = [Nn,..,K,..,N0,Dd,..,D0]
                m[i] = m[i] * p

            return m

    def compute_phi_from_parents(self, *u_parents, mask=True):

        # Compute weighted average of the parameters

        # Cluster parameters
        Phi = self.distribution.compute_phi_from_parents(*(u_parents[1:]))
        # Contributions/weights/probabilities
        P = u_parents[0][0]

        phi = list()

        for ind in range(len(Phi)):
            # Compute element-wise product and then sum over K clusters.
            # Note that the dimensions aren't perfectly aligned because
            # the cluster dimension (K) may be arbitrary for phi, and phi
            # also has dimensions (Dd,..,D0) of the parameters.
            # Shape(phi)    = [Nn,..,K,..,N0,Dd,..,D0]
            # Shape(p)      = [Nn,..,N0,K]
            # Shape(result) = [Nn,..,N0,Dd,..,D0]
            # General broadcasting rules apply for Nn,..,N0, that is,
            # preceding dimensions may be missing or dimension may be
            # equal to one. Probably, shape(phi) has lots of missing
            # dimensions and/or dimensions that are one.

            if self.cluster_plate < 0:
                cluster_axis = self.cluster_plate - self.distribution.ndims[ind]
            #else:
            #    cluster_axis = cluster_plate

            # Move cluster axis to the last:
            # Shape(phi)    = [Nn,..,N0,Dd,..,D0,K]
            phi.append(utils.moveaxis(Phi[ind], cluster_axis, -1))

            # Add axes to p:
            # Shape(p)      = [Nn,..,N0,K,1,..,1]
            p = utils.add_trailing_axes(P, self.distribution.ndims[ind])
            # Move cluster axis to the last:
            # Shape(p)      = [Nn,..,N0,1,..,1,K]
            p = utils.moveaxis(p, -(self.distribution.ndims[ind]+1), -1)

            # Now the shapes broadcast perfectly and we can sum
            # p*phi over the last axis:
            # Shape(result) = [Nn,..,N0,Dd,..,D0]
            phi[ind] = utils.sum_product(p, phi[ind], axes_to_sum=-1)

        return phi

    def compute_moments_and_cgf(self, phi, mask=True):
        return self.distribution.compute_moments_and_cgf(phi, mask=mask)

    def compute_cgf_from_parents(self, *u_parents):

        # Compute weighted average of g over the clusters.

        # Shape(g)      = [Nn,..,K,..,N0]
        # Shape(p)      = [Nn,..,N0,K]
        # Shape(result) = [Nn,..,N0]

        # Compute g for clusters:
        # Shape(g)      = [Nn,..,K,..,N0]
        g = self.distribution.compute_cgf_from_parents(*(u_parents[1:]))

        # Move cluster axis to last:
        # Shape(g)      = [Nn,..,N0,K]
        g = utils.moveaxis(g, self.cluster_plate, -1)

        # Cluster assignments/contributions/probabilities/weights:
        # Shape(p)      = [Nn,..,N0,K]
        p = u_parents[0][0]

        # Weighted average of g over the clusters. As p and g are
        # properly aligned, you can just sum p*g over the last
        # axis and utilize broadcasting:
        # Shape(result) = [Nn,..,N0]
        g = utils.sum_product(p, g, axes_to_sum=-1)

        return g

    def compute_fixed_moments_and_f(self, x, mask=True):
        """ Compute u(x) and f(x) for given x. """
        return self.distribution.compute_fixed_moments_and_f(x, mask=True)

class Mixture(ExponentialFamily):

    @useconstructor
    def __init__(self, z, node_class, *args, cluster_plate=-1, **kwargs):
        self.cluster_plate = cluster_plate
        super().__init__(z, *args, **kwargs)

    @classmethod
    def _constructor(cls, z, node_class, *args, cluster_plate=-1, **kwargs):
        """
        Constructs distribution and statistics objects.
        """
        if cluster_plate >= 0:
            raise Exception("Give negative value for axis index cluster_plates")

        # TODO/FIXME: Constant (non-node, numeric) z is a bit
        # non-trivial. Constant z is an array of cluster assignments, e.g.,
        # [2,0,2,3,1,2]. However, it is not possible to know the number of
        # clusters from this. It could be 4 but it could be 10 as well.
        # Thus, we can't create a constant node from z because the number of
        # clusters is required by constant categorical. It might be possible
        # to infer the number of clusters from the cluster_plate axis of the
        # other parameters but that is not trivial. A simple solution is to
        # require the user to provide the number of clusters when it can't
        # be inferred otherwise. Anyway, this is left for future work.

        try:
            # Convert a node
            z = z._convert(CategoricalStatistics)
        except:
            # Conversion failed, thus z is a constant (or invalid node)
            raise NotImplementedError("Constant cluster assignments are "
                                      "not yet implemented")

        # Number of clusters
        K = z.dims[0][0]

        # Get the stuff for the mixed distribution
        (dims, distribution, statistics, parent_statistics) = \
          node_class._constructor(*args)

        # Convert the distribution to a mixture
        distribution = MixtureDistribution(distribution,
                                           cluster_plate)

        # Add cluster assignments to parents
        parent_statistics = ((CategoricalStatistics(K),) + \
                            parent_statistics)

        return (dims,
                distribution,
                statistics,
                parent_statistics)

    def _plates_to_parent(self, index):
        if index == 0:
            return self.plates
        else:
            if self.cluster_plate < 0:
                plates = list(self.plates)
                if self.cluster_plate < 0:
                    k = len(self.plates) + self.cluster_plate + 1
                else:
                    k = self.cluster_plate
                plates.insert(k, self.parents[0].dims[0][0])
                plates = tuple(plates)

            return plates

    def _plates_from_parent(self, index):
        if index == 0:
            return self.parents[index].plates
        else:
            plates = list(self.parents[index].plates)
            plates.pop(self.cluster_plate)
            return tuple(plates)

    def integrated_logpdf_from_parents(self, x, index):

        """ Approximates the posterior predictive pdf \int
        p(x|parents) q(parents) dparents in log-scale as \int
        q(parents_i) exp( \int q(parents_\i) \log p(x|parents)
        dparents_\i ) dparents_i."""

        if index == 0:
            # Integrate out the cluster assignments

            # First, integrate the cluster parameters in log-scale

            # compute_logpdf(cls, u, phi, g, f):

            # Shape(x) = [M1,..,Mm,N1,..,Nn,D1,..,Dd]
            # Add the cluster axis to x:
            # Shape(x) = [M1,..,Mm,N1,..,1,..,Nn,D1,..,Dd]
            cluster_axis = self.cluster_plate - \
                           self._statistics.ndim_observations
            x = np.expand_dims(x, axis=cluster_axis)

            u_parents = self._message_from_parents()

            # Shape(u) = [M1,..,Mm,N1,..,1,..,Nn,D1,..,Dd]
            # Shape(f) = [M1,..,Mm,N1,..,1,..,Nn]
            (u, f) = self._distribution.distribution.compute_fixed_moments_and_f(x)
            # Shape(phi) = [N1,..,K,..,Nn,D1,..,Dd]
            phi = self._distribution.distribution.compute_phi_from_parents(*(u_parents[1:]))
            # Shape(g) = [N1,..,K,..,Nn]
            g = self._distribution.distribution.compute_cgf_from_parents(*(u_parents[1:]))
            # Shape(lpdf) = [M1,..,Mm,N1,..,K,..,Nn]
            lpdf = self._distribution.distribution.compute_logpdf(u, phi, g, f)

            # From logpdf to pdf, but avoid over/underflow
            lpdf_max = np.max(lpdf, axis=self.cluster_plate, keepdims=True)
            pdf = np.exp(lpdf-lpdf_max)

            # Move cluster axis to be the last:
            # Shape(pdf) = [M1,..,Mm,N1,..,Nn,K]
            pdf = utils.moveaxis(pdf, self.cluster_plate, -1)

            # Cluster assignments/probabilities/weights
            # Shape(p) = [N1,..,Nn,K]
            p = u_parents[0][0]

            # Weighted average. TODO/FIXME: Use einsum!
            # Shape(pdf) = [M1,..,Mm,N1,..,Nn]
            pdf = np.sum(pdf * p, axis=self.cluster_plate)

            # Back to log-scale (add the overflow fix!)
            lpdf_max = np.squeeze(lpdf_max, axis=self.cluster_plate)
            lpdf = np.log(pdf) + lpdf_max

            return lpdf

        raise NotImplementedError()
<commit_msg>ENH: Minor fixes to Mixture node<commit_after>######################################################################
# Copyright (C) 2011,2012,2014 Jaakko Luttinen
#
# This file is licensed under Version 3.0 of the GNU General Public
# License. See LICENSE for a text of the license.
######################################################################

######################################################################
# This file is part of BayesPy.
#
# BayesPy is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# BayesPy 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 BayesPy.  If not, see <http://www.gnu.org/licenses/>.
######################################################################

import itertools
import numpy as np
import scipy as sp
import scipy.linalg.decomp_cholesky as decomp
import scipy.linalg as linalg
import scipy.special as special
import scipy.spatial.distance as distance

from bayespy.utils import utils

from .expfamily import ExponentialFamily, \
                       ExponentialFamilyDistribution, \
                       useconstructor

from .categorical import Categorical, \
                         CategoricalStatistics

class MixtureDistribution(ExponentialFamilyDistribution):

    def __init__(self, distribution, cluster_plate):
        self.distribution = distribution
        self.cluster_plate = cluster_plate
        self.ndims = distribution.ndims
        self.ndims_parents = distribution.ndims_parents

    def compute_message_to_parent(self, parent, index, u, *u_parents):

        if index == 0:

            # Shape(phi)    = [Nn,..,K,..,N0,Dd,..,D0]
            # Shape(L)      = [Nn,..,K,..,N0]
            # Shape(u)      = [Nn,..,N0,Dd,..,D0]
            # Shape(result) = [Nn,..,N0,K]

            # Compute g:
            # Shape(g)      = [Nn,..,K,..,N0]
            g = self.distribution.compute_cgf_from_parents(*(u_parents[1:]))
            # Reshape(g):
            # Shape(g)      = [Nn,..,N0,K]
            g = utils.moveaxis(g, self.cluster_plate, -1)

            # Compute phi:
            # Shape(phi)    = [Nn,..,K,..,N0,Dd,..,D0]
            phi = self.distribution.compute_phi_from_parents(*(u_parents[1:]))
            # Reshape phi:
            # Shape(phi)    = [Nn,..,N0,K,Dd,..,D0]
            for ind in range(len(phi)):
                phi[ind] = utils.moveaxis(phi[ind],
                                          self.cluster_plate-self.distribution.ndims[ind],
                                          -1-self.distribution.ndims[ind])

            # Reshape u:
            # Shape(u)      = [Nn,..,N0,1,Dd,..,D0]
            u_self = list()
            for ind in range(len(u)):
                u_self.append(np.expand_dims(u[ind],
                                             axis=(-1-self.distribution.ndims[ind])))

            # Compute logpdf:
            # Shape(L)      = [Nn,..,N0,K]
            L = self.distribution.compute_logpdf(u_self, phi, g, 0)

            # Sum over other than the cluster dimensions? No!
            # Hmm.. I think the message passing method will do
            # that automatically

            m = [L]

            return m

        elif index >= 1:

            # Parent index for the distribution used for the
            # mixture.
            index = index - 1

            # Reshape u:
            # Shape(u)      = [Nn,..1,..,N0,Dd,..,D0]
            u_self = list()
            for ind in range(len(u)):
                if self.cluster_plate < 0:
                    cluster_axis = self.cluster_plate - self.distribution.ndims[ind]
                else:
                    cluster_axis = self.cluster_plate
                u_self.append(np.expand_dims(u[ind], axis=cluster_axis))

            # Message from the mixed distribution
            m = self.distribution.compute_message_to_parent(parent,
                                                        index,
                                                        u_self,
                                                        *(u_parents[1:]))

            # Weigh the messages with the responsibilities
            for i in range(len(m)):

                # Shape(m)      = [Nn,..,K,..,N0,Dd,..,D0]
                # Shape(p)      = [Nn,..,N0,K]
                # Shape(result) = [Nn,..,K,..,N0,Dd,..,D0]

                # Number of axes for the variable dimensions for
                # the parent message.
                D = self.distribution.ndims_parents[index][i]

                # Responsibilities for clusters are the first
                # parent's first moment:
                # Shape(p)      = [Nn,..,N0,K]
                p = u_parents[0][0]
                # Move the cluster axis to the proper place:
                # Shape(p)      = [Nn,..,K,..,N0]
                p = utils.moveaxis(p, -1, self.cluster_plate)
                # Add axes for variable dimensions to the contributions
                # Shape(p)      = [Nn,..,K,..,N0,1,..,1]
                p = utils.add_trailing_axes(p, D)

                if self.cluster_plate < 0:
                    # Add the variable dimensions
                    cluster_axis = self.cluster_plate - D

                # Add axis for clusters:
                # Shape(m)      = [Nn,..,1,..,N0,Dd,..,D0]
                #m[i] = np.expand_dims(m[i], axis=cluster_axis)

                #
                # TODO: You could do summing here already so that
                # you wouldn't compute huge matrices as
                # intermediate result. Use einsum.

                # Compute the message contributions for each
                # cluster:
                # Shape(result) = [Nn,..,K,..,N0,Dd,..,D0]
                m[i] = m[i] * p

            return m

    def compute_phi_from_parents(self, *u_parents, mask=True):

        # Compute weighted average of the parameters

        # Cluster parameters
        Phi = self.distribution.compute_phi_from_parents(*(u_parents[1:]))
        # Contributions/weights/probabilities
        P = u_parents[0][0]

        phi = list()

        for ind in range(len(Phi)):
            # Compute element-wise product and then sum over K clusters.
            # Note that the dimensions aren't perfectly aligned because
            # the cluster dimension (K) may be arbitrary for phi, and phi
            # also has dimensions (Dd,..,D0) of the parameters.
            # Shape(phi)    = [Nn,..,K,..,N0,Dd,..,D0]
            # Shape(p)      = [Nn,..,N0,K]
            # Shape(result) = [Nn,..,N0,Dd,..,D0]
            # General broadcasting rules apply for Nn,..,N0, that is,
            # preceding dimensions may be missing or dimension may be
            # equal to one. Probably, shape(phi) has lots of missing
            # dimensions and/or dimensions that are one.

            if self.cluster_plate < 0:
                cluster_axis = self.cluster_plate - self.distribution.ndims[ind]
            #else:
            #    cluster_axis = cluster_plate

            # Move cluster axis to the last:
            # Shape(phi)    = [Nn,..,N0,Dd,..,D0,K]
            phi.append(utils.moveaxis(Phi[ind], cluster_axis, -1))

            # Add axes to p:
            # Shape(p)      = [Nn,..,N0,K,1,..,1]
            p = utils.add_trailing_axes(P, self.distribution.ndims[ind])
            # Move cluster axis to the last:
            # Shape(p)      = [Nn,..,N0,1,..,1,K]
            p = utils.moveaxis(p, -(self.distribution.ndims[ind]+1), -1)

            # Now the shapes broadcast perfectly and we can sum
            # p*phi over the last axis:
            # Shape(result) = [Nn,..,N0,Dd,..,D0]
            phi[ind] = utils.sum_product(p, phi[ind], axes_to_sum=-1)

        return phi

    def compute_moments_and_cgf(self, phi, mask=True):
        return self.distribution.compute_moments_and_cgf(phi, mask=mask)

    def compute_cgf_from_parents(self, *u_parents):

        # Compute weighted average of g over the clusters.

        # Shape(g)      = [Nn,..,K,..,N0]
        # Shape(p)      = [Nn,..,N0,K]
        # Shape(result) = [Nn,..,N0]

        # Compute g for clusters:
        # Shape(g)      = [Nn,..,K,..,N0]
        g = self.distribution.compute_cgf_from_parents(*(u_parents[1:]))

        # Move cluster axis to last:
        # Shape(g)      = [Nn,..,N0,K]
        g = utils.moveaxis(g, self.cluster_plate, -1)

        # Cluster assignments/contributions/probabilities/weights:
        # Shape(p)      = [Nn,..,N0,K]
        p = u_parents[0][0]

        # Weighted average of g over the clusters. As p and g are
        # properly aligned, you can just sum p*g over the last
        # axis and utilize broadcasting:
        # Shape(result) = [Nn,..,N0]
        g = utils.sum_product(p, g, axes_to_sum=-1)

        return g

    def compute_fixed_moments_and_f(self, x, mask=True):
        """ Compute u(x) and f(x) for given x. """
        return self.distribution.compute_fixed_moments_and_f(x, mask=True)

class Mixture(ExponentialFamily):

    @useconstructor
    def __init__(self, z, node_class, *args, cluster_plate=-1, **kwargs):
        self.cluster_plate = cluster_plate
        super().__init__(z, *args, **kwargs)

    @classmethod
    def _constructor(cls, z, node_class, *args, cluster_plate=-1, **kwargs):
        """
        Constructs distribution and statistics objects.
        """
        if cluster_plate >= 0:
            raise Exception("Give negative value for axis index cluster_plates")

        # TODO/FIXME: Constant (non-node, numeric) z is a bit
        # non-trivial. Constant z is an array of cluster assignments, e.g.,
        # [2,0,2,3,1,2]. However, it is not possible to know the number of
        # clusters from this. It could be 4 but it could be 10 as well.
        # Thus, we can't create a constant node from z because the number of
        # clusters is required by constant categorical. It might be possible
        # to infer the number of clusters from the cluster_plate axis of the
        # other parameters but that is not trivial. A simple solution is to
        # require the user to provide the number of clusters when it can't
        # be inferred otherwise. Anyway, this is left for future work.

        if not hasattr(z, '_convert'):
            raise NotImplementedError("Constant cluster assignments are "
                                      "not yet implemented")

        # Convert a node to get the number of clusters
        original_z = z
        z = z._convert(CategoricalStatistics)
        K = z.dims[0][0]
        # Delete the conversion node if a conversion was done so it won't stay
        # haunting.
        # TODO/FIXME: What if the conversion was done by using two or more
        # consecutive conversion nodes? This would only delete the last
        # node. This whole problem may require further thinking..
        if z is not original_z:
            z.delete()

        # Get the stuff for the mixed distribution
        (dims, distribution, statistics, parent_statistics) = \
          node_class._constructor(*args)

        # Convert the distribution to a mixture
        distribution = MixtureDistribution(distribution, cluster_plate)

        # Add cluster assignments to parents
        parent_statistics = (CategoricalStatistics(K),) + parent_statistics

        return (dims,
                distribution,
                statistics,
                parent_statistics)

    def _plates_to_parent(self, index):
        if index == 0:
            return self.plates
        else:
            if self.cluster_plate < 0:
                plates = list(self.plates)
                if self.cluster_plate < 0:
                    k = len(self.plates) + self.cluster_plate + 1
                else:
                    k = self.cluster_plate
                plates.insert(k, self.parents[0].dims[0][0])
                plates = tuple(plates)

            return plates

    def _plates_from_parent(self, index):
        if index == 0:
            return self.parents[index].plates
        else:
            plates = list(self.parents[index].plates)
            # Remove the cluster plate, if the parent has it
            if len(plates) >= abs(self.cluster_plate):
                plates.pop(self.cluster_plate)
            return tuple(plates)

    def integrated_logpdf_from_parents(self, x, index):

        """ Approximates the posterior predictive pdf \int
        p(x|parents) q(parents) dparents in log-scale as \int
        q(parents_i) exp( \int q(parents_\i) \log p(x|parents)
        dparents_\i ) dparents_i."""

        if index == 0:
            # Integrate out the cluster assignments

            # First, integrate the cluster parameters in log-scale

            # compute_logpdf(cls, u, phi, g, f):

            # Shape(x) = [M1,..,Mm,N1,..,Nn,D1,..,Dd]
            # Add the cluster axis to x:
            # Shape(x) = [M1,..,Mm,N1,..,1,..,Nn,D1,..,Dd]
            cluster_axis = self.cluster_plate - \
                           self._statistics.ndim_observations
            x = np.expand_dims(x, axis=cluster_axis)

            u_parents = self._message_from_parents()

            # Shape(u) = [M1,..,Mm,N1,..,1,..,Nn,D1,..,Dd]
            # Shape(f) = [M1,..,Mm,N1,..,1,..,Nn]
            (u, f) = self._distribution.distribution.compute_fixed_moments_and_f(x)
            # Shape(phi) = [N1,..,K,..,Nn,D1,..,Dd]
            phi = self._distribution.distribution.compute_phi_from_parents(*(u_parents[1:]))
            # Shape(g) = [N1,..,K,..,Nn]
            g = self._distribution.distribution.compute_cgf_from_parents(*(u_parents[1:]))
            # Shape(lpdf) = [M1,..,Mm,N1,..,K,..,Nn]
            lpdf = self._distribution.distribution.compute_logpdf(u, phi, g, f)

            # From logpdf to pdf, but avoid over/underflow
            lpdf_max = np.max(lpdf, axis=self.cluster_plate, keepdims=True)
            pdf = np.exp(lpdf-lpdf_max)

            # Move cluster axis to be the last:
            # Shape(pdf) = [M1,..,Mm,N1,..,Nn,K]
            pdf = utils.moveaxis(pdf, self.cluster_plate, -1)

            # Cluster assignments/probabilities/weights
            # Shape(p) = [N1,..,Nn,K]
            p = u_parents[0][0]

            # Weighted average. TODO/FIXME: Use einsum!
            # Shape(pdf) = [M1,..,Mm,N1,..,Nn]
            pdf = np.sum(pdf * p, axis=self.cluster_plate)

            # Back to log-scale (add the overflow fix!)
            lpdf_max = np.squeeze(lpdf_max, axis=self.cluster_plate)
            lpdf = np.log(pdf) + lpdf_max

            return lpdf

        raise NotImplementedError()
<|endoftext|>


<commit_before>import numpy

from chainer import functions
from chainer import testing

@testing.parameterize(*testing.product({
    'shape': [
        # c, x, y, output
        ((3, 2, 4),) * 4,
        ((4,), (3, 1, 1), (2, 1), (3, 2, 4)),
    ],
    'dtype': [numpy.float16, numpy.float32, numpy.float32],
}))
@testing.inject_backend_tests(
    None,
    # CPU tests
    [
        {},
    ]
    # GPU tests
    + testing.product({
        'use_cuda': [True],
        'use_cudnn': ['never', 'always'],
        'cuda_device': [0, 1],
    })
    # ChainerX tests
    + testing.product({
        'use_chainerx': [True],
        'chainerx_device': ['native:0', 'cuda:0', 'cuda:1'],
    })
)
class TestWhere(testing.FunctionTestCase):

    def setUp(self):
        if self.dtype == numpy.float16:
            self.check_backward_options.update({
                'atol': 1e-3, 'rtol': 1e-3,
            })

    def generate_inputs(self):
        c_shape, x_shape, y_shape, out_shape = self.shape
        c = numpy.random.uniform(-1, 1, c_shape) > 0
        x = numpy.random.uniform(-1, 1, x_shape).astype(self.dtype)
        y = numpy.random.uniform(-1, 1, y_shape).astype(self.dtype)
        return c, x, y

    def forward_expected(self, inputs):
        c, x, y = inputs
        z_expected = numpy.where(c, x, y)
        return z_expected,

    def forward(self, inputs, devices):
        c, x, y = inputs
        z = functions.where(c, x, y)
        return z,

testing.run_module(__name__, __file__)
<commit_msg>Test `check_type_forward` of `F.where`<commit_after>import unittest

import numpy
import pytest

import chainer
from chainer import functions
from chainer import testing
from chainer.utils import type_check

@testing.parameterize(*testing.product({
    'shape': [
        # c, x, y, output
        ((3, 2, 4),) * 4,
        ((4,), (3, 1, 1), (2, 1), (3, 2, 4)),
    ],
    'dtype': [numpy.float16, numpy.float32, numpy.float32],
}))
@testing.inject_backend_tests(
    None,
    # CPU tests
    [
        {},
    ]
    # GPU tests
    + testing.product({
        'use_cuda': [True],
        'use_cudnn': ['never', 'always'],
        'cuda_device': [0, 1],
    })
    # ChainerX tests
    + testing.product({
        'use_chainerx': [True],
        'chainerx_device': ['native:0', 'cuda:0', 'cuda:1'],
    })
)
class TestWhere(testing.FunctionTestCase):

    def setUp(self):
        if self.dtype == numpy.float16:
            self.check_backward_options.update({
                'atol': 1e-3, 'rtol': 1e-3,
            })

    def generate_inputs(self):
        c_shape, x_shape, y_shape, out_shape = self.shape
        c = numpy.random.uniform(-1, 1, c_shape) > 0
        x = numpy.random.uniform(-1, 1, x_shape).astype(self.dtype)
        y = numpy.random.uniform(-1, 1, y_shape).astype(self.dtype)
        return c, x, y

    def forward_expected(self, inputs):
        c, x, y = inputs
        z_expected = numpy.where(c, x, y)
        return z_expected,

    def forward(self, inputs, devices):
        c, x, y = inputs
        z = functions.where(c, x, y)
        return z,

class TestWhereTypeCheck(unittest.TestCase):

    def check_forward_raises(self, c_data, x_data, y_data):
        c = chainer.Variable(c_data)
        x = chainer.Variable(x_data)
        y = chainer.Variable(y_data)
        with pytest.raises(type_check.InvalidType):
            functions.where(c, x, y)

    def test_cond_int(self):
        c_data = numpy.zeros(3, numpy.int32)
        x_data = numpy.zeros(3, numpy.float32)
        y_data = numpy.zeros(3, numpy.float32)
        self.check_forward_raises(c_data, x_data, y_data)

    def test_xy_precision(self):
        c_data = numpy.zeros(3, numpy.bool_)
        x_data = numpy.zeros(3, numpy.float32)
        y_data = numpy.zeros(3, numpy.float64)
        self.check_forward_raises(c_data, x_data, y_data)

    def test_shape(self):
        c_data = numpy.zeros(3, numpy.bool_)
        x_data = numpy.zeros(1, numpy.float32)
        y_data = numpy.zeros(2, numpy.float32)
        self.check_forward_raises(c_data, x_data, y_data)

testing.run_module(__name__, __file__)
<|endoftext|>


<commit_before>import os
import StringIO

try:
    import json
except ImportError:
    import simplejson as json

from bento.core.utils import \
    subst_vars, normalize_path, unnormalize_path
from bento.core.pkg_objects import \
    Executable

import bento.compat.api as compat

def ipkg_meta_from_pkg(pkg):
    """Return meta dict for Installed pkg from a PackageDescription
    instance."""
    meta = {}
    for m in ["name", "version", "summary", "url", "author",
              "author_email", "license", "download_url", "description",
              "platforms", "classifiers", "install_requires",
              "top_levels"]:
        meta[m] = getattr(pkg, m)
    return meta

class InstalledSection(object):
    @classmethod
    def from_data_files(cls, name, data_files):
        return cls("datafiles", name,
                   data_files.source_dir,
                   data_files.target_dir,
                   data_files.files)

    def __init__(self, tp, name, srcdir, target, files):
        self.tp = tp
        self.name = name
        if os.sep != "/":
            self.source_dir = normalize_path(srcdir)
            self.target_dir = normalize_path(target)
            self.files = [normalize_path(path) for path in files]
        else:
            self.source_dir = srcdir
            self.target_dir = target
            self.files = files

    @property
    def fullname(self):
        return self.tp + ":" + self.name

def iter_source_files(file_sections):
    for kind in file_sections:
        if not kind in ["executables"]:
            for name, section in file_sections[kind].items():
                for f in section:
                    yield f[0]

def iter_files(file_sections):
    if os.sep != "/":
        for kind in file_sections:
            for name, section in file_sections[kind].items():
                for source, target in section:
                    yield kind, unnormalize_path(source), unnormalize_path(target)
    else:
        for kind in file_sections:
            for name, section in file_sections[kind].items():
                for source, target in section:
                    yield kind, source, target

class InstalledPkgDescription(object):
    @classmethod
    def from_egg(cls, egg_path):
        zid = compat.ZipFile(egg_path)
        try:
            data = json.loads(zid.read("EGG-INFO/ipkg.info"))
            return cls.from_json_dict(data)
        finally:
            zid.close()

    @classmethod
    def from_json_dict(cls, d):
        return cls.__from_data(d)

    @classmethod
    def from_string(cls, s):
        return cls.__from_data(json.loads(s))

    @classmethod
    def from_file(cls, filename):
        fid = open(filename)
        try:
            return cls.__from_data(json.load(fid))
        finally:
            fid.close()

    @classmethod
    def __from_data(cls, data):
        def _encode_kw(d):
            return dict([(k.encode(), v) for k, v in d.items()])

        meta_vars = _encode_kw(data["meta"])
        path_vars = data["variables"]["paths"]

        executables = {}
        for name, executable in data["variables"]["executables"].items():
            executables[name] = Executable.from_parse_dict(_encode_kw(executable))

        file_sections = {}

        def json_to_file_section(data):
            tp, section_name = data["name"].split(":", 1)
            section = InstalledSection(tp, section_name, data["source_dir"],
                                       data["target_dir"], data["files"])
            return tp, section_name, section

        for section in data["file_sections"]:
            tp, name, files = json_to_file_section(section)
            if tp in file_sections:
                if name in file_sections[tp]:
                    raise ValueError("section %s of type %s already exists !" % (name, type))
                file_sections[tp][name] = files
            else:
                file_sections[tp] = {name: files}
        return cls(file_sections, meta_vars, path_vars, executables)

    def __init__(self, files, meta, path_options, executables):
        self.files = files
        self.meta = meta
        self.path_variables = path_options
        self.executables = executables

    def write(self, filename):
        fid = open(filename, "w")
        try:
            return self._write(fid)
        finally:
            fid.close()

    def _write(self, fid):
        def executable_to_json(executable):
            return {"name": executable.name,
                    "module": executable.module,
                    "function": executable.function}

        def section_to_json(section):
            return {"name": section.fullname,
                    "source_dir": section.source_dir,
                    "target_dir": section.target_dir,
                    "files": section.files}

        data = {}
        data["meta"] = self.meta

        executables = dict([(k, executable_to_json(v)) \
                            for k, v in self.executables.items()])
        variables = {"paths": self.path_variables,
                     "executables": executables}
        data["variables"] = variables

        file_sections = []
        for tp, value in self.files.items():
            if tp in ["pythonfiles", "bentofiles"]:
                for i in value.values():
                    i.srcdir = "$_srcrootdir"
                    file_sections.append(section_to_json(i))
            elif tp in ["datafiles", "extensions", "executables",
                        "compiled_libraries"]:
                for i in value.values():
                    file_sections.append(section_to_json(i))
            else:
                raise ValueError("Unknown section %s" % tp)
        data["file_sections"] = file_sections
        if os.environ.has_key("BENTOMAKER_PRETTY"):
            json.dump(data, fid, sort_keys=True, indent=4)
        else:
            json.dump(data, fid, separators=(',', ':'))

    def resolve_paths(self, src_root_dir="."):
        self.path_variables['_srcrootdir'] = src_root_dir

        file_sections = {}
        for tp in self.files:
            file_sections[tp] = {}
            for name, section in self.files[tp].items():
                srcdir = subst_vars(section.source_dir, self.path_variables)
                target = subst_vars(section.target_dir, self.path_variables)

                file_sections[tp][name] = \
                        [(os.path.join(srcdir, f), os.path.join(target, f))
                         for f in section.files]

        return file_sections
<commit_msg>REF: split name/category in ipkg.info.<commit_after>import os
import StringIO

try:
    import json
except ImportError:
    import simplejson as json

from bento.core.utils import \
    subst_vars, normalize_path, unnormalize_path
from bento.core.pkg_objects import \
    Executable

import bento.compat.api as compat

def ipkg_meta_from_pkg(pkg):
    """Return meta dict for Installed pkg from a PackageDescription
    instance."""
    meta = {}
    for m in ["name", "version", "summary", "url", "author",
              "author_email", "license", "download_url", "description",
              "platforms", "classifiers", "install_requires",
              "top_levels"]:
        meta[m] = getattr(pkg, m)
    return meta

class InstalledSection(object):
    @classmethod
    def from_data_files(cls, name, data_files):
        return cls("datafiles", name,
                   data_files.source_dir,
                   data_files.target_dir,
                   data_files.files)

    def __init__(self, category, name, srcdir, target, files):
        self.category = category
        self.name = name
        if os.sep != "/":
            self.source_dir = normalize_path(srcdir)
            self.target_dir = normalize_path(target)
            self.files = [normalize_path(path) for path in files]
        else:
            self.source_dir = srcdir
            self.target_dir = target
            self.files = files

def iter_source_files(file_sections):
    for kind in file_sections:
        if not kind in ["executables"]:
            for name, section in file_sections[kind].items():
                for f in section:
                    yield f[0]

def iter_files(file_sections):
    if os.sep != "/":
        for kind in file_sections:
            for name, section in file_sections[kind].items():
                for source, target in section:
                    yield kind, unnormalize_path(source), unnormalize_path(target)
    else:
        for kind in file_sections:
            for name, section in file_sections[kind].items():
                for source, target in section:
                    yield kind, source, target

class InstalledPkgDescription(object):
    @classmethod
    def from_egg(cls, egg_path):
        zid = compat.ZipFile(egg_path)
        try:
            data = json.loads(zid.read("EGG-INFO/ipkg.info"))
            return cls.from_json_dict(data)
        finally:
            zid.close()

    @classmethod
    def from_json_dict(cls, d):
        return cls.__from_data(d)

    @classmethod
    def from_string(cls, s):
        return cls.__from_data(json.loads(s))

    @classmethod
    def from_file(cls, filename):
        fid = open(filename)
        try:
            return cls.__from_data(json.load(fid))
        finally:
            fid.close()

    @classmethod
    def __from_data(cls, data):
        def _encode_kw(d):
            return dict([(k.encode(), v) for k, v in d.items()])

        meta_vars = _encode_kw(data["meta"])
        path_vars = data["variables"]["paths"]

        executables = {}
        for name, executable in data["variables"]["executables"].items():
            executables[name] = Executable.from_parse_dict(_encode_kw(executable))

        file_sections = {}

        def json_to_file_section(data):
            category = data["category"]
            name = data["name"]
            section = InstalledSection(category, name, data["source_dir"],
                                       data["target_dir"], data["files"])
            return category, name, section

        for section in data["file_sections"]:
            tp, name, files = json_to_file_section(section)
            if tp in file_sections:
                if name in file_sections[tp]:
                    raise ValueError("section %s of type %s already exists !" % (name, type))
                file_sections[tp][name] = files
            else:
                file_sections[tp] = {name: files}
        return cls(file_sections, meta_vars, path_vars, executables)

    def __init__(self, files, meta, path_options, executables):
        self.files = files
        self.meta = meta
        self.path_variables = path_options
        self.executables = executables

    def write(self, filename):
        fid = open(filename, "w")
        try:
            return self._write(fid)
        finally:
            fid.close()

    def _write(self, fid):
        def executable_to_json(executable):
            return {"name": executable.name,
                    "module": executable.module,
                    "function": executable.function}

        def section_to_json(section):
            return {"name": section.name,
                    "category": section.category,
                    "source_dir": section.source_dir,
                    "target_dir": section.target_dir,
                    "files": section.files}

        data = {}
        data["meta"] = self.meta

        executables = dict([(k, executable_to_json(v)) \
                            for k, v in self.executables.items()])
        variables = {"paths": self.path_variables,
                     "executables": executables}
        data["variables"] = variables

        file_sections = []
        for category, value in self.files.items():
            if category in ["pythonfiles", "bentofiles"]:
                for i in value.values():
                    i.srcdir = "$_srcrootdir"
                    file_sections.append(section_to_json(i))
            elif category in ["datafiles", "extensions", "executables",
                        "compiled_libraries"]:
                for i in value.values():
                    file_sections.append(section_to_json(i))
            else:
                raise ValueError("Unknown section %s" % category)
        data["file_sections"] = file_sections
        if os.environ.has_key("BENTOMAKER_PRETTY"):
            json.dump(data, fid, sort_keys=True, indent=4)
        else:
            json.dump(data, fid, separators=(',', ':'))

    def resolve_paths(self, src_root_dir="."):
        self.path_variables['_srcrootdir'] = src_root_dir

        file_sections = {}
        for category in self.files:
            file_sections[category] = {}
            for name, section in self.files[category].items():
                srcdir = subst_vars(section.source_dir, self.path_variables)
                target = subst_vars(section.target_dir, self.path_variables)

                file_sections[category][name] = \
                        [(os.path.join(srcdir, f), os.path.join(target, f))
                         for f in section.files]

        return file_sections
<|endoftext|>


<commit_before># Copyright: 2013 Bastian Blank <bastian@waldi.eu.org>
# License: BSD 2-clause, see LICENSE for details.

import collections
import os
import pickle
import logging

logger = logging.getLogger(__name__)

class Storage(object):
    """
    Filesystem storage - store meta and data into separate files in a directory.
    """
    def __init__(self, app):
        self.directory = app.config['STORAGE_FILESYSTEM_DIRECTORY']
        app.storage = self

    def _filename(self, name):
        if '/' in name:
            raise RuntimeError
        return os.path.join(self.directory, name)

    def _open(self, name, mode):
        basefilename = self._filename(name)
        file_data = open(basefilename + '.data', mode)
        file_meta = open(basefilename + '.meta', mode)
        return Item(file_data, file_meta)

    def create(self, name, size):
        return self._open(name, 'w+bx')

    def open(self, name):
        return self._open(name, 'rb')

    def openwrite(self, name):
        return self._open(name, 'r+b')

    def remove(self, name):
        basefilename = self._filename(name)
        file_data = basefilename + '.data'
        file_meta = basefilename + '.meta'
        try:
            os.remove(file_data)
        except OSError as e:
            logger.error("Could not delete file: %s\n %s" % (file_data, str(e)))
            raise
        try:
            os.remove(file_meta)
        except OSError as e:
            logger.error("Could not delete file: %s\n %s" % (file_meta, str(e)))
            raise

    def __iter__(self):
        names = [fn[:-5] for fn in os.listdir(self.directory)
                 if fn.endswith('.meta')]
        for name in names:
            yield name

class Item(object):
    """
    Represents an open item.

    :ivar data: Open file-like object to data.
    """
    def __init__(self, file_data, file_meta):
        """
        :param file_data: Open file-like object to data file.
        :param file_meta: Open file-like object to meta file.
        """
        self.data = Data(file_data)
        self.meta = Meta(file_meta)

    def __enter__(self):
        return self

    def __exit__(self, *exc):
        self.data.close()
        self.meta.close()

    close = __exit__

class Data(object):
    """
    Data of item.
    """
    def __init__(self, file_data):
        self._file = file_data

    @property
    def size(self):
        self._file.seek(0, os.SEEK_END)
        return self._file.tell()

    def close(self):
        self._file.close()

    def read(self, size, offset):
        self._file.seek(offset)
        return self._file.read(size)

    def write(self, data, offset):
        self._file.seek(offset)
        return self._file.write(data)

class Meta(collections.MutableMapping):
    """
    Meta-data of item.
    """
    def __init__(self, file_meta):
        self._file = file_meta
        data = file_meta.read()
        if data:
            self._data = pickle.loads(data)
            self._changed = False
        else:
            self._data = {}
            self._changed = True

    def __iter__(self):
        return iter(self._data)

    def __len__(self):
        return len(self._data)

    def __getitem__(self, key):
        return self._data[key]

    def __setitem__(self, key, value):
        self._data[key] = value
        self._changed = True

    def __delitem__(self, key):
        del self._data[key]
        self._changed = True

    def close(self):
        self.write()
        self._file.close()

    def write(self):
        if self._changed:
            self._write()
            self._changed = False

    def _write(self):
        self._file.seek(0)
        pickle.dump(self._data, self._file)
        self._file.seek(0)
<commit_msg>raise error and log when no file can be written to STORAGE_FILESYSTEM_DIRECTORY<commit_after># Copyright: 2013 Bastian Blank <bastian@waldi.eu.org>
# License: BSD 2-clause, see LICENSE for details.

import collections
import os
import pickle
import logging
import tempfile

logger = logging.getLogger(__name__)

class Storage(object):
    """
    Filesystem storage - store meta and data into separate files in a directory.
    """
    def __init__(self, app):
        storage_dir = app.config['STORAGE_FILESYSTEM_DIRECTORY']
        try:
            _, tmp_file = tempfile.mkstemp(dir=storage_dir)
        except OSError as e:
            logger.error("Could write file in storage directory: %s\n %s", storage_dir, e)
            raise
        else:
            os.remove(tmp_file)
            self.directory = storage_dir
            app.storage = self

    def _filename(self, name):
        if '/' in name:
            raise RuntimeError
        return os.path.join(self.directory, name)

    def _open(self, name, mode):
        basefilename = self._filename(name)
        file_data = open(basefilename + '.data', mode)
        file_meta = open(basefilename + '.meta', mode)
        return Item(file_data, file_meta)

    def create(self, name, size):
        return self._open(name, 'w+bx')

    def open(self, name):
        return self._open(name, 'rb')

    def openwrite(self, name):
        return self._open(name, 'r+b')

    def remove(self, name):
        basefilename = self._filename(name)
        file_data = basefilename + '.data'
        file_meta = basefilename + '.meta'
        try:
            os.remove(file_data)
        except OSError as e:
            logger.error("Could not delete file: %s\n %s" % (file_data, str(e)))
            raise
        try:
            os.remove(file_meta)
        except OSError as e:
            logger.error("Could not delete file: %s\n %s" % (file_meta, str(e)))
            raise

    def __iter__(self):
        names = [fn[:-5] for fn in os.listdir(self.directory)
                 if fn.endswith('.meta')]
        for name in names:
            yield name

class Item(object):
    """
    Represents an open item.

    :ivar data: Open file-like object to data.
    """
    def __init__(self, file_data, file_meta):
        """
        :param file_data: Open file-like object to data file.
        :param file_meta: Open file-like object to meta file.
        """
        self.data = Data(file_data)
        self.meta = Meta(file_meta)

    def __enter__(self):
        return self

    def __exit__(self, *exc):
        self.data.close()
        self.meta.close()

    close = __exit__

class Data(object):
    """
    Data of item.
    """
    def __init__(self, file_data):
        self._file = file_data

    @property
    def size(self):
        self._file.seek(0, os.SEEK_END)
        return self._file.tell()

    def close(self):
        self._file.close()

    def read(self, size, offset):
        self._file.seek(offset)
        return self._file.read(size)

    def write(self, data, offset):
        self._file.seek(offset)
        return self._file.write(data)

class Meta(collections.MutableMapping):
    """
    Meta-data of item.
    """
    def __init__(self, file_meta):
        self._file = file_meta
        data = file_meta.read()
        if data:
            self._data = pickle.loads(data)
            self._changed = False
        else:
            self._data = {}
            self._changed = True

    def __iter__(self):
        return iter(self._data)

    def __len__(self):
        return len(self._data)

    def __getitem__(self, key):
        return self._data[key]

    def __setitem__(self, key, value):
        self._data[key] = value
        self._changed = True

    def __delitem__(self, key):
        del self._data[key]
        self._changed = True

    def close(self):
        self.write()
        self._file.close()

    def write(self):
        if self._changed:
            self._write()
            self._changed = False

    def _write(self):
        self._file.seek(0)
        pickle.dump(self._data, self._file)
        self._file.seek(0)
<|endoftext|>


<commit_before>'''
Created on 27.05.2015

@author: vvladych
'''
from gi.repository import Gtk

from forecastmgmt.ui.forecast.abstract_data_process_component import AbstractDataOverviewComponent, AbstractDataManipulationComponent, AbstractDataProcessComponent

from forecastmgmt.ui.ui_tools import TreeviewColumn, show_info_dialog

from forecastmgmt.model.model_text import ModelText

from forecastmgmt.dao.db_connection import get_db_connection
import psycopg2.extras

class ModelProcessComponent(AbstractDataProcessComponent):

    def __init__(self, forecast):
        super(ModelProcessComponent, self).__init__(ModelManipulationComponent(forecast, ModelOverviewComponent(forecast)))

class ModelManipulationComponent(AbstractDataManipulationComponent):

    def __init__(self, forecast, overview_component):
        super(ModelManipulationComponent, self).__init__(overview_component)
        self.forecast=forecast

    def create_layout(self, parent_layout_grid, row):
        row+=1
        # Add model text view
        scrolledwindow= Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        self.forecast_model_textview=Gtk.TextView()
        self.forecast_model_textview.get_buffer().set_text(self.forecast.model_text.model_text)
        scrolledwindow.add(self.forecast_model_textview)
        parent_layout_grid.attach(scrolledwindow,0,row,1,1)

        row+=1
        # Add save button
        self.save_model_button=Gtk.Button("Save", Gtk.STOCK_SAVE)
        parent_layout_grid.attach(self.save_model_button,1,row,1,1)
        self.save_model_button.connect("clicked", self.save_model_action)

    def save_model_action(self, widget):
        textbuffer=self.forecast_model_textview.get_buffer()
        model_text=textbuffer.get_text(textbuffer.get_start_iter(),textbuffer.get_end_iter(),True)
        if self.forecast.model_text==None:
            show_info_dialog("insert text")
            ModelText(forecast_sid=self.forecast.sid, model_text=model_text).insert()
            self.forecast.load_model_text()
        else:
            if self.forecast.model_text.model_text!=model_text:
                self.forecast.model_text.update(model_text=model_text)
                show_info_dialog("update model text")
                self.forecast.load_model_text()
                self.forecast_model_textview.get_buffer().set_text(self.forecast.model_text.model_text)
            else:
                show_info_dialog("nothing to update")

class ModelOverviewComponent(AbstractDataOverviewComponent):

    treecolumns=[TreeviewColumn("model_text_sid", 0, True), TreeviewColumn("model text", 1, False)]

    def __init__(self, forecast):
        self.forecast=forecast
        super(ModelOverviewComponent, self).__init__(ModelOverviewComponent.treecolumns)

    def populate_model(self):
        self.treemodel.clear()
        cur=get_db_connection().cursor(cursor_factory=psycopg2.extras.NamedTupleCursor)
        data=(self.forecast.sid,)
        cur.execute("""SELECT
                        sid, substring(model_text from 1 for 100) as model_text
                        FROM
                        fc_model_text
                        WHERE
                        forecast_sid=%s
                        """,data)
        for p in cur.fetchall():
            self.treemodel.append([ "%s" % p.sid, "%s" % p.model_text, "", "", ""])
        cur.close()<commit_msg>layout for model process component implemented<commit_after>'''
Created on 27.05.2015

@author: vvladych
'''
from gi.repository import Gtk

from forecastmgmt.ui.forecast.abstract_data_process_component import AbstractDataOverviewComponent, AbstractDataManipulationComponent, AbstractDataProcessComponent

from forecastmgmt.ui.ui_tools import TreeviewColumn, show_info_dialog

from forecastmgmt.dao.db_connection import get_db_connection
import psycopg2.extras

from forecastmgmt.model.fc_object import FCObject
from forecastmgmt.model.fc_object_property import FCObjectProperty

class ModelProcessComponent(AbstractDataProcessComponent):

    def __init__(self, forecast):
        super(ModelProcessComponent, self).__init__(ModelManipulationComponent(forecast, ModelOverviewComponent(forecast)))

class ModelManipulationComponent(AbstractDataManipulationComponent):

    def __init__(self, forecast, overview_component):
        super(ModelManipulationComponent, self).__init__(overview_component)
        self.forecast=forecast

    def create_layout(self, parent_layout_grid, row):
        self.parent_layout_grid=parent_layout_grid
        row+=1
        # choose object property
        object_chooser_label = Gtk.Label("Choose object")
        object_chooser_label.set_justify(Gtk.Justification.LEFT)
        parent_layout_grid.attach(object_chooser_label,0,row,1,1)

        self.object_combobox_model=self.populate_object_combobox_model()
        self.object_combobox=Gtk.ComboBox.new_with_model_and_entry(self.object_combobox_model)
        self.object_combobox.set_entry_text_column(1)
        self.object_combobox.connect("changed", self.on_object_combobox_changed)
        parent_layout_grid.attach(self.object_combobox,1,row,1,1)

        self.object_property_combobox_model=Gtk.ListStore(str,str)
        self.object_property_combobox_model.append(["1", "test"])
        self.object_property_combobox=Gtk.ComboBox.new_with_model_and_entry(self.object_property_combobox_model)
        self.object_property_combobox.set_entry_text_column(1)
        parent_layout_grid.attach(self.object_property_combobox,2,row,1,1)

        # set point-in-time
        row+=2

        pit_label=Gtk.Label("Choose point-in-time")
        pit_label.set_justify(Gtk.Justification.LEFT)
        parent_layout_grid.attach(pit_label,0,row,1,1)

        self.state_date_day_textentry=Gtk.Entry()
        parent_layout_grid.attach(self.state_date_day_textentry,1,row,1,1)
        self.state_date_month_textentry=Gtk.Entry()
        parent_layout_grid.attach(self.state_date_month_textentry,2,row,1,1)
        self.state_date_year_textentry=Gtk.Entry()
        parent_layout_grid.attach(self.state_date_year_textentry,3,row,1,1)

        pit_choose_button=Gtk.Button("Pick date")
        parent_layout_grid.attach(pit_choose_button,4,row,1,1)
        pit_choose_button.connect("clicked", self.show_calendar)

        # set value
        row+=2
        object_property_value_label=Gtk.Label("Set value")
        object_property_value_label.set_justify(Gtk.Justification.LEFT)
        parent_layout_grid.attach(object_property_value_label,0,row,1,1)

        self.object_property_value_textentry=Gtk.Entry()
        parent_layout_grid.attach(self.object_property_value_textentry,1,row,2,1)

        # TODO: set precondition(s)

        row+=2

        self.add_state_button=Gtk.Button("Add", Gtk.STOCK_ADD)
        parent_layout_grid.attach(self.add_state_button,0,row,1,1)
        self.add_state_button.connect("clicked", self.add_state_action)

        self.delete_button=Gtk.Button("Delete", Gtk.STOCK_DELETE)
        self.delete_button.connect("clicked", self.delete_action)
        parent_layout_grid.attach(self.delete_button,1,row,1,1)

        # add / remove buttons

        # Add model text view

        row+=1

        return row

    def show_calendar(self, widget):
        self.calendar_window=Gtk.Dialog()
        self.calendar_window.action_area.hide()
        self.calendar_window.set_decorated(False)
        self.calendar_window.set_property('skip-taskbar-hint', True)
        self.calendar_window.set_size_request(200,200)

        self.calendar=Gtk.Calendar()
        self.calendar.connect('day-selected-double-click', self.day_selected, None)
        self.calendar_window.vbox.pack_start(self.calendar, True, True, 0)
        self.calendar.show()
        self.calendar_window.run()

    def day_selected(self, calendar, event):
        (year,month,day)=self.calendar.get_date()
        self.state_date_day_textentry.set_text("%s" % day)
        self.state_date_month_textentry.set_text("%s" % month)
        self.state_date_year_textentry.set_text("%s" % year)
        self.calendar_window.destroy()

    def get_active_object(self):
        tree_iter = self.object_combobox.get_active_iter()
        if tree_iter!=None:
            model = self.object_combobox.get_model()
            return model[tree_iter][0]
        else:
            print("please choose an object!")

    def on_object_combobox_changed(self, widget):
        self.populate_object_property_combobox_model(self.get_active_object())

    def populate_object_property_combobox_model(self, object_sid):
        self.object_property_combobox_model.clear()
        object_properties=FCObjectProperty().get_all_for_foreign_key(object_sid)
        for op in object_properties:
            self.object_property_combobox_model.append(["%s" % op.sid, op.common_name])

    def populate_object_combobox_model(self):
        combobox_model=Gtk.ListStore(str,str)
        object_list=FCObject().get_all()
        for o in object_list:
            combobox_model.append(["%s" % o.sid, o.common_name])
        return combobox_model

    def add_state_action(self, widget):
        print("add state")

    def delete_action(self, widget):
        print("delete chosen state")

class ModelOverviewComponent(AbstractDataOverviewComponent):

    treecolumns=[TreeviewColumn("model_text_sid", 0, True), TreeviewColumn("model text", 1, False)]

    def __init__(self, forecast):
        self.forecast=forecast
        super(ModelOverviewComponent, self).__init__(ModelOverviewComponent.treecolumns)

    def populate_model(self):
        print("hier")

<|endoftext|>


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

from django.conf.urls import patterns, url, include
from tastypie.api import Api
from apps.api.rfid.user import UserResource
from apps.api.rfid.events import AttendeeResource, EventResource, AttendanceEventResource

rfid_api = Api(api_name='rfid')

rfid_api.register(UserResource())
rfid_api.register(AttendeeResource())
rfid_api.register(AttendanceEventResource())

rfid_api.register(EventResource())

urlpatterns = patterns('',
    url(r'^', include(rfid_api.urls)),
)
<commit_msg>Modified urls.py in rfid api<commit_after># -*- coding: utf-8 -*-

from django.conf.urls import patterns, url, include
from tastypie.api import Api
from apps.api.rfid.user import UserResource
from apps.api.rfid.events import AttendeeResource, EventResource, AttendanceEventResource

rfid_api = Api(api_name='rfid')

rfid_api.register(UserResource())
rfid_api.register(AttendeeResource())
rfid_api.register(AttendanceEventResource())
rfid_api.register(EventResource())

urlpatterns = patterns('',
    url(r'^', include(rfid_api.urls)),
)
<|endoftext|>


<commit_before>from copy import copy
from django.template.defaultfilters import slugify
from tastypie import fields
from tastypie.resources import ModelResource
from tastypie.authorization import Authorization

from filebrowser.base import FileObject
from filebrowser.settings import VERSIONS

from apps.events.models import Event
from apps.events.models import Attendee
from apps.events.models import AttendanceEvent
from apps.events.models import CompanyEvent

from apps.companyprofile.models import Company

from apps.api.v0.authentication import UserResource

class AttendeeResource(ModelResource):
    user = fields.ToOneField(UserResource, 'user', full=True)

    class Meta:
        queryset = Attendee.objects.all()
        resource_name = 'attendees'

class CompanyResource(ModelResource):

    class Meta:
        queryset = Company.objects.all()
        resource_name = 'company'
        fields = ['image']
class CompanyEventResource(ModelResource):
    companies = fields.ToOneField(CompanyResource, 'company', full=True)
    class Meta:
        queryset = CompanyEvent.objects.all()
        resource_name ='companies'

class AttendanceEventResource(ModelResource):
    users = fields.ToManyField(AttendeeResource, 'attendees', full=False)

    class Meta:
        queryset = AttendanceEvent.objects.all()
        resource_name = 'attendance_event'

        # XXX: Noop authorization is probably not safe for producion
        authorization = Authorization()

class EventResource(ModelResource):
    author = fields.ToOneField(UserResource, 'author', full=True)
    company_event = fields.ToManyField(CompanyEventResource, 'companies', full=True, null=True, blank=True)
    attendance_event = fields.ToOneField(AttendanceEventResource, 'attendance_event', full=True, null=True, blank=True)

    def alter_list_data_to_serialize(self, request, data):
        # Renames list data 'object' to 'events'.
        if isinstance(data, dict):
            data['events'] = copy(data['objects'])
            del(data['objects'])
        return data

    # Making multiple images for the events
    def dehydrate(self, bundle):

        # Setting sluyg-field
        bundle.data['slug'] = slugify(bundle.data['title'])

        # If image is set
        if bundle.data['image']:
            # Parse to FileObject used by Filebrowser
            temp_image = FileObject(bundle.data['image'])

            # Itterate the different versions (by key)
            for ver in VERSIONS.keys():
                # Check if the key start with article_ (if it does, we want to crop to that size)
                if ver.startswith('events_'):
                    # Adding the new image to the object
                    bundle.data['image_'+ver] = temp_image.version_generate(ver).url

            # Unset the image-field
            del(bundle.data['image'])

        # Do the same thing for the company image
        if bundle.data['company_event']:
            for company in bundle.data['company_event']:
                temp_image = FileObject(company.data['companies'].data['image'])
                for ver in VERSIONS.keys():
                    if ver.startswith('companies_thumb'):
                        company.data['companies'].data['image_'+ver] = temp_image.version_generate(ver).url
                del(company.data['companies'].data['image'])

        # Returning washed object
        return bundle

    class Meta:
        queryset = Event.objects.all()
        resource_name = 'events'
        # XXX: Noop authorization is probably not safe for producion
        authorization = Authorization()

        include_absolute_url = True
        ordering = ['event_start']
        filtering = {
            'event_end' : ('gte',)
        }
<commit_msg>Fixed filtering on the main view<commit_after>from copy import copy
from django.template.defaultfilters import slugify
from tastypie import fields
from tastypie.resources import ModelResource
from tastypie.authorization import Authorization

from filebrowser.base import FileObject
from filebrowser.settings import VERSIONS

from apps.events.models import Event
from apps.events.models import Attendee
from apps.events.models import AttendanceEvent
from apps.events.models import CompanyEvent
from apps.events.utils import can_display_event

from apps.companyprofile.models import Company

from apps.api.v0.authentication import UserResource

class AttendeeResource(ModelResource):
    user = fields.ToOneField(UserResource, 'user', full=True)

    class Meta:
        queryset = Attendee.objects.all()
        resource_name = 'attendees'

class CompanyResource(ModelResource):

    class Meta:
        queryset = Company.objects.all()
        resource_name = 'company'
        fields = ['image']

class CompanyEventResource(ModelResource):
    companies = fields.ToOneField(CompanyResource, 'company', full=True)
    class Meta:
        queryset = CompanyEvent.objects.all()
        resource_name ='companies'

class AttendanceEventResource(ModelResource):
    users = fields.ToManyField(AttendeeResource, 'attendees', full=False)

    class Meta:
        queryset = AttendanceEvent.objects.all()
        resource_name = 'attendance_event'

        # XXX: Noop authorization is probably not safe for producion
        authorization = Authorization()

class EventResource(ModelResource):
    author = fields.ToOneField(UserResource, 'author', full=True)
    company_event = fields.ToManyField(CompanyEventResource, 'companies', full=True, null=True, blank=True)
    attendance_event = fields.ToOneField(AttendanceEventResource, 'attendance_event', full=True, null=True, blank=True)

    def alter_list_data_to_serialize(self, request, data):
        # Renames list data 'object' to 'events'.
        if isinstance(data, dict):
            data['events'] = copy(data['objects'])
            del(data['objects'])
        return data

    # Making multiple images for the events
    def dehydrate(self, bundle):

        # Setting sluyg-field
        bundle.data['slug'] = slugify(bundle.data['title'])

        # If image is set
        if bundle.data['image']:
            # Parse to FileObject used by Filebrowser
            temp_image = FileObject(bundle.data['image'])

            # Itterate the different versions (by key)
            for ver in VERSIONS.keys():
                # Check if the key start with article_ (if it does, we want to crop to that size)
                if ver.startswith('events_'):
                    # Adding the new image to the object
                    bundle.data['image_'+ver] = temp_image.version_generate(ver).url

            # Unset the image-field
            del(bundle.data['image'])

        # Do the same thing for the company image
        if bundle.data['company_event']:
            for company in bundle.data['company_event']:
                temp_image = FileObject(company.data['companies'].data['image'])
                for ver in VERSIONS.keys():
                    if ver.startswith('companies_thumb'):
                        company.data['companies'].data['image_'+ver] = temp_image.version_generate(ver).url
                del(company.data['companies'].data['image'])

        # Returning washed object
        return bundle

    def get_object_list(self, request):

        events = Event.objects.all()
        filtered_events = set()

        #Removes restricted events if the user does not belong to the right group
        for event in events:
            if can_display_event(event, request.user):
                filtered_events.add(event.pk)

        return Event.objects.filter(pk__in = filtered_events)

    class Meta:
        queryset = Event.objects.all()
        resource_name = 'events'
        # XXX: Noop authorization is probably not safe for producion
        authorization = Authorization()

        include_absolute_url = True
        ordering = ['event_start']
        filtering = {
            'event_end' : ('gte',)
        }
<|endoftext|>


<commit_before>from django.contrib import admin
from apps.article.models import Article, Tag, ArticleTag
from django.conf import settings
from filebrowser.settings import VERSIONS, ADMIN_THUMBNAIL

class ArticleTagAdmin(admin.ModelAdmin):
    model = ArticleTag

class ArticleTagInline(admin.TabularInline):
    model = ArticleTag
    max_num = 99
    extra = 0

class TagAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.changed_by = request.user
        if not change:
            obj.created_by = request.user
        obj.save()

class ArticleAdmin(admin.ModelAdmin):
    inlines = (ArticleTagInline,)
    list_display = ("heading", "created_by", "changed_by")

    # set the created and changed by fields
    def save_model(self, request, obj, form, change):
        if (obj.image):
            obj.image.version_generate(ADMIN_THUMBNAIL).url

            # Itterate the different versions (by key)
            for ver in VERSIONS.keys():
                # Check if the key start with article_ (if it does, we want to crop to that size)
                if ver.startswith('article_'):
                    obj.image.version_generate(ver).url

        obj.changed_by = request.user

        if not change:
            obj.created_by = request.user
        obj.save()

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instances in instances:
            instances.save()

admin.site.register(Article, ArticleAdmin)
admin.site.register(Tag, TagAdmin)
<commit_msg>Strip '.' from tag names to fix error<commit_after>from django.contrib import admin
from apps.article.models import Article, Tag, ArticleTag
from django.conf import settings
from filebrowser.settings import VERSIONS, ADMIN_THUMBNAIL

class ArticleTagAdmin(admin.ModelAdmin):
    model = ArticleTag

class ArticleTagInline(admin.TabularInline):
    model = ArticleTag
    max_num = 99
    extra = 0

class TagAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.changed_by = request.user
        if not change:
            obj.name = obj.name.replace('.', '')
            obj.created_by = request.user
        obj.save()

class ArticleAdmin(admin.ModelAdmin):
    inlines = (ArticleTagInline,)
    list_display = ("heading", "created_by", "changed_by")

    # set the created and changed by fields
    def save_model(self, request, obj, form, change):
        if (obj.image):
            obj.image.version_generate(ADMIN_THUMBNAIL).url

            # Itterate the different versions (by key)
            for ver in VERSIONS.keys():
                # Check if the key start with article_ (if it does, we want to crop to that size)
                if ver.startswith('article_'):
                    obj.image.version_generate(ver).url

        obj.changed_by = request.user

        if not change:
            obj.created_by = request.user
        obj.save()

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instances in instances:
            instances.save()

admin.site.register(Article, ArticleAdmin)
admin.site.register(Tag, TagAdmin)
<|endoftext|>


<commit_before>
<commit_msg>Update Client.py<commit_after>

<|endoftext|>