<commit_before># coding: utf-8
import types

import pandas as pd
from .seidel import Triangulator

def tesselate_shapes_frame(df_shapes, shape_i_columns):
    '''
    Tesselate each shape path into one or more triangles.

    Return `pandas.DataFrame` with columns storing the following fields
    for each row (where each row corresponds to a triangle vertex):

     - `shape_i_columns`: The shape path index column(s).
     - `triangle_i`: The integer triangle index within each electrode path.
     - `vertex_i`: The integer vertex index within each triangle.
    '''
    frames = []
    if isinstance(shape_i_columns, types.StringType):
        shape_i_columns = [shape_i_columns]

    for shape_i, df_path in df_shapes.groupby(shape_i_columns):
        triangulator = Triangulator(df_path[['x', 'y']].values)

        if not isinstance(shape_i, (types.ListType, types.TupleType)):
            shape_i = [shape_i]

        for i, triangle_i in enumerate(triangulator.triangles()):
            frame = pd.DataFrame(triangle_i, columns=['x', 'y']).reset_index()
            frame.rename(columns={'index': 'vertex_i'}, inplace=True)
            frame.insert(0, 'triangle_i', i)

            for i in xrange(len(shape_i_columns)):
                frame.insert(i, shape_i_columns[i], shape_i[i])
            frames.append(frame)

    return pd.concat(frames).reset_index(drop=True)
<commit_msg>Improve performance of tesselate_shapes_frame<commit_after># coding: utf-8
import types

import pandas as pd
from .seidel import Triangulator

def tesselate_shapes_frame(df_shapes, shape_i_columns):
    '''
    Tesselate each shape path into one or more triangles.

    Return `pandas.DataFrame` with columns storing the following fields
    for each row (where each row corresponds to a triangle vertex):

     - `shape_i_columns`: The shape path index column(s).
     - `triangle_i`: The integer triangle index within each electrode path.
     - `vertex_i`: The integer vertex index within each triangle.
    '''
    frames = []
    if isinstance(shape_i_columns, types.StringType):
        shape_i_columns = [shape_i_columns]

    for shape_i, df_path in df_shapes.groupby(shape_i_columns):
        triangulator = Triangulator(df_path[['x', 'y']].values)

        if not isinstance(shape_i, (types.ListType, types.TupleType)):
            shape_i = [shape_i]

        for i, triangle_i in enumerate(triangulator.triangles()):
            triangle_points_i = [shape_i + [i] + [j, x, y]
                                 for j, (x, y) in enumerate(triangle_i)]
            frames.extend(triangle_points_i)
    return pd.DataFrame(frames, columns=shape_i_columns +
                        ['triangle_i', 'vertex_i', 'x', 'y'])
<|endoftext|>


<commit_before># Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module defines the interface for Streaming AEAD."""

from __future__ import absolute_import
from __future__ import division
from __future__ import google_type_annotations
from __future__ import print_function

import abc
from typing import BinaryIO

class StreamingAead(object):
  """The interface for streaming authenticated encryption with associated data.

  Streaming encryption is typically used for encrypting large plaintexts such
  as large files. This interface supports a streaming interface for symmetric
  encryption with authentication. The underlying encryption modes are selected
  so that partial plaintext can be obtained fast by decrypting and
  authenticating just a part of the ciphertext.
  """

  __metaclass__ = abc.ABCMeta

  @abc.abstractmethod
  def new_encrypting_stream(self, ciphertext_destination: BinaryIO,
                            associated_data: bytes) -> BinaryIO:
    # pyformat: disable
    """Get a new encrypting stream that writes to ciphertext_destination.

    Args:
      ciphertext_destination: A writable binary file object to which ciphertext
        will be written. It must support write(), close(), closed, and
        writable().
      associated_data: Associated data to be used by the AEAD encryption. It is
        not included in the ciphertext and must be passed in as a parameter for
        decryption.

    The ciphertext_destination's write() method is expected to present one of
    the following three behaviours in the case of a partial or failed write():
      - return a non-negative integer number of bytes written
      - return None (equivalent to returning 0)
      - raise BlockingIOError with characters_written set correctly to a
        non-negative integer (equivalent to returning that integer)
    In the case of a full write, the number of bytes written should be returned.

    The standard BufferedIOBase and RawIOBase base classes exhibit these
    behaviours and are hence supported.

    Returns:
      An encrypting file object wrapper around 'ciphertext_destination', such
      that any bytes written to the wrapper are AEAD-encrypted using
      'associated_data' as associated authenticated data.

      It supports the following:
        write()
        close()
        closed
        tell()
        isatty()
        flush() (no-op)
        writable()
        readable()
        seekable()
        __enter__() and __exit__()
      Other methods, including read() and seek(), raise io.UnsupportedOperation.
      Closing the wrapper also closes the ciphertext_destination.

    Raises:
      tink.TinkError if the creation fails.
    """
    # pyformat: enable
    raise NotImplementedError()

  @abc.abstractmethod
  def new_decrypting_stream(self, ciphertext_source: BinaryIO,
                            associated_data: bytes) -> BinaryIO:
    """Get a new decrypting stream that reads from ciphertext_source.

    Args:
      ciphertext_source: A readable binary file object from which ciphertext
        will be read.
      associated_data: Associated data to be used by the AEAD decryption. It
        must match the associated_data supplied for the encryption.

    Returns:
      A decrypting file object wrapper around 'ciphertext_source', such that
      any bytes read from the wrapper are AEAD-decrypted using 'associated_data'
      as associated authenticated data.

      It supports the following:
        read()
        read1()
        readinto()
        readinto1()
        readline()
        readlines()
        readall()
        close()
        closed
        tell()
        isatty()
        flush() (no-op)
        readable()
        writable()
        seekable()
        __enter__() and __exit__()
        __iter__() and __next__()
      Other methods, including write() and seek(), raise
      io.UnsupportedOperation.
      Closing the wrapper also closes the ciphertext_source.

    Raises:
      tink.TinkError if the creation fails.

    """
    raise NotImplementedError()
<commit_msg>Add ciphertext_source read() conditions to docstring.<commit_after># Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module defines the interface for Streaming AEAD."""

from __future__ import absolute_import
from __future__ import division
from __future__ import google_type_annotations
from __future__ import print_function

import abc
from typing import BinaryIO

class StreamingAead(object):
  """The interface for streaming authenticated encryption with associated data.

  Streaming encryption is typically used for encrypting large plaintexts such
  as large files. This interface supports a streaming interface for symmetric
  encryption with authentication. The underlying encryption modes are selected
  so that partial plaintext can be obtained fast by decrypting and
  authenticating just a part of the ciphertext.
  """

  __metaclass__ = abc.ABCMeta

  @abc.abstractmethod
  def new_encrypting_stream(self, ciphertext_destination: BinaryIO,
                            associated_data: bytes) -> BinaryIO:
    # pyformat: disable
    """Get a new encrypting stream that writes to ciphertext_destination.

    Args:
      ciphertext_destination: A writable binary file object to which ciphertext
        will be written. It must support write(), close(), closed, and
        writable().
      associated_data: Associated data to be used by the AEAD encryption. It is
        not included in the ciphertext and must be passed in as a parameter for
        decryption.

    The ciphertext_destination's write() method is expected to present one of
    the following three behaviours in the case of a partial or failed write():
      - return a non-negative integer number of bytes written
      - return None (equivalent to returning 0)
      - raise BlockingIOError with characters_written set correctly to a
        non-negative integer (equivalent to returning that integer)
    In the case of a full write, the number of bytes written should be returned.

    The standard BufferedIOBase and RawIOBase base classes exhibit these
    behaviours and are hence supported.

    Returns:
      An encrypting file object wrapper around 'ciphertext_destination', such
      that any bytes written to the wrapper are AEAD-encrypted using
      'associated_data' as associated authenticated data.

      It supports the following:
        write()
        close()
        closed
        tell()
        isatty()
        flush() (no-op)
        writable()
        readable()
        seekable()
        __enter__() and __exit__()
      Other methods, including read() and seek(), raise io.UnsupportedOperation.
      Closing the wrapper also closes the ciphertext_destination.

    Raises:
      tink.TinkError if the creation fails.
    """
    # pyformat: enable
    raise NotImplementedError()

  @abc.abstractmethod
  def new_decrypting_stream(self, ciphertext_source: BinaryIO,
                            associated_data: bytes) -> BinaryIO:
    """Get a new decrypting stream that reads from ciphertext_source.

    Args:
      ciphertext_source: A readable binary file object from which ciphertext
        will be read.
      associated_data: Associated data to be used by the AEAD decryption. It
        must match the associated_data supplied for the encryption.

    The cipertext_source's read() method is expected to return an empty bytes
    object if the stream is already at EOF. In the case where the stream is not
    at EOF yet but no data is available at the moment, it is expected to either
    return None or raise BlockingIOError.

    The standard BufferedIOBase and RawIOBase base classes exhibit these
    behaviours and are hence supported.

    Returns:
      A decrypting file object wrapper around 'ciphertext_source', such that
      any bytes read from the wrapper are AEAD-decrypted using 'associated_data'
      as associated authenticated data.

      It supports the following:
        read()
        read1()
        readinto()
        readinto1()
        readline()
        readlines()
        readall()
        close()
        closed
        tell()
        isatty()
        flush() (no-op)
        readable()
        writable()
        seekable()
        __enter__() and __exit__()
        __iter__() and __next__()
      Other methods, including write() and seek(), raise
      io.UnsupportedOperation.
      Closing the wrapper also closes the ciphertext_source.

    Raises:
      tink.TinkError if the creation fails.

    """
    raise NotImplementedError()
<|endoftext|>


<commit_before># Copyright 2022 The KerasCV 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.
"""
Title: Training a KerasCV model for Imagenet Classification
Author: [ianjjohnson](https://github.com/ianjjohnson)
Date created: 2022/07/25
Last modified: 2022/07/25
Description: Use KerasCV to train an image classifier using modern best practices
"""

import sys

import tensorflow as tf
from absl import flags
from tensorflow.keras import callbacks
from tensorflow.keras import losses
from tensorflow.keras import metrics
from tensorflow.keras import optimizers

import keras_cv
from keras_cv import models
from keras_cv.datasets import imagenet

"""
## Overview
KerasCV makes training state-of-the-art classification models easy by providing implementations of modern models, preprocessing techniques, and layers.
In this tutorial, we walk through training a model against the Imagenet dataset using Keras and KerasCV.
This tutorial requires you to have KerasCV installed:
```shell
pip install keras-cv
```
"""

"""
## Setup and flags

"""

flags.DEFINE_string(
    "model_name", None, "The name of the model in KerasCV.models to use."
)
flags.DEFINE_string("imagenet_path", None, "Directory from which to load Imagenet.")
flags.DEFINE_string(
    "backup_path", None, "Directory which will be used for training backups."
)
flags.DEFINE_string(
    "weights_path", None, "Directory which will be used to store weight checkpoints."
)
flags.DEFINE_string(
    "tensorboard_path", None, "Directory which will be used to store tensorboard logs."
)
flags.DEFINE_integer("batch_size", 256, "Batch size for training and evaluation.")
flags.DEFINE_boolean(
    "use_xla", True, "Whether or not to use XLA (jit_compile) for training."
)
flags.DEFINE_float(
    "initial_learning_rate",
    0.1,
    "Initial learning rate which will reduce on plateau.",
)

FLAGS = flags.FLAGS
FLAGS(sys.argv)

if FLAGS.model_name not in models.__dict__:
    raise ValueError(f"Invalid model name: {FLAGS.model_name}")

CLASSES = 1000
IMAGE_SIZE = (224, 224)
EPOCHS = 250

"""
## Data loading
This guide uses the
[Imagenet dataset](https://www.tensorflow.org/datasets/catalog/imagenet2012).
Note that this requires manual download and preprocessing. You can find more
information about preparing this dataset at keras_cv/datasets/imagenet/README.md
"""

train_ds = imagenet.load(
    split="train",
    tfrecord_path=FLAGS.imagenet_path,
    batch_size=FLAGS.batch_size,
    img_size=IMAGE_SIZE,
)
test_ds = imagenet.load(
    split="validation",
    tfrecord_path=FLAGS.imagenet_path,
    batch_size=FLAGS.batch_size,
    img_size=IMAGE_SIZE,
)

"""
Next, we augment our dataset.
We define a set of augmentation layers and then apply them to our input dataset.
"""

AUGMENT_LAYERS = [
    keras_cv.layers.RandomFlip(),
    keras_cv.layers.RandAugment(value_range=(0, 255), magnitude=0.3),
    keras_cv.layers.CutMix(),
]

@tf.function
def augment(img, label):
    inputs = {"images": img, "labels": label}
    for layer in AUGMENT_LAYERS:
        inputs = layer(inputs)
    return inputs["images"], inputs["labels"]

train_ds = train_ds.map(augment, num_parallel_calls=tf.data.AUTOTUNE).prefetch(
    tf.data.AUTOTUNE
)
test_ds = test_ds.prefetch(tf.data.AUTOTUNE)

"""
Now we can begin training our model. We begin by loading a model from KerasCV.
Note that we also specify a distribution strategy while creating the model.
Different distribution strategies may be used for different training hardware, as indicated below.
"""

# For TPU training, use tf.distribute.TPUStrategy()
# MirroredStrategy is best for a single machine with multiple GPUs
strategy = tf.distribute.MirroredStrategy()

with strategy.scope():
    model = models.__dict__[FLAGS.model_name]
    model = model(
        include_rescaling=True,
        include_top=True,
        classes=CLASSES,
        input_shape=IMAGE_SIZE + (3,),
    )

"""
Next, we pick an optimizer. Here we use Adam with a constant learning rate.
Note that learning rate will decrease over time due to the ReduceLROnPlateau callback.
"""

optimizer = optimizers.SGD(learning_rate=FLAGS.initial_learning_rate, momentum=0.9)

"""
Next, we pick a loss function. We use CategoricalCrossentropy with label smoothing.
"""

loss_fn = losses.CategoricalCrossentropy(label_smoothing=0.1)

"""
Next, we specify the metrics that we want to track. For this example, we track accuracy.
"""

with strategy.scope():
    training_metrics = [metrics.CategoricalAccuracy()]

"""
As a last piece of configuration, we configure callbacks for the method.
We use EarlyStopping, BackupAndRestore, and a model checkpointing callback.
"""

callbacks = [
    callbacks.ReduceLROnPlateau(
        monitor="val_loss", factor=0.1, patience=10, min_delta=0.001, min_lr=0.0001
    ),
    callbacks.EarlyStopping(patience=20),
    callbacks.BackupAndRestore(FLAGS.backup_path),
    callbacks.ModelCheckpoint(FLAGS.weights_path, save_weights_only=True),
    callbacks.TensorBoard(log_dir=FLAGS.tensorboard_path),
]

"""
We can now compile the model and fit it to the training dataset.
"""

model.compile(
    optimizer=optimizer,
    loss=loss_fn,
    metrics=training_metrics,
    jit_compile=FLAGS.use_xla,
)

model.fit(
    train_ds,
    batch_size=FLAGS.batch_size,
    epochs=EPOCHS,
    callbacks=callbacks,
    validation_data=test_ds,
)
<commit_msg>Add support for model kwargs to basic training script (#742)<commit_after># Copyright 2022 The KerasCV 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.
"""
Title: Training a KerasCV model for Imagenet Classification
Author: [ianjjohnson](https://github.com/ianjjohnson)
Date created: 2022/07/25
Last modified: 2022/07/25
Description: Use KerasCV to train an image classifier using modern best practices
"""

import sys

import tensorflow as tf
from absl import flags
from tensorflow.keras import callbacks
from tensorflow.keras import losses
from tensorflow.keras import metrics
from tensorflow.keras import optimizers

import keras_cv
from keras_cv import models
from keras_cv.datasets import imagenet

"""
## Overview
KerasCV makes training state-of-the-art classification models easy by providing implementations of modern models, preprocessing techniques, and layers.
In this tutorial, we walk through training a model against the Imagenet dataset using Keras and KerasCV.
This tutorial requires you to have KerasCV installed:
```shell
pip install keras-cv
```
"""

"""
## Setup and flags

"""

flags.DEFINE_string(
    "model_name", None, "The name of the model in KerasCV.models to use."
)
flags.DEFINE_string("imagenet_path", None, "Directory from which to load Imagenet.")
flags.DEFINE_string(
    "backup_path", None, "Directory which will be used for training backups."
)
flags.DEFINE_string(
    "weights_path", None, "Directory which will be used to store weight checkpoints."
)
flags.DEFINE_string(
    "tensorboard_path", None, "Directory which will be used to store tensorboard logs."
)
flags.DEFINE_integer("batch_size", 256, "Batch size for training and evaluation.")
flags.DEFINE_boolean(
    "use_xla", True, "Whether or not to use XLA (jit_compile) for training."
)
flags.DEFINE_float(
    "initial_learning_rate",
    0.1,
    "Initial learning rate which will reduce on plateau.",
)
flags.DEFINE_string(
    "model_kwargs",
    "{}",
    "Keyword argument dictionary to pass to the constructor of the model being trained",
)

FLAGS = flags.FLAGS
FLAGS(sys.argv)

if FLAGS.model_name not in models.__dict__:
    raise ValueError(f"Invalid model name: {FLAGS.model_name}")

CLASSES = 1000
IMAGE_SIZE = (224, 224)
EPOCHS = 250

"""
## Data loading
This guide uses the
[Imagenet dataset](https://www.tensorflow.org/datasets/catalog/imagenet2012).
Note that this requires manual download and preprocessing. You can find more
information about preparing this dataset at keras_cv/datasets/imagenet/README.md
"""

train_ds = imagenet.load(
    split="train",
    tfrecord_path=FLAGS.imagenet_path,
    batch_size=FLAGS.batch_size,
    img_size=IMAGE_SIZE,
)
test_ds = imagenet.load(
    split="validation",
    tfrecord_path=FLAGS.imagenet_path,
    batch_size=FLAGS.batch_size,
    img_size=IMAGE_SIZE,
)

"""
Next, we augment our dataset.
We define a set of augmentation layers and then apply them to our input dataset.
"""

AUGMENT_LAYERS = [
    keras_cv.layers.RandomFlip(),
    keras_cv.layers.RandAugment(value_range=(0, 255), magnitude=0.3),
    keras_cv.layers.CutMix(),
]

@tf.function
def augment(img, label):
    inputs = {"images": img, "labels": label}
    for layer in AUGMENT_LAYERS:
        inputs = layer(inputs)
    return inputs["images"], inputs["labels"]

train_ds = train_ds.map(augment, num_parallel_calls=tf.data.AUTOTUNE).prefetch(
    tf.data.AUTOTUNE
)
test_ds = test_ds.prefetch(tf.data.AUTOTUNE)

"""
Now we can begin training our model. We begin by loading a model from KerasCV.
Note that we also specify a distribution strategy while creating the model.
Different distribution strategies may be used for different training hardware, as indicated below.
"""

# For TPU training, use tf.distribute.TPUStrategy()
# MirroredStrategy is best for a single machine with multiple GPUs
strategy = tf.distribute.MirroredStrategy()

with strategy.scope():
    model = models.__dict__[FLAGS.model_name]
    model = model(
        include_rescaling=True,
        include_top=True,
        classes=CLASSES,
        input_shape=IMAGE_SIZE + (3,),
        **eval(FLAGS.model_kwargs),
    )

"""
Next, we pick an optimizer. Here we use Adam with a constant learning rate.
Note that learning rate will decrease over time due to the ReduceLROnPlateau callback.
"""

optimizer = optimizers.SGD(learning_rate=FLAGS.initial_learning_rate, momentum=0.9)

"""
Next, we pick a loss function. We use CategoricalCrossentropy with label smoothing.
"""

loss_fn = losses.CategoricalCrossentropy(label_smoothing=0.1)

"""
Next, we specify the metrics that we want to track. For this example, we track accuracy.
"""

with strategy.scope():
    training_metrics = [metrics.CategoricalAccuracy()]

"""
As a last piece of configuration, we configure callbacks for the method.
We use EarlyStopping, BackupAndRestore, and a model checkpointing callback.
"""

callbacks = [
    callbacks.ReduceLROnPlateau(
        monitor="val_loss", factor=0.1, patience=10, min_delta=0.001, min_lr=0.0001
    ),
    callbacks.EarlyStopping(patience=20),
    callbacks.BackupAndRestore(FLAGS.backup_path),
    callbacks.ModelCheckpoint(FLAGS.weights_path, save_weights_only=True),
    callbacks.TensorBoard(log_dir=FLAGS.tensorboard_path),
]

"""
We can now compile the model and fit it to the training dataset.
"""

model.compile(
    optimizer=optimizer,
    loss=loss_fn,
    metrics=training_metrics,
    jit_compile=FLAGS.use_xla,
)

model.fit(
    train_ds,
    batch_size=FLAGS.batch_size,
    epochs=EPOCHS,
    callbacks=callbacks,
    validation_data=test_ds,
)
<|endoftext|>


<commit_before>from unittest import TestCase

import turbodbc.data_types
from turbodbc import STRING, BINARY, NUMBER, DATETIME, ROWID

ALL_TYPE_CODES = [turbodbc.data_types._BOOLEAN_CODE,
                  turbodbc.data_types._INTEGER_CODE,
                  turbodbc.data_types._FLOATING_POINT_CODE,
                  turbodbc.data_types._STRING_CODE,
                  turbodbc.data_types._TIMESTAMP_CODE,
                  turbodbc.data_types._DATE_CODE]

ALL_DATA_TYPES = [STRING, BINARY, NUMBER, DATETIME, ROWID]

class TestDataTypes(TestCase):
    def test_each_type_code_matches_one_data_type(self):
        for type_code in ALL_TYPE_CODES:
            matches = [type for type in ALL_DATA_TYPES if type_code == type]
            self.assertEqual(1, len(matches))

    def test_each_type_code_matches_all_but_one_data_type(self):
        for type_code in ALL_TYPE_CODES:
            mismatches = [type for type in ALL_DATA_TYPES if type_code != type]
            expected = len(ALL_DATA_TYPES) - 1
            self.assertEqual(expected, len(mismatches))
<commit_msg>Migrate test_data_types to pytest<commit_after>import turbodbc.data_types
from turbodbc import STRING, BINARY, NUMBER, DATETIME, ROWID

ALL_TYPE_CODES = [turbodbc.data_types._BOOLEAN_CODE,
                  turbodbc.data_types._INTEGER_CODE,
                  turbodbc.data_types._FLOATING_POINT_CODE,
                  turbodbc.data_types._STRING_CODE,
                  turbodbc.data_types._TIMESTAMP_CODE,
                  turbodbc.data_types._DATE_CODE]

ALL_DATA_TYPES = [STRING, BINARY, NUMBER, DATETIME, ROWID]

def test_each_type_code_matches_one_data_type():
    for type_code in ALL_TYPE_CODES:
        matches = [type for type in ALL_DATA_TYPES if type_code == type]
        assert 1 == len(matches)

def test_each_type_code_matches_all_but_one_data_type():
    for type_code in ALL_TYPE_CODES:
        mismatches = [type for type in ALL_DATA_TYPES if type_code != type]
        expected = len(ALL_DATA_TYPES) - 1
        assert expected == len(mismatches)
<|endoftext|>


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

from django import template
from django.conf import settings
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.template.defaultfilters import linebreaksbr
from django.core.cache import cache

from opps.containers.models import Container, ContainerBox
from opps.channels.models import Channel

from magicdate import magicdate

register = template.Library()
logger = logging.getLogger()

@register.assignment_tag
def get_recommendations(query_slice, child_class, container):
    """
    Takes the container object and get recommendations and filters by given
    child_class and limit the result by given slice.

    Sample usage::

        {% get_recommendations ":3" "post" container as context_var %}

    query_slice:
        A string with slice notation to limit the queryset result
    child_class:
        Name of child class
    container:
        A Container object
    """

    if not query_slice:
        query_slice = ":"

    bits = []
    for x in query_slice.split(':'):
        if len(x) == 0:
            bits.append(None)
        else:
            bits.append(int(x))

    return container.recommendation(child_class, bits)

@register.simple_tag(takes_context=True)
def get_containerbox(context, slug, template_name=None, **extra_context):

    request = context['request']
    is_mobile = getattr(request, 'is_mobile', False)

    cachekey = "ContainerBox-{}-{}-{}".format(
        slug,
        template_name,
        is_mobile
    )

    render = cache.get(cachekey)
    if render:
        return render

    filters = {}
    filters['site'] = settings.SITE_ID
    filters['slug'] = slug
    filters['date_available__lte'] = timezone.now()
    filters['published'] = True
    try:
        box = ContainerBox.objects.get(**filters)
    except ContainerBox.DoesNotExist:
        box = ContainerBox.objects.none()
        if settings.OPPS_CONTAINERS_SITE_ID:
            filters['site'] = settings.OPPS_CONTAINERS_SITE_ID
            try:
                box = ContainerBox.objects.get(**filters)
            except ContainerBox.DoesNotExist:
                pass

    t = template.loader.get_template('articles/articlebox_detail.html')
    if template_name:
        t = template.loader.get_template(template_name)

    context = {
        'articlebox': box,
        'slug': slug,
        'context': context
    }

    context.update(extra_context)

    render = t.render(template.Context(context))

    cache.set(cachekey, render, settings.OPPS_CACHE_EXPIRE)

    return render

@register.simple_tag
def get_all_containerbox(channel_long_slug=None, template_name=None):
    """
    Takes all containers or containers that match the channel name (long slug).

    Sample usages::

        {% get_all_containerbox "channel" template_name='my_template.html' %}
        {% get_all_containerbox "channel/subchannel" %}
        {% get_all_containerbox %}

    channel_long_slug:
        Long path to channel (including subchannel if is the case)
    """

    cachekey = "get_all_containerbox-{}-{}".format(
        channel_long_slug,
        template_name)

    render = cache.get(cachekey)
    if render:
        return render

    filters = {}
    filters['date_available__lte'] = timezone.now()
    filters['published'] = True
    filters['site'] = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        filters['site'] = settings.OPPS_CONTAINERS_SITE_ID

    boxes = ContainerBox.objects.filter(**filters)

    if channel_long_slug:
        boxes = boxes.filter(channel_long_slug=channel_long_slug)

    t = template.loader.get_template('articles/articlebox_list.html')
    if template_name:
        t = template.loader.get_template(template_name)

    render = t.render(template.Context({'articleboxes': boxes}))
    cache.set(cachekey, render, settings.OPPS_CACHE_EXPIRE)

    return render

@register.simple_tag
def get_post_content(post, template_name='containers/post_related.html',
                     content_field='content', related_name='related_posts',
                     get_related=True, safe=True, divider="
",
                     placeholder=settings.OPPS_RELATED_POSTS_PLACEHOLDER):
    """
    takes the post and tries to find the related posts to embed inside
    the content, if not found return only the content.

    post:
        Post instance
    template_name:
        path to template which receives the related posts
    content_field:
        name of the field with post content
    related_name:
        a m2m field name or a @property name which
        returns a queryset of related posts
    get_related:
        if False bypass and return only the content
    safe:
        if True mark the content as safe
    divider:
        used when there is no placeholder
    placeholder:
        the string to replace ex: --related--
    """
    if not hasattr(post, content_field):
        return None
    content = getattr(post, content_field, '')

    # REMOVE NEW LINES
    content = linebreaksbr(content)

    # Fix embed allowfullscreen
    # TinyMCE BUG
    content = content.replace('allowfullscreen="allowfullscreen"',
                              'allowfullscreen="true"')

    if not get_related:
        return content

    related_posts = getattr(post, related_name, None)

    if not related_posts.exists():
        return mark_safe(content)

    # GET THE TEMPLATE
    t = template.loader.get_template(template_name)
    related_rendered = t.render(template.Context({
        'post': post, related_name: related_posts}))
    # EMBED RELATED POSTS
    if placeholder in content:
        return mark_safe(content.replace(
            placeholder,
            related_rendered
        ))
    else:
        return mark_safe(content + divider + related_rendered)

@register.simple_tag
def get_url(obj, http=False, target=None, url_only=False):

    if not hasattr(obj, 'child_class'):
        return obj.get_absolute_url()

    try:
        _url = obj.get_absolute_url()
        _target = target or '_self'
        _is_link = obj.child_class == 'Link'
        # Determine if it's a local or foreign link
        if _is_link and not obj.link.is_local() and not target:
            _target = '_blank'
        # Determine url type
        if http:
            _url = 'http://{}{}'.format(
                obj.site,
                obj.get_absolute_url())
        if url_only:
            return _url
        return 'href="{}" target="{}"'.format(_url, _target)
    except Exception as e:
        logger.error("Exception at templatetag get_url: {}".format(e))
        return obj.get_absolute_url()

@register.assignment_tag
def get_containers_by(limit=None, **filters):
    """Return a list of containers filtered by given args"""
    cachekey = hash(frozenset(filters.items()))
    _cache = cache.get(cachekey)
    if _cache:
        return _cache

    site = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        site = settings.OPPS_CONTAINERS_SITE_ID

    containers = [i for i in Container.objects.filter(
        site=site, published=True, **filters)[:limit]]
    cache.set("getconby-{}".format(cachekey), 3600)
    return containers

@register.assignment_tag
def filter_queryset_by(queryset, **filters):
    """Filter object list"""
    cachekey = hash(frozenset(filters.items()))
    _cache = cache.get(cachekey)
    if _cache:
        return _cache

    if not getattr(queryset, 'query', False):
        return queryset

    if not queryset.query.can_filter():
        # create new queryset based on the ids and apply filter
        ids = [i.id for i in queryset]
        queryset = queryset.model.objects.filter(id__in=ids).filter(**filters)
        return queryset

    containers = queryset.filter(**filters)
    cache.set("filterquerysetby-{}".format(cachekey), 3600)
    return containers

@register.assignment_tag
def exclude_queryset_by(queryset, **excludes):
    """Exclude object list"""
    cachekey = hash(frozenset(excludes.items()))
    _cache = cache.get(cachekey)
    if _cache:
        return _cache

    if not getattr(queryset, 'query', False):
        return queryset

    if not queryset.query.can_filter():
        # create new queryset based on the ids and apply filter
        ids = [i.id for i in queryset]
        queryset = queryset.model.objects.filter(id__in=ids).exclude(
            **excludes
        )
        return queryset

    containers = queryset.exclude(**excludes)
    cache.set("excludequerysetby-{}".format(cachekey), 3600)
    return containers

@register.assignment_tag
def get_container_by_channel(slug, number=10, depth=1,
                             include_children=True, **kwargs):
    box = None
    magic_date = kwargs.pop('magic_date', False)
    date = timezone.now()
    if magic_date:
        try:
            date = magicdate(magic_date)
        except Exception:
            pass

    if include_children:
        try:
            kwargs['channel_long_slug__in'] = cache.get(
                'get_container_by_channel-{}'.format(slug))
            if not kwargs['channel_long_slug__in']:
                base_channel = Channel.objects.get(long_slug=slug)
                kwargs['channel_long_slug__in'] = [base_channel.long_slug]

                def _append_recursivelly(channel, current_level=0):
                    # Depth test
                    if current_level >= depth:
                        return
                    elif current_level < depth:
                        current_level += 1

                    for children in channel.get_children():
                        kwargs['channel_long_slug__in'].append(
                            children.long_slug)
                        # Recursion
                        _channel = Channel.objects.get(
                            long_slug=children.long_slug)
                        _append_recursivelly(_channel, current_level)

                _append_recursivelly(base_channel)
                cache.set('get_container_by_channel-{}'.format(slug),
                          kwargs['channel_long_slug__in'],
                          settings.OPPS_CACHE_EXPIRE)
        except Channel.DoesNotExist:
            kwargs['channel_long_slug__in'] = []
    try:
        kwargs['site'] = settings.SITE_ID
        if settings.OPPS_CONTAINERS_SITE_ID:
            kwargs['site'] = settings.OPPS_CONTAINERS_SITE_ID
        kwargs['show_on_root_channel'] = include_children
        kwargs['date_available__lte'] = date
        kwargs['published'] = True
        box = Container.objects.distinct().filter(
            **kwargs).order_by('-date_available')[:number]
    except:
        pass
    return box

@register.assignment_tag
def get_containerbox_by(**filters):
    """Return a list of containers filtered by given args"""
    site = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        site = settings.OPPS_CONTAINERS_SITE_ID
    return ContainerBox.objects.filter(site=site,
                                       published=True,
                                       date_available__lte=timezone.now(),
                                       **filters)

@register.simple_tag(takes_context=True)
def get_containerbox_list(context, slug, num=0, template_name=None):
    """ returns a list of sub-lists of the containerbox specific containers,
        the size of the sub lists is treated with a parameter num """

    request = context['request']

    cachekey = "ContainerBoxList-{}-{}-{}".format(
        slug,
        template_name,
        request.is_mobile,
    )

    render = cache.get(cachekey)
    if render:
        return render

    site = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        site = settings.OPPS_CONTAINERS_SITE_ID
    try:
        box = ContainerBox.objects.filter(
            site=site, slug=slug,
            date_available__lte=timezone.now(),
            published=True)
        if isinstance(num, int) and num > 0 and box:
            list_box = box[0].ordered_box_containers()
            box = [list_box[i:i + num] for i in range(0, len(list_box), num)]
    except ContainerBox.DoesNotExist:
        box = None

    t = template.loader.get_template('articles/articlebox_container_list.html')
    if template_name:
        t = template.loader.get_template(template_name)

    render = t.render(template.Context({
        'list_container': box,
        'slug': slug,
        'context': context}
    ))

    cache.set(cachekey, render, settings.OPPS_CACHE_EXPIRE)

    return render

@register.assignment_tag
def get_custom_field_value(obj, field_slug):
    """
    Return a custom field value
    """
    if not callable(getattr(obj, 'custom_fields')):
        return None

    if not obj.custom_fields():
        return None

    return obj.custom_fields().get(field_slug)
<commit_msg>Change filter_queryset_by and exclude_queryset_by, now accepting __in lookups<commit_after># -*- coding: utf-8 -*-
import logging

from django import template
from django.conf import settings
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.template.defaultfilters import linebreaksbr
from django.core.cache import cache

from opps.containers.models import Container, ContainerBox
from opps.channels.models import Channel

from magicdate import magicdate

register = template.Library()
logger = logging.getLogger()

@register.assignment_tag
def get_recommendations(query_slice, child_class, container):
    """
    Takes the container object and get recommendations and filters by given
    child_class and limit the result by given slice.

    Sample usage::

        {% get_recommendations ":3" "post" container as context_var %}

    query_slice:
        A string with slice notation to limit the queryset result
    child_class:
        Name of child class
    container:
        A Container object
    """

    if not query_slice:
        query_slice = ":"

    bits = []
    for x in query_slice.split(':'):
        if len(x) == 0:
            bits.append(None)
        else:
            bits.append(int(x))

    return container.recommendation(child_class, bits)

@register.simple_tag(takes_context=True)
def get_containerbox(context, slug, template_name=None, **extra_context):

    request = context['request']
    is_mobile = getattr(request, 'is_mobile', False)

    cachekey = "ContainerBox-{}-{}-{}".format(
        slug,
        template_name,
        is_mobile
    )

    render = cache.get(cachekey)
    if render:
        return render

    filters = {}
    filters['site'] = settings.SITE_ID
    filters['slug'] = slug
    filters['date_available__lte'] = timezone.now()
    filters['published'] = True
    try:
        box = ContainerBox.objects.get(**filters)
    except ContainerBox.DoesNotExist:
        box = ContainerBox.objects.none()
        if settings.OPPS_CONTAINERS_SITE_ID:
            filters['site'] = settings.OPPS_CONTAINERS_SITE_ID
            try:
                box = ContainerBox.objects.get(**filters)
            except ContainerBox.DoesNotExist:
                pass

    t = template.loader.get_template('articles/articlebox_detail.html')
    if template_name:
        t = template.loader.get_template(template_name)

    context = {
        'articlebox': box,
        'slug': slug,
        'context': context
    }

    context.update(extra_context)

    render = t.render(template.Context(context))

    cache.set(cachekey, render, settings.OPPS_CACHE_EXPIRE)

    return render

@register.simple_tag
def get_all_containerbox(channel_long_slug=None, template_name=None):
    """
    Takes all containers or containers that match the channel name (long slug).

    Sample usages::

        {% get_all_containerbox "channel" template_name='my_template.html' %}
        {% get_all_containerbox "channel/subchannel" %}
        {% get_all_containerbox %}

    channel_long_slug:
        Long path to channel (including subchannel if is the case)
    """

    cachekey = "get_all_containerbox-{}-{}".format(
        channel_long_slug,
        template_name)

    render = cache.get(cachekey)
    if render:
        return render

    filters = {}
    filters['date_available__lte'] = timezone.now()
    filters['published'] = True
    filters['site'] = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        filters['site'] = settings.OPPS_CONTAINERS_SITE_ID

    boxes = ContainerBox.objects.filter(**filters)

    if channel_long_slug:
        boxes = boxes.filter(channel_long_slug=channel_long_slug)

    t = template.loader.get_template('articles/articlebox_list.html')
    if template_name:
        t = template.loader.get_template(template_name)

    render = t.render(template.Context({'articleboxes': boxes}))
    cache.set(cachekey, render, settings.OPPS_CACHE_EXPIRE)

    return render

@register.simple_tag
def get_post_content(post, template_name='containers/post_related.html',
                     content_field='content', related_name='related_posts',
                     get_related=True, safe=True, divider="
",
                     placeholder=settings.OPPS_RELATED_POSTS_PLACEHOLDER):
    """
    takes the post and tries to find the related posts to embed inside
    the content, if not found return only the content.

    post:
        Post instance
    template_name:
        path to template which receives the related posts
    content_field:
        name of the field with post content
    related_name:
        a m2m field name or a @property name which
        returns a queryset of related posts
    get_related:
        if False bypass and return only the content
    safe:
        if True mark the content as safe
    divider:
        used when there is no placeholder
    placeholder:
        the string to replace ex: --related--
    """
    if not hasattr(post, content_field):
        return None
    content = getattr(post, content_field, '')

    # REMOVE NEW LINES
    content = linebreaksbr(content)

    # Fix embed allowfullscreen
    # TinyMCE BUG
    content = content.replace('allowfullscreen="allowfullscreen"',
                              'allowfullscreen="true"')

    if not get_related:
        return content

    related_posts = getattr(post, related_name, None)

    if not related_posts.exists():
        return mark_safe(content)

    # GET THE TEMPLATE
    t = template.loader.get_template(template_name)
    related_rendered = t.render(template.Context({
        'post': post, related_name: related_posts}))
    # EMBED RELATED POSTS
    if placeholder in content:
        return mark_safe(content.replace(
            placeholder,
            related_rendered
        ))
    else:
        return mark_safe(content + divider + related_rendered)

@register.simple_tag
def get_url(obj, http=False, target=None, url_only=False):

    if not hasattr(obj, 'child_class'):
        return obj.get_absolute_url()

    try:
        _url = obj.get_absolute_url()
        _target = target or '_self'
        _is_link = obj.child_class == 'Link'
        # Determine if it's a local or foreign link
        if _is_link and not obj.link.is_local() and not target:
            _target = '_blank'
        # Determine url type
        if http:
            _url = 'http://{}{}'.format(
                obj.site,
                obj.get_absolute_url())
        if url_only:
            return _url
        return 'href="{}" target="{}"'.format(_url, _target)
    except Exception as e:
        logger.error("Exception at templatetag get_url: {}".format(e))
        return obj.get_absolute_url()

@register.assignment_tag
def get_containers_by(limit=None, **filters):
    """Return a list of containers filtered by given args"""
    cachekey = hash(frozenset(filters.items()))
    _cache = cache.get(cachekey)
    if _cache:
        return _cache

    site = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        site = settings.OPPS_CONTAINERS_SITE_ID

    containers = [i for i in Container.objects.filter(
        site=site, published=True, **filters)[:limit]]
    cache.set("getconby-{}".format(cachekey), 3600)
    return containers

@register.assignment_tag
def filter_queryset_by(queryset, **filters):
    """Filter object list"""
    cachekey = hash(frozenset(filters.items()))
    _cache = cache.get(cachekey)
    if _cache:
        return _cache

    # check for __in lookups and split the param
    found_in_lookup = None
    for key in filters.keys():
        if '__in' in key:
            found_in_lookup = key

    if found_in_lookup:
        filters[found_in_lookup] = filters[found_in_lookup].split(',')

    if not getattr(queryset, 'query', False):
        return queryset

    if not queryset.query.can_filter():
        # create new queryset based on the ids and apply filter
        ids = [i.id for i in queryset]
        queryset = queryset.model.objects.filter(id__in=ids).filter(**filters)
        return queryset

    containers = queryset.filter(**filters)
    cache.set("filterquerysetby-{}".format(cachekey), 3600)
    return containers

@register.assignment_tag
def exclude_queryset_by(queryset, **excludes):
    """Exclude object list"""
    cachekey = hash(frozenset(excludes.items()))
    _cache = cache.get(cachekey)
    if _cache:
        return _cache

    # check for __in lookups and split the param
    found_in_lookup = None
    for key in excludes.keys():
        if '__in' in key:
            found_in_lookup = key

    if found_in_lookup:
        excludes[found_in_lookup] = excludes[found_in_lookup].split(',')

    if not getattr(queryset, 'query', False):
        return queryset

    if not queryset.query.can_filter():
        # create new queryset based on the ids and apply filter
        ids = [i.id for i in queryset]
        queryset = queryset.model.objects.filter(id__in=ids).exclude(
            **excludes
        )
        return queryset

    containers = queryset.exclude(**excludes)
    cache.set("excludequerysetby-{}".format(cachekey), 3600)
    return containers

@register.assignment_tag
def get_container_by_channel(slug, number=10, depth=1,
                             include_children=True, **kwargs):
    box = None
    magic_date = kwargs.pop('magic_date', False)
    date = timezone.now()
    if magic_date:
        try:
            date = magicdate(magic_date)
        except Exception:
            pass

    if include_children:
        try:
            kwargs['channel_long_slug__in'] = cache.get(
                'get_container_by_channel-{}'.format(slug))
            if not kwargs['channel_long_slug__in']:
                base_channel = Channel.objects.get(long_slug=slug)
                kwargs['channel_long_slug__in'] = [base_channel.long_slug]

                def _append_recursivelly(channel, current_level=0):
                    # Depth test
                    if current_level >= depth:
                        return
                    elif current_level < depth:
                        current_level += 1

                    for children in channel.get_children():
                        kwargs['channel_long_slug__in'].append(
                            children.long_slug)
                        # Recursion
                        _channel = Channel.objects.get(
                            long_slug=children.long_slug)
                        _append_recursivelly(_channel, current_level)

                _append_recursivelly(base_channel)
                cache.set('get_container_by_channel-{}'.format(slug),
                          kwargs['channel_long_slug__in'],
                          settings.OPPS_CACHE_EXPIRE)
        except Channel.DoesNotExist:
            kwargs['channel_long_slug__in'] = []
    try:
        kwargs['site'] = settings.SITE_ID
        if settings.OPPS_CONTAINERS_SITE_ID:
            kwargs['site'] = settings.OPPS_CONTAINERS_SITE_ID
        kwargs['show_on_root_channel'] = include_children
        kwargs['date_available__lte'] = date
        kwargs['published'] = True
        box = Container.objects.distinct().filter(
            **kwargs).order_by('-date_available')[:number]
    except:
        pass
    return box

@register.assignment_tag
def get_containerbox_by(**filters):
    """Return a list of containers filtered by given args"""
    site = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        site = settings.OPPS_CONTAINERS_SITE_ID
    return ContainerBox.objects.filter(site=site,
                                       published=True,
                                       date_available__lte=timezone.now(),
                                       **filters)

@register.simple_tag(takes_context=True)
def get_containerbox_list(context, slug, num=0, template_name=None):
    """ returns a list of sub-lists of the containerbox specific containers,
        the size of the sub lists is treated with a parameter num """

    request = context['request']

    cachekey = "ContainerBoxList-{}-{}-{}".format(
        slug,
        template_name,
        request.is_mobile,
    )

    render = cache.get(cachekey)
    if render:
        return render

    site = settings.SITE_ID
    if settings.OPPS_CONTAINERS_SITE_ID:
        site = settings.OPPS_CONTAINERS_SITE_ID
    try:
        box = ContainerBox.objects.filter(
            site=site, slug=slug,
            date_available__lte=timezone.now(),
            published=True)
        if isinstance(num, int) and num > 0 and box:
            list_box = box[0].ordered_box_containers()
            box = [list_box[i:i + num] for i in range(0, len(list_box), num)]
    except ContainerBox.DoesNotExist:
        box = None

    t = template.loader.get_template('articles/articlebox_container_list.html')
    if template_name:
        t = template.loader.get_template(template_name)

    render = t.render(template.Context({
        'list_container': box,
        'slug': slug,
        'context': context}
    ))

    cache.set(cachekey, render, settings.OPPS_CACHE_EXPIRE)

    return render

@register.assignment_tag
def get_custom_field_value(obj, field_slug):
    """
    Return a custom field value
    """
    if not callable(getattr(obj, 'custom_fields')):
        return None

    if not obj.custom_fields():
        return None

    return obj.custom_fields().get(field_slug)
<|endoftext|>


<commit_before>
import ast,os
from docutils import nodes, statemachine, utils
from docutils.parsers.rst import Directive
from docutils.parsers.rst import directives
from docutils.nodes import fully_normalize_name

def setup(app):
    app.add_directive('autoexample', AutoExampleDirective)

def parse_example(basepath, filename, img_folder):
    path = os.path.join(basepath, filename)
    with open(path) as f:
        content = f.read().strip()
    n = ast.parse(content)
    docstring = ast.get_docstring(n)
    if docstring == None:
        return []

    # Header
    s = [filename, "".ljust(len(filename), '-')]

    # Location
    folder = os.path.basename(basepath)
    s.append("Location: *%s/%s*" % (folder, filename))

    # Docstring
    s.append("")
    s.append(docstring)
    s.append("")

    # Screenshot
    img_name,_ = os.path.splitext(filename)
    img_name += ".png"
    if img_folder != None:
        img_path = os.path.join(img_folder, img_name)
        #img_path = os.path.abspath(img_path)
        if os.path.isfile(img_path) or True:
            s.append("")
            s.append(".. image:: " + img_path)
            s.append("")

    s.append("")
    return s

def parse_examples(path, img_folder):
    lines = []
    print("autoexample: documenting files in " + path)
    #print os.getcwd()
    for root, dirs, files in os.walk(path):
        for file in files:
            path = os.path.join(root, file)
            if not os.path.isfile(path):
                continue
            _, ext = os.path.splitext(path)
            if ext != ".py":
                continue
            print("autoexample: documenting " + file)
            lines += parse_example(root, file, img_folder)

    return "\n".join(lines)

class AutoExampleDirective(Directive):
    # this enables content in the directive
    #has_content = True
    required_arguments = 1
    option_spec = {'image_folder': str}

    def run(self):
        source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        path = os.path.normpath(os.path.join(source_dir, path))

        path = utils.relative_path(None, path)
        path = nodes.reprunicode(path)
        img_folder = None
        if "image_folder" in self.options:
            #img_folder = os.path.normpath(os.path.join(source_dir, self.options["image_folder"]))
            img_folder = self.options["image_folder"]

            #print path.join(self.srcdir, imgpath)

            #print "IMG FOLDER:",img_folder
        rawtext = parse_examples(path, img_folder)

        include_lines = statemachine.string2lines(rawtext, self.state.document.settings.tab_width,
                                                  convert_whitespace=True)

        self.state_machine.insert_input(include_lines, path)
        return []<commit_msg>fixed images for rtd?<commit_after>
import ast,os
from docutils import nodes, statemachine, utils
from docutils.parsers.rst import Directive
from docutils.parsers.rst import directives
from docutils.nodes import fully_normalize_name

def setup(app):
    app.add_directive('autoexample', AutoExampleDirective)

def parse_example(basepath, filename, img_folder, img_folder_os):
    path = os.path.join(basepath, filename)
    with open(path) as f:
        content = f.read().strip()
    n = ast.parse(content)
    docstring = ast.get_docstring(n)
    if docstring == None:
        return []

    # Header
    s = [filename, "".ljust(len(filename), '-')]

    # Location
    folder = os.path.basename(basepath)
    s.append("Location: *%s/%s*" % (folder, filename))

    # Docstring
    s.append("")
    s.append(docstring)
    s.append("")

    # Screenshot
    img_name,_ = os.path.splitext(filename)
    img_name += ".png"
    if img_folder != None:
        #print os.path.abspath(img_folder)
        #print os.path.abspath(img_folder_os)
        img_path = os.path.join(img_folder, img_name)
        img_path_os = os.path.join(img_folder_os, img_name)
        if os.path.isfile(img_path_os):
            s.append("")
            s.append(".. image:: " + img_path)
            s.append("")

    s.append("")
    return s

def parse_examples(path, img_folder, img_folder_os):
    lines = []
    print("autoexample: documenting files in " + path)
    #print os.getcwd()
    for root, dirs, files in os.walk(path):
        for file in files:
            path = os.path.join(root, file)
            if not os.path.isfile(path):
                continue
            _, ext = os.path.splitext(path)
            if ext != ".py":
                continue
            print("autoexample: documenting " + file)
            lines += parse_example(root, file, img_folder, img_folder_os)

    return "\n".join(lines)

class AutoExampleDirective(Directive):
    # this enables content in the directive
    #has_content = True
    required_arguments = 1
    option_spec = {'image_folder': str}

    def run(self):
        source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        path = os.path.normpath(os.path.join(source_dir, path))

        path = utils.relative_path(None, path)
        path = nodes.reprunicode(path)
        img_folder = None
        img_folder_os = None
        if "image_folder" in self.options:
            # This is extremly messy..
            # To be able to test if file exist in path we need to use img_path_os
            # But that cannot be used for the .. image:: tag, instead we need to use the raw option!
            img_folder_os = os.path.normpath(os.path.join(source_dir, self.options["image_folder"]))
            img_folder = self.options["image_folder"]
        rawtext = parse_examples(path, img_folder, img_folder_os)

        include_lines = statemachine.string2lines(rawtext, self.state.document.settings.tab_width,
                                                  convert_whitespace=True)

        self.state_machine.insert_input(include_lines, path)
        return []<|endoftext|>


<commit_before>import json

from django.shortcuts import render,redirect
from django.http import HttpResponse, Http404
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth.models import User
from django.utils import timezone

from approver.models import Project
from approver.forms import AboutYouForm, ProjectForm
from approver.workflows import project_crud
from approver.decorators import login_required
import approver.constants as constants
import approver.utils as utils
from django.core.urlresolvers import reverse

@login_required
def project(request, project_id=None):
    '''Project can be viewed only if it is not archived. SuperUser can edit the archived project'''
    context = {
        'content': 'approver/project.html',
        'project_id': project_id,
    }
    current_user = User.objects.get(username=utils.get_current_user_gatorlink(request.session))
    if request.method == 'POST':
        project_form = request.POST
        title = project_form.get('title')
        project = project_crud.get_project_or_none(project_id)
        if(project is None):
            project = project_crud.create_or_update_project(current_user, project_form, project_id)
        else:
            if project.archived and not project_crud.current_user_is_superuser(current_user):
                return utils.dashboard_redirect_and_toast(request, 'Project is Archived.')
            if project_crud.curent_user_is_project_owner(current_user, project) is not True and project_crud.current_user_is_superuser:
                project = project_crud.create_or_update_project(current_user, project_form, project_id)
                return utils.dashboard_su_redirect_and_toast(request, 'Project is Saved.')

            if (project_crud.curent_user_is_project_owner(current_user, project) is True and project.get_is_editable() and not project.archived):
                project = project_crud.create_or_update_project(current_user, project_form, project_id)
            else:
                return utils.dashboard_redirect_and_toast(request, 'You are not allowed to edit this project'.format(project_id))
        return redirect(reverse("approver:similar_projects", args=[str(project.id)]))

    else:
        now = timezone.now()
        project_form = ProjectForm()
        context['form'] = project_form
        if(project_id is not None):
            project = project_crud.get_project_or_none(project_id)
            if(project is None):
                return utils.dashboard_redirect_and_toast(request, 'Project with id {} does not exist.'.format(project_id))
            else:
                if project.archived and not project_crud.current_user_is_superuser(current_user) :
                    return utils.dashboard_redirect_and_toast(request, 'Project is Archived.')
                if(project_crud.is_current_project_editable(current_user, project) is not True):
                    if project_crud.current_user_is_project_advisor_or_collaborator(current_user,project):
                        context['form'] = ProjectForm(project,is_disabled=True)
                        return utils.layout_render(request,context)
                    else:
                        return utils.dashboard_redirect_and_toast(request, 'You are not authorized to edit this project.')
                else:
                    if (project.get_is_editable() is not True):
                        context['form'] = ProjectForm(project,is_disabled=True)
                        return utils.layout_render(request,context)
                    else:
                        context['form'] = ProjectForm(project)
                        return utils.layout_render(request, context)
        else:
            return utils.layout_render(request, context)
<commit_msg>allow admins to edit approved projects<commit_after>import json

from django.shortcuts import render,redirect
from django.http import HttpResponse, Http404
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth.models import User
from django.utils import timezone

from approver.models import Project
from approver.forms import AboutYouForm, ProjectForm
from approver.workflows import project_crud
from approver.decorators import login_required
import approver.constants as constants
import approver.utils as utils
from django.core.urlresolvers import reverse

@login_required
def project(request, project_id=None):
    '''Project can be viewed only if it is not archived. SuperUser can edit the archived project'''
    context = {
        'content': 'approver/project.html',
        'project_id': project_id,
    }
    current_user = User.objects.get(username=utils.get_current_user_gatorlink(request.session))
    if request.method == 'POST':
        project_form = request.POST
        title = project_form.get('title')
        project = project_crud.get_project_or_none(project_id)
        if(project is None):
            project = project_crud.create_or_update_project(current_user, project_form, project_id)
        else:
            if project.archived and not project_crud.current_user_is_superuser(current_user):
                return utils.dashboard_redirect_and_toast(request, 'Project is Archived.')
            if project_crud.curent_user_is_project_owner(current_user, project) is not True and project_crud.current_user_is_superuser:
                project = project_crud.create_or_update_project(current_user, project_form, project_id)
                return utils.dashboard_su_redirect_and_toast(request, 'Project is Saved.')

            if (project_crud.curent_user_is_project_owner(current_user, project) is True and project.get_is_editable() and not project.archived):
                project = project_crud.create_or_update_project(current_user, project_form, project_id)
            else:
                return utils.dashboard_redirect_and_toast(request, 'You are not allowed to edit this project'.format(project_id))
        return redirect(reverse("approver:similar_projects", args=[str(project.id)]))

    else:
        now = timezone.now()
        project_form = ProjectForm()
        context['form'] = project_form
        if(project_id is not None):
            project = project_crud.get_project_or_none(project_id)
            if(project is None):
                return utils.dashboard_redirect_and_toast(request, 'Project with id {} does not exist.'.format(project_id))
            else:
                if project.archived and not project_crud.current_user_is_superuser(current_user) :
                    return utils.dashboard_redirect_and_toast(request, 'Project is Archived.')
                if(project_crud.is_current_project_editable(current_user, project) is not True):
                    if project_crud.current_user_is_project_advisor_or_collaborator(current_user,project):
                        context['form'] = ProjectForm(project,is_disabled=True)
                        return utils.layout_render(request,context)
                    else:
                        return utils.dashboard_redirect_and_toast(request, 'You are not authorized to edit this project.')
                else:
                    if (project.get_is_editable() is not True):
                        if (project_crud.current_user_is_superuser(current_user)):
                            context['form'] = ProjectForm(project,is_disabled=False)
                        else:
                            context['form'] = ProjectForm(project,is_disabled=True)
                        return utils.layout_render(request,context)
                    else:
                        context['form'] = ProjectForm(project)
                        return utils.layout_render(request, context)
        else:
            return utils.layout_render(request, context)
<|endoftext|>


<commit_before>from django.contrib import messages
from django.core.mail import send_mail
from django.utils.translation import ugettext_lazy as _

import stored_messages

from osmaxx.excerptexport import models

from excerptconverter.baseexcerptconverter import BaseExcerptConverter

class ConverterHelper:
    def __init__(self, extraction_order):
        self.extraction_order = extraction_order
        self.user = extraction_order.orderer

    def file_conversion_finished(self):
        if self.extraction_order.output_files.count() >= len(self.extraction_order.extraction_formats):
            self.inform_user(
                messages.SUCCESS,
                _('The extraction of the order "%(order_id)s" has been finished.') % {
                    'order_id': self.extraction_order.id
                },
                True
            )
            self.extraction_order.state = models.ExtractionOrderState.FINISHED
            self.extraction_order.save()

    def inform_user(self, message_type, message_text, email=True):
        stored_messages.api.add_message_for(
            users=[self.user],
            level=message_type,
            message_text=message_text
        )

        if email:
            if hasattr(self.user, 'email'):
                send_mail(
                    '[OSMAXX] '+message_text,
                    message_text,
                    'no-reply@osmaxx.hsr.ch',
                    [self.user.email]
                )
            else:
                self.inform_user(
                    messages.WARNING,
                    _("There is no email address assigned to your account. "
                      "You won't be notified by email on process finish!"),
                    email=False
                )<commit_msg>missing newline at end of file<commit_after>from django.contrib import messages
from django.core.mail import send_mail
from django.utils.translation import ugettext_lazy as _

import stored_messages

from osmaxx.excerptexport import models

from excerptconverter.baseexcerptconverter import BaseExcerptConverter

class ConverterHelper:
    def __init__(self, extraction_order):
        self.extraction_order = extraction_order
        self.user = extraction_order.orderer

    def file_conversion_finished(self):
        if self.extraction_order.output_files.count() >= len(self.extraction_order.extraction_formats):
            self.inform_user(
                messages.SUCCESS,
                _('The extraction of the order "%(order_id)s" has been finished.') % {
                    'order_id': self.extraction_order.id
                },
                True
            )
            self.extraction_order.state = models.ExtractionOrderState.FINISHED
            self.extraction_order.save()

    def inform_user(self, message_type, message_text, email=True):
        stored_messages.api.add_message_for(
            users=[self.user],
            level=message_type,
            message_text=message_text
        )

        if email:
            if hasattr(self.user, 'email'):
                send_mail(
                    '[OSMAXX] '+message_text,
                    message_text,
                    'no-reply@osmaxx.hsr.ch',
                    [self.user.email]
                )
            else:
                self.inform_user(
                    messages.WARNING,
                    _("There is no email address assigned to your account. "
                      "You won't be notified by email on process finish!"),
                    email=False
                )
<|endoftext|>


<commit_before># "NOQA" to suppress flake8 warning
from cupyx.runtime import get_runtime_info  # NOQA
from cupyx.rsqrt import rsqrt  # NOQA
from cupyx.scatter import scatter_add  # NOQA
<commit_msg>flake8<commit_after># "NOQA" to suppress flake8 warning
from cupyx.rsqrt import rsqrt  # NOQA
from cupyx.runtime import get_runtime_info  # NOQA
from cupyx.scatter import scatter_add  # NOQA
<|endoftext|>


<commit_before>from django.shortcuts import render
from django.conf import settings
from .models import Customer
from django.http import HttpResponse
import chwrapper

# Create your views here.
def profile(request):
    current_customer = request.user
    if request.method == 'GET':
        return render(request, 'customer/profile.html', {'current_customer':current_customer})
    elif request.method == 'POST':
        # search_term = request.POST.get("q", "")
        search_client = chwrapper.Search(settings.ACCESS_TOKEN)
        response = search_client.search_companies(request.POST.get("q", ""))
        response_json = response.json()
        if response_json['total_results'] == 0:
            return HttpResponse('No results')
        elif response_json['total_results'] > 0:
            title = response_json['items'][0]['title']
            return HttpResponse(title)
<commit_msg>profile view handles get requests either initial or after user clicking submit - now also a get request. If the user submits a search request the response is now sent to profile template with differentiation between 0 or greater than 0 results<commit_after>from django.shortcuts import render
from django.conf import settings
from .models import Customer
from django.http import HttpResponse
import chwrapper

# Create your views here.
def profile(request):
    current_customer = request.user
    query = request.GET.get("q")
    if query:
        # search_term = request.POST.get("q", "")
        search_client = chwrapper.Search(settings.ACCESS_TOKEN)
        response = search_client.search_companies(query)
        response_json = response.json()
        if response_json['total_results'] == 0:
            message = 'No results'
            return render(request, 'customer/profile.html', {'current_customer':current_customer, 'message': message})
        elif response_json['total_results'] > 0:
            company_number = response_json['items'][0]['company_number']
            title = response_json['items'][0]['title']
            address_dict = response_json['items'][0]['address']
            return render(request, 'customer/profile.html', {'current_customer':current_customer, 'company_number': company_number, 'title': title, 'address_dict': address_dict})

    else:
        return render(request, 'customer/profile.html', {'current_customer':current_customer})
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, models, fields, _
from odoo.exceptions import UserError

class PaymentWizard(models.TransientModel):
    _name = 'payment.acquirer.onboarding.wizard'
    _description = 'Payment acquire onboarding wizard'

    payment_method = fields.Selection([
        ('paypal', "Pay with PayPal"),
        ('stripe', "Pay with credit card (via Stripe)"),
        ('other', "Pay with another payment acquirer"),
        ('manual', "Custom payment instructions"),
    ], string="Payment Method", default=lambda self: self._get_default_payment_acquirer_onboarding_value('payment_method'))

    paypal_email_account = fields.Char("PayPal Email ID", default=lambda self: self._get_default_payment_acquirer_onboarding_value('paypal_email_account'))
    paypal_seller_account = fields.Char("Paypal Merchant ID", default=lambda self: self._get_default_payment_acquirer_onboarding_value('paypal_seller_account'))
    paypal_pdt_token = fields.Char("Paypal PDT Token", default=lambda self: self._get_default_payment_acquirer_onboarding_value('paypal_pdt_token'))

    stripe_secret_key = fields.Char(default=lambda self: self._get_default_payment_acquirer_onboarding_value('stripe_secret_key'))
    stripe_publishable_key = fields.Char(default=lambda self: self._get_default_payment_acquirer_onboarding_value('stripe_publishable_key'))

    manual_name = fields.Char("Method",  default=lambda self: self._get_default_payment_acquirer_onboarding_value('manual_name'))
    journal_name = fields.Char("Bank Name", default=lambda self: self._get_default_payment_acquirer_onboarding_value('journal_name'))
    acc_number = fields.Char("Account Number",  default=lambda self: self._get_default_payment_acquirer_onboarding_value('acc_number'))
    manual_post_msg = fields.Html("Payment Instructions")

    @api.onchange('journal_name', 'acc_number')
    def _set_manual_post_msg_value(self):
        self.manual_post_msg = _('Please make a payment to

Bank: %s

Account Number: %s

Account Holder: %s

') %\
                               (self.journal_name or _("Bank") , self.acc_number or _("Account"), self.env.user.company_id.name)

    _payment_acquirer_onboarding_cache = {}
    _data_fetched = False

    def _get_manual_payment_acquirer(self, env=None):
        if env is None:
            env = self.env
        module_id = env.ref('base.module_payment_transfer').id
        return env['payment.acquirer'].search([('module_id', '=', module_id),
            ('company_id', '=', env.user.company_id.id)], limit=1)

    def _get_default_payment_acquirer_onboarding_value(self, key):
        if not self.env.user._is_admin():
            raise UserError(_("Only administrators can access this data."))

        if self._data_fetched:
            return self._payment_acquirer_onboarding_cache.get(key, '')

        self._data_fetched = True

        self._payment_acquirer_onboarding_cache['payment_method'] = self.env.user.company_id.payment_onboarding_payment_method

        installed_modules = self.env['ir.module.module'].sudo().search([
            ('name', 'in', ('payment_paypal', 'payment_stripe')),
            ('state', '=', 'installed'),
        ]).mapped('name')

        if 'payment_paypal' in installed_modules:
            acquirer = self.env.ref('payment.payment_acquirer_paypal')
            self._payment_acquirer_onboarding_cache['paypal_email_account'] = acquirer['paypal_email_account']
            self._payment_acquirer_onboarding_cache['paypal_seller_account'] = acquirer['paypal_seller_account']
            self._payment_acquirer_onboarding_cache['paypal_pdt_token'] = acquirer['paypal_pdt_token']

        if 'payment_stripe' in installed_modules:
            acquirer = self.env.ref('payment.payment_acquirer_stripe')
            self._payment_acquirer_onboarding_cache['stripe_secret_key'] = acquirer['stripe_secret_key']
            self._payment_acquirer_onboarding_cache['stripe_publishable_key'] = acquirer['stripe_publishable_key']

        manual_payment = self._get_manual_payment_acquirer()
        journal = manual_payment.journal_id

        self._payment_acquirer_onboarding_cache['manual_name'] = manual_payment['name']
        self._payment_acquirer_onboarding_cache['manual_post_msg'] = manual_payment['post_msg']
        self._payment_acquirer_onboarding_cache['journal_name'] = journal.name if journal.name != "Bank" else ""
        self._payment_acquirer_onboarding_cache['acc_number'] = journal.bank_acc_number

        return self._payment_acquirer_onboarding_cache.get(key, '')

    def _install_module(self, module_name):
        module = self.env['ir.module.module'].sudo().search([('name', '=', module_name)])
        if module.state not in ('installed', 'to install', 'to upgrade'):
            module.button_immediate_install()

    def _on_save_payment_acquirer(self):
        self._install_module('account_payment')

    @api.multi
    def add_payment_methods(self):
        """ Install required payment acquiers, configure them and mark the
            onboarding step as done."""

        if self.payment_method == 'paypal':
            self._install_module('payment_paypal')

        if self.payment_method == 'stripe':
            self._install_module('payment_stripe')

        if self.payment_method  in ('paypal', 'stripe', 'manual', 'other'):

            self._on_save_payment_acquirer()

            self.env.user.company_id.payment_onboarding_payment_method = self.payment_method

            # create a new env including the freshly installed module(s)
            new_env = api.Environment(self.env.cr, self.env.uid, self.env.context)

            if self.payment_method == 'paypal':
                new_env.ref('payment.payment_acquirer_paypal').write({
                    'paypal_email_account': self.paypal_email_account,
                    'paypal_seller_account': self.paypal_seller_account,
                    'paypal_pdt_token': self.paypal_pdt_token,
                    'website_published': True,
                })
            if self.payment_method == 'stripe':
                new_env.ref('payment.payment_acquirer_stripe').write({
                    'stripe_secret_key': self.stripe_secret_key,
                    'stripe_publishable_key': self.stripe_publishable_key,
                    'website_published': True,
                })
            if self.payment_method == 'manual':
                manual_acquirer = self._get_manual_payment_acquirer(new_env)
                if not manual_acquirer:
                    raise UserError(_(
                        'No manual payment method could be found for this company. ' +
                        'Please create one from the Payment Acquirer menu.'
                    ))
                manual_acquirer.name = self.manual_name
                manual_acquirer.post_msg = self.manual_post_msg
                manual_acquirer.website_published = True

                journal = manual_acquirer.journal_id
                if journal:
                    journal.name = self.journal_name
                    journal.bank_acc_number = self.acc_number
                else:
                    raise UserError(_("You have to set a journal for your payment acquirer %s." % (self.manual_name,)))

            # delete wizard data immediately to get rid of residual credentials
            self.unlink()
        # the user clicked `apply` and not cancel so we can assume this step is done.
        self._set_payment_acquirer_onboarding_step_done()
        return {'type': 'ir.actions.act_window_close'}

    def _set_payment_acquirer_onboarding_step_done(self):
        self.env.user.company_id.set_onboarding_step_done('payment_acquirer_onboarding_state')

    def action_onboarding_other_payment_acquirer(self):
        self._set_payment_acquirer_onboarding_step_done()
        action = self.env.ref('payment.action_payment_acquirer').read()[0]
        return action
<commit_msg>[FIX] payment: Acquired deployed in production<commit_after># -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, models, fields, _
from odoo.exceptions import UserError

class PaymentWizard(models.TransientModel):
    _name = 'payment.acquirer.onboarding.wizard'
    _description = 'Payment acquire onboarding wizard'

    payment_method = fields.Selection([
        ('paypal', "Pay with PayPal"),
        ('stripe', "Pay with credit card (via Stripe)"),
        ('other', "Pay with another payment acquirer"),
        ('manual', "Custom payment instructions"),
    ], string="Payment Method", default=lambda self: self._get_default_payment_acquirer_onboarding_value('payment_method'))

    paypal_email_account = fields.Char("PayPal Email ID", default=lambda self: self._get_default_payment_acquirer_onboarding_value('paypal_email_account'))
    paypal_seller_account = fields.Char("Paypal Merchant ID", default=lambda self: self._get_default_payment_acquirer_onboarding_value('paypal_seller_account'))
    paypal_pdt_token = fields.Char("Paypal PDT Token", default=lambda self: self._get_default_payment_acquirer_onboarding_value('paypal_pdt_token'))

    stripe_secret_key = fields.Char(default=lambda self: self._get_default_payment_acquirer_onboarding_value('stripe_secret_key'))
    stripe_publishable_key = fields.Char(default=lambda self: self._get_default_payment_acquirer_onboarding_value('stripe_publishable_key'))

    manual_name = fields.Char("Method",  default=lambda self: self._get_default_payment_acquirer_onboarding_value('manual_name'))
    journal_name = fields.Char("Bank Name", default=lambda self: self._get_default_payment_acquirer_onboarding_value('journal_name'))
    acc_number = fields.Char("Account Number",  default=lambda self: self._get_default_payment_acquirer_onboarding_value('acc_number'))
    manual_post_msg = fields.Html("Payment Instructions")

    @api.onchange('journal_name', 'acc_number')
    def _set_manual_post_msg_value(self):
        self.manual_post_msg = _('Please make a payment to

Bank: %s

Account Number: %s

Account Holder: %s

') %\
                               (self.journal_name or _("Bank") , self.acc_number or _("Account"), self.env.user.company_id.name)

    _payment_acquirer_onboarding_cache = {}
    _data_fetched = False

    def _get_manual_payment_acquirer(self, env=None):
        if env is None:
            env = self.env
        module_id = env.ref('base.module_payment_transfer').id
        return env['payment.acquirer'].search([('module_id', '=', module_id),
            ('company_id', '=', env.user.company_id.id)], limit=1)

    def _get_default_payment_acquirer_onboarding_value(self, key):
        if not self.env.user._is_admin():
            raise UserError(_("Only administrators can access this data."))

        if self._data_fetched:
            return self._payment_acquirer_onboarding_cache.get(key, '')

        self._data_fetched = True

        self._payment_acquirer_onboarding_cache['payment_method'] = self.env.user.company_id.payment_onboarding_payment_method

        installed_modules = self.env['ir.module.module'].sudo().search([
            ('name', 'in', ('payment_paypal', 'payment_stripe')),
            ('state', '=', 'installed'),
        ]).mapped('name')

        if 'payment_paypal' in installed_modules:
            acquirer = self.env.ref('payment.payment_acquirer_paypal')
            self._payment_acquirer_onboarding_cache['paypal_email_account'] = acquirer['paypal_email_account']
            self._payment_acquirer_onboarding_cache['paypal_seller_account'] = acquirer['paypal_seller_account']
            self._payment_acquirer_onboarding_cache['paypal_pdt_token'] = acquirer['paypal_pdt_token']

        if 'payment_stripe' in installed_modules:
            acquirer = self.env.ref('payment.payment_acquirer_stripe')
            self._payment_acquirer_onboarding_cache['stripe_secret_key'] = acquirer['stripe_secret_key']
            self._payment_acquirer_onboarding_cache['stripe_publishable_key'] = acquirer['stripe_publishable_key']

        manual_payment = self._get_manual_payment_acquirer()
        journal = manual_payment.journal_id

        self._payment_acquirer_onboarding_cache['manual_name'] = manual_payment['name']
        self._payment_acquirer_onboarding_cache['manual_post_msg'] = manual_payment['post_msg']
        self._payment_acquirer_onboarding_cache['journal_name'] = journal.name if journal.name != "Bank" else ""
        self._payment_acquirer_onboarding_cache['acc_number'] = journal.bank_acc_number

        return self._payment_acquirer_onboarding_cache.get(key, '')

    def _install_module(self, module_name):
        module = self.env['ir.module.module'].sudo().search([('name', '=', module_name)])
        if module.state not in ('installed', 'to install', 'to upgrade'):
            module.button_immediate_install()

    def _on_save_payment_acquirer(self):
        self._install_module('account_payment')

    @api.multi
    def add_payment_methods(self):
        """ Install required payment acquiers, configure them and mark the
            onboarding step as done."""

        if self.payment_method == 'paypal':
            self._install_module('payment_paypal')

        if self.payment_method == 'stripe':
            self._install_module('payment_stripe')

        if self.payment_method  in ('paypal', 'stripe', 'manual', 'other'):

            self._on_save_payment_acquirer()

            self.env.user.company_id.payment_onboarding_payment_method = self.payment_method

            # create a new env including the freshly installed module(s)
            new_env = api.Environment(self.env.cr, self.env.uid, self.env.context)

            if self.payment_method == 'paypal':
                new_env.ref('payment.payment_acquirer_paypal').write({
                    'paypal_email_account': self.paypal_email_account,
                    'paypal_seller_account': self.paypal_seller_account,
                    'paypal_pdt_token': self.paypal_pdt_token,
                    'website_published': True,
                    'environment': 'prod',
                })
            if self.payment_method == 'stripe':
                new_env.ref('payment.payment_acquirer_stripe').write({
                    'stripe_secret_key': self.stripe_secret_key,
                    'stripe_publishable_key': self.stripe_publishable_key,
                    'website_published': True,
                    'environment': 'prod',
                })
            if self.payment_method == 'manual':
                manual_acquirer = self._get_manual_payment_acquirer(new_env)
                if not manual_acquirer:
                    raise UserError(_(
                        'No manual payment method could be found for this company. ' +
                        'Please create one from the Payment Acquirer menu.'
                    ))
                manual_acquirer.name = self.manual_name
                manual_acquirer.post_msg = self.manual_post_msg
                manual_acquirer.website_published = True
                manual_acquirer.environment = 'prod'

                journal = manual_acquirer.journal_id
                if journal:
                    journal.name = self.journal_name
                    journal.bank_acc_number = self.acc_number
                else:
                    raise UserError(_("You have to set a journal for your payment acquirer %s." % (self.manual_name,)))

            # delete wizard data immediately to get rid of residual credentials
            self.unlink()
        # the user clicked `apply` and not cancel so we can assume this step is done.
        self._set_payment_acquirer_onboarding_step_done()
        return {'type': 'ir.actions.act_window_close'}

    def _set_payment_acquirer_onboarding_step_done(self):
        self.env.user.company_id.set_onboarding_step_done('payment_acquirer_onboarding_state')

    def action_onboarding_other_payment_acquirer(self):
        self._set_payment_acquirer_onboarding_step_done()
        action = self.env.ref('payment.action_payment_acquirer').read()[0]
        return action
<|endoftext|>


<commit_before>#!/usr/bin/env python
from openpyxl.styles import Font

from EPPs.common import SendMailEPP
from datetime import date
from openpyxl import Workbook

# batch limit function reduces the number of samples in each batch call to prevent server resource error (modified from prepare_discard_plate.py)
def batch_limit(lims, list_instance, max_query=100):
    submitted_samples_batch = []
    for start in range(0, len(list_instance), max_query):
        submitted_samples_batch = submitted_samples_batch + lims.get_batch(list_instance[start:start + max_query])
    return submitted_samples_batch

def get_human_artifacts(lims):
    # find all the human submitted samples in the LIMS
    submitted_samples = lims.get_samples(udf={'Species': 'human'}) + lims.get_samples(
        udf={'Species': 'Homo sapiens'})
    # it is too slow querying each sample for udf and project details so make batch calls to the LIMS using batch_limit function
    submitted_samples_batch = batch_limit(lims, submitted_samples)
    return submitted_samples_batch

def create_excel_report(lims, report_path):
    # obtain the samples present in the LIMS that are from humans and not showing as "Sample Destroyed"
    submitted_samples_batch = get_human_artifacts(lims)

    # create a new xlsx workbook and obtain the active worksheet that is created by default
    wb = Workbook()
    ws = wb.active
    ws.title = 'Human Tissue Report'
    # define lists containing the column headers, the excel columns and the widths of the excel columns
    column_headers = ['PI', 'Sample Type', 'Project Name', 'Submitted Sample Name', 'REC#', 'Ethics Committee',
                      'Freezer', 'Shelf']
    columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
    widths = [20, 15, 15, 25, 20, 60, 20, 20]

    # populate the active worksheet with the column headers and widths as well as formatting fonr to bold
    for header, column, width in zip(column_headers, columns, widths):
        ws[column + '1'] = header
        ws[column + '1'].font = Font(bold=True)
        ws.column_dimensions[column].width = width

    # populate the report with the sample information
    # start the row counter at 2 as the headings are in row 1
    row_counter = 2

    # create a dictionary where key is the sample name so can sort later by reverse sample name when writing csv
    samples_dict = {}
    for sample in submitted_samples_batch:
        samples_dict[sample.name] = sample

    sample_keys_list = samples_dict.keys()

    # sort sample keys
    sample_keys_list = sorted(sample_keys_list, reverse=True)

    # write excel file in sample name reverse alphanumerical order
    for key in sample_keys_list:
        freezer_location = samples_dict[key].udf.get('Freezer')
        project_name = samples_dict[key].project.name
        # only include samples where the freezer location is not "Sample Destroyed" and the project is an actual
        # project identified by starting with an X
        if freezer_location != 'Sample Destroyed' and project_name[0] == 'X1':
            shelf = samples_dict[key].udf.get('Shelf')
            ws['A' + str(row_counter)] = 'Edinburgh Genomics'
            ws['B' + str(row_counter)] = 'DNA'
            ws['C' + str(row_counter)] = project_name
            ws['D' + str(row_counter)] = samples_dict[key].name
            ws['E' + str(row_counter)] = samples_dict[key].project.udf.get('REC#')
            ws['F' + str(row_counter)] = samples_dict[key].project.udf.get(
                'Organisation providing ethical consent approval')
            ws['G' + str(row_counter)] = freezer_location
            ws['H' + str(row_counter)] = shelf
            row_counter += 1

    wb.save(filename=report_path)

class GenerateHumanTissueReport(SendMailEPP):
    """Generate an excel file containing the details of samples in LIMS where the sample UDF Species is human or homo sapiens and the freezer location
    is not Sample Destroyed"""

    # today's date required for file name and email
    todays_date = str(date.today())
    # csv report needs to be accessible throughout object
    report_path = 'Human_Tissue_Report_' + todays_date + '.xlsx'

    def send_email(self):
        msg_subject = "Human Tissue Report - Edinburgh Genomics - " + self.todays_date
        msg = "Hi,\n\nPlease find attached the Human Tissue Report from Edinburgh Genomics Clinical for %s.\n\nKind Regards,\nEdinburgh Genomics" % self.todays_date
        self.send_mail(msg_subject, msg, attachments=[self.report_path], config_name='human_tissue')

    def _run(self):
        create_excel_report(self.lims, self.report_path)
        self.send_email()

if __name__ == '__main__':
    GenerateHumanTissueReport().run()
<commit_msg>Typo corrected in if statement/<commit_after>#!/usr/bin/env python
from openpyxl.styles import Font

from EPPs.common import SendMailEPP
from datetime import date
from openpyxl import Workbook

# batch limit function reduces the number of samples in each batch call to prevent server resource error (modified from prepare_discard_plate.py)
def batch_limit(lims, list_instance, max_query=100):
    submitted_samples_batch = []
    for start in range(0, len(list_instance), max_query):
        submitted_samples_batch = submitted_samples_batch + lims.get_batch(list_instance[start:start + max_query])
    return submitted_samples_batch

def get_human_artifacts(lims):
    # find all the human submitted samples in the LIMS
    submitted_samples = lims.get_samples(udf={'Species': 'human'}) + lims.get_samples(
        udf={'Species': 'Homo sapiens'})
    # it is too slow querying each sample for udf and project details so make batch calls to the LIMS using batch_limit function
    submitted_samples_batch = batch_limit(lims, submitted_samples)
    return submitted_samples_batch

def create_excel_report(lims, report_path):
    # obtain the samples present in the LIMS that are from humans and not showing as "Sample Destroyed"
    submitted_samples_batch = get_human_artifacts(lims)

    # create a new xlsx workbook and obtain the active worksheet that is created by default
    wb = Workbook()
    ws = wb.active
    ws.title = 'Human Tissue Report'
    # define lists containing the column headers, the excel columns and the widths of the excel columns
    column_headers = ['PI', 'Sample Type', 'Project Name', 'Submitted Sample Name', 'REC#', 'Ethics Committee',
                      'Freezer', 'Shelf']
    columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
    widths = [20, 15, 15, 25, 20, 60, 20, 20]

    # populate the active worksheet with the column headers and widths as well as formatting fonr to bold
    for header, column, width in zip(column_headers, columns, widths):
        ws[column + '1'] = header
        ws[column + '1'].font = Font(bold=True)
        ws.column_dimensions[column].width = width

    # populate the report with the sample information
    # start the row counter at 2 as the headings are in row 1
    row_counter = 2

    # create a dictionary where key is the sample name so can sort later by reverse sample name when writing csv
    samples_dict = {}
    for sample in submitted_samples_batch:
        samples_dict[sample.name] = sample

    sample_keys_list = samples_dict.keys()

    # sort sample keys
    sample_keys_list = sorted(sample_keys_list, reverse=True)

    # write excel file in sample name reverse alphanumerical order
    for key in sample_keys_list:
        freezer_location = samples_dict[key].udf.get('Freezer')
        project_name = samples_dict[key].project.name
        # only include samples where the freezer location is not "Sample Destroyed" and the project is an actual
        # project identified by starting with an X
        if freezer_location != 'Sample Destroyed' and project_name[:2] == 'X1':
            shelf = samples_dict[key].udf.get('Shelf')
            ws['A' + str(row_counter)] = 'Edinburgh Genomics'
            ws['B' + str(row_counter)] = 'DNA'
            ws['C' + str(row_counter)] = project_name
            ws['D' + str(row_counter)] = samples_dict[key].name
            ws['E' + str(row_counter)] = samples_dict[key].project.udf.get('REC#')
            ws['F' + str(row_counter)] = samples_dict[key].project.udf.get(
                'Organisation providing ethical consent approval')
            ws['G' + str(row_counter)] = freezer_location
            ws['H' + str(row_counter)] = shelf
            row_counter += 1

    wb.save(filename=report_path)

class GenerateHumanTissueReport(SendMailEPP):
    """Generate an excel file containing the details of samples in LIMS where the sample UDF Species is human or homo sapiens and the freezer location
    is not Sample Destroyed"""

    # today's date required for file name and email
    todays_date = str(date.today())
    # csv report needs to be accessible throughout object
    report_path = 'Human_Tissue_Report_' + todays_date + '.xlsx'

    def send_email(self):
        msg_subject = "Human Tissue Report - Edinburgh Genomics - " + self.todays_date
        msg = "Hi,\n\nPlease find attached the Human Tissue Report from Edinburgh Genomics Clinical for %s.\n\nKind Regards,\nEdinburgh Genomics" % self.todays_date
        self.send_mail(msg_subject, msg, attachments=[self.report_path], config_name='human_tissue')

    def _run(self):
        create_excel_report(self.lims, self.report_path)
        self.send_email()

if __name__ == '__main__':
    GenerateHumanTissueReport().run()
<|endoftext|>