<commit_before>"""
================================================
Comapriation of kernel ridge regression and SVR
================================================

Both kernel ridge regression (KRR) and SVR learn a non-linear function by
employing the kernel trick, i.e., they learn a
linear function in the Reproducing kernel Hilbert space induced by the
respective kernel. They differ in the loss functions (ridge versus epsilon-
insensitive loss). In contrast to SVR, fitting a KRR can be done in closed-
form and is typically faster for medium-sized datasets. On the other hand,
the learned model is non-sparse and thus slower than SVR at prediction-time.

This example illustrates both methods on an artificial dataset, which
consists of a sinusoidal target function and strong noise added to every fifth
datapoint. The first figure compares the learned model of KRR and SVR when both
complexity/regularization and bandwidth of the RBF kernel are optimized using
grid-search. The learned functions are very similar; however, fitting KRR is
approx. seven times faster than fitting SVR (both with grid-search). However,
prediction of 100000 target values is more than tree times faster with SVR since
it has learned a sparse model using only approx. 1/3 of the 100 training
datapoints as support vectors.

The next figure compares the time for fitting and prediction of KRR and SVR for
different sizes of the training set. Fitting KRR is faster than SVR for medium-
sized training sets (less than 1000 samples); however, for larger training sets
SVR scales better. With regard to prediction time, SVR is faster than
KRR for all sizes of the training set because of the learned sparse
solution. Note that the degree of sparsity and thus the prediction time depends
on the parameters epsilon and C of the SVR.
"""

# Authors: Jan Hendrik Metzen <jhm@informatik.uni-bremen.de>
# License: BSD 3 clause

from __future__ import division
import time

import numpy as np

from sklearn.svm import SVR
from sklearn.grid_search import GridSearchCV
from sklearn.learning_curve import learning_curve
from sklearn.kernel_ridge import KernelRidge
import matplotlib.pyplot as plt

np.random.seed(0)

#############################################################################
# Generate sample data
X = 5 * np.random.rand(10000, 1)
y = np.sin(X).ravel()

# Add noise to targets
y[::5] += 3 * (0.5 - np.random.rand(X.shape[0]/5))

X_plot = np.linspace(0, 5, 100000)[:, None]

#############################################################################
# Fit regression model
train_size = 100
svr = GridSearchCV(SVR(kernel='rbf', gamma=1e-1), cv=5,
				   param_grid={"C": [1e0, 1e1, 1e2, 1e3],
							   "gamma": np.logspace(-2, 2, 5)
							   })

kr = GridSearchCV(KernelRidge(kernel='rbf', gamma=1e-1), cv=5,
				  param_grid={"alpha": [1e0, 1e-1, 1e-2, 1e-3],
				  			  "gamma": np.logspace(-2, 2, 5)
				  			  })

t0 = time.time()
svr.fit(X[:train_size], y[:train_size])
svr_fit = time.time() - t0
print("SVR complexity and bandwidth selected and model fitted in %.3f s"
	  % svr_fit)

t0 = time.time()
kr.fit(X[:train_size], y[:train_size])
kr_fit = time.time() - t0
print("KRR complexity and bandwidth selected and model fitted in %.3f s"
	  % kr_fit)

sv_ratio = svr.best_estimator_.support_.shape[0] / train_size
print("Support vector ratio: %.3f" % sv_ratio)

t0 = time.time()
y_svr = svr.predict(X_plot)
svr_predict = time.time() - t0
print("SVR prediction for %d inputs in %.3f s"
	  % (X_plot.shape[0], svr_predict))

t0 = time.time()
y_kr = kr.predict(X_plot)
kr_predict = time.time() - t0
print("KRR prediction for %d inputs in %.3f s"
	  % (X_plot.shape[0], kr_predict))

#############################################################################
# look at the results
sv_ind = svr.best_estimator_.support_
plt.scatter(X[sv_ind], y[sv_ind], c='r', s=50, label='SVR support vectors')
plt.scatter(X[:100], y[:100], c='k', label='data')
plt.hold('on')
plt.plot(X_plot, y_svr, c='r',
	     label='SVR (fit: %.3fs, predict: %.3fs)' % (svr_fit, svr_predict))
plt.plot(X_plot, y_kr, c='g',
	     label='KRR (fit: %.3fs, predict: %.3fs)' % (kr_fit, kr_predict))
plt.xlabel('data')
plt.ylabel('target')
plt.title('SVR versus Kernel Ridge')
plt.legend()

# Visualize training and prediction time
plt.figure()

# Generate sample data
X = 5 * np.random.rand(10000, 1)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - np.random.rand(X.shape[0]/5))
sizes = np.logspace(1, 4, 7)
for name, estimator in {"KRR": KernelRidge(kernel='rbf', alpha=1e-1,
	                                      gamma=1e+1),
             		    "SVR": SVR(kernel='rbf', C=1e1, gamma=1e+1)}.items():
	train_time = []
	test_time = []
	for train_test_size in sizes:
		t0 = time.time()
		estimator.fit(X[:train_test_size], y[:train_test_size])
		train_time.append(time.time() - t0)

		t0 = time.time()
		estimator.predict(X_plot[:1000])
		test_time.append(time.time() - t0)

	plt.plot(sizes, train_time, 'o-', color="r" if name == "svr" else "g",
 		 label="%s (train)" % name)
	plt.plot(sizes, test_time, 'o--', color="r" if name == "svr" else "g",
		 label="%s (test)" % name)

plt.xscale("log")
plt.yscale("log")
plt.xlabel("Train size")
plt.ylabel("Time (seconds)")
plt.title('Execution Time')
plt.legend(loc="best")

# Visualize learning curves
plt.figure()

svr = SVR(kernel='rbf', C=1e1, gamma=1e-1)
kr = KernelRidge(kernel='rbf', alpha=1e-1, gamma=1e-1)
train_sizes, train_scores_svr, test_scores_svr = \
	learning_curve(svr, X[:100], y[:100], train_sizes=np.linspace(0.1, 1, 10),
 				   scoring="mean_squared_error", cv=10)
train_sizes_abs, train_scores_kr, test_scores_kr = \
 	learning_curve(kr, X[:100], y[:100], train_sizes=np.linspace(0.1, 1, 10),
 				   scoring="mean_squared_error", cv=10)

plt.plot(train_sizes, test_scores_svr.mean(1), 'o-', color="r",
 		 label="SVR")
plt.plot(train_sizes, test_scores_kr.mean(1), 'o-', color="g",
		 label="KRR")
plt.xlabel("Train size")
plt.ylabel("Mean Squared Error")
plt.title('Learning curves')
plt.legend(loc="best")

plt.show()
<commit_msg>FIX Fixed assigning colors to methods in KRR example<commit_after>"""
================================================
Comapriation of kernel ridge regression and SVR
================================================

Both kernel ridge regression (KRR) and SVR learn a non-linear function by
employing the kernel trick, i.e., they learn a
linear function in the Reproducing kernel Hilbert space induced by the
respective kernel. They differ in the loss functions (ridge versus epsilon-
insensitive loss). In contrast to SVR, fitting a KRR can be done in closed-
form and is typically faster for medium-sized datasets. On the other hand,
the learned model is non-sparse and thus slower than SVR at prediction-time.

This example illustrates both methods on an artificial dataset, which
consists of a sinusoidal target function and strong noise added to every fifth
datapoint. The first figure compares the learned model of KRR and SVR when both
complexity/regularization and bandwidth of the RBF kernel are optimized using
grid-search. The learned functions are very similar; however, fitting KRR is
approx. seven times faster than fitting SVR (both with grid-search). However,
prediction of 100000 target values is more than tree times faster with SVR since
it has learned a sparse model using only approx. 1/3 of the 100 training
datapoints as support vectors.

The next figure compares the time for fitting and prediction of KRR and SVR for
different sizes of the training set. Fitting KRR is faster than SVR for medium-
sized training sets (less than 1000 samples); however, for larger training sets
SVR scales better. With regard to prediction time, SVR is faster than
KRR for all sizes of the training set because of the learned sparse
solution. Note that the degree of sparsity and thus the prediction time depends
on the parameters epsilon and C of the SVR.
"""

# Authors: Jan Hendrik Metzen <jhm@informatik.uni-bremen.de>
# License: BSD 3 clause

from __future__ import division
import time

import numpy as np

from sklearn.svm import SVR
from sklearn.grid_search import GridSearchCV
from sklearn.learning_curve import learning_curve
from sklearn.kernel_ridge import KernelRidge
import matplotlib.pyplot as plt

np.random.seed(0)

#############################################################################
# Generate sample data
X = 5 * np.random.rand(10000, 1)
y = np.sin(X).ravel()

# Add noise to targets
y[::5] += 3 * (0.5 - np.random.rand(X.shape[0]/5))

X_plot = np.linspace(0, 5, 100000)[:, None]

#############################################################################
# Fit regression model
train_size = 100
svr = GridSearchCV(SVR(kernel='rbf', gamma=1e-1), cv=5,
				   param_grid={"C": [1e0, 1e1, 1e2, 1e3],
							   "gamma": np.logspace(-2, 2, 5)
							   })

kr = GridSearchCV(KernelRidge(kernel='rbf', gamma=1e-1), cv=5,
				  param_grid={"alpha": [1e0, 1e-1, 1e-2, 1e-3],
				  			  "gamma": np.logspace(-2, 2, 5)
				  			  })

t0 = time.time()
svr.fit(X[:train_size], y[:train_size])
svr_fit = time.time() - t0
print("SVR complexity and bandwidth selected and model fitted in %.3f s"
	  % svr_fit)

t0 = time.time()
kr.fit(X[:train_size], y[:train_size])
kr_fit = time.time() - t0
print("KRR complexity and bandwidth selected and model fitted in %.3f s"
	  % kr_fit)

sv_ratio = svr.best_estimator_.support_.shape[0] / train_size
print("Support vector ratio: %.3f" % sv_ratio)

t0 = time.time()
y_svr = svr.predict(X_plot)
svr_predict = time.time() - t0
print("SVR prediction for %d inputs in %.3f s"
	  % (X_plot.shape[0], svr_predict))

t0 = time.time()
y_kr = kr.predict(X_plot)
kr_predict = time.time() - t0
print("KRR prediction for %d inputs in %.3f s"
	  % (X_plot.shape[0], kr_predict))

#############################################################################
# look at the results
sv_ind = svr.best_estimator_.support_
plt.scatter(X[sv_ind], y[sv_ind], c='r', s=50, label='SVR support vectors')
plt.scatter(X[:100], y[:100], c='k', label='data')
plt.hold('on')
plt.plot(X_plot, y_svr, c='r',
	     label='SVR (fit: %.3fs, predict: %.3fs)' % (svr_fit, svr_predict))
plt.plot(X_plot, y_kr, c='g',
	     label='KRR (fit: %.3fs, predict: %.3fs)' % (kr_fit, kr_predict))
plt.xlabel('data')
plt.ylabel('target')
plt.title('SVR versus Kernel Ridge')
plt.legend()

# Visualize training and prediction time
plt.figure()

# Generate sample data
X = 5 * np.random.rand(10000, 1)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - np.random.rand(X.shape[0]/5))
sizes = np.logspace(1, 4, 7)
for name, estimator in {"KRR": KernelRidge(kernel='rbf', alpha=1e-1,
	                                      gamma=1e+1),
             		    "SVR": SVR(kernel='rbf', C=1e1, gamma=1e+1)}.items():
	train_time = []
	test_time = []
	for train_test_size in sizes:
		t0 = time.time()
		estimator.fit(X[:train_test_size], y[:train_test_size])
		train_time.append(time.time() - t0)

		t0 = time.time()
		estimator.predict(X_plot[:1000])
		test_time.append(time.time() - t0)

	plt.plot(sizes, train_time, 'o-', color="r" if name == "SVR" else "g",
 		 label="%s (train)" % name)
	plt.plot(sizes, test_time, 'o--', color="r" if name == "SVR" else "g",
		 label="%s (test)" % name)

plt.xscale("log")
plt.yscale("log")
plt.xlabel("Train size")
plt.ylabel("Time (seconds)")
plt.title('Execution Time')
plt.legend(loc="best")

# Visualize learning curves
plt.figure()

svr = SVR(kernel='rbf', C=1e1, gamma=1e-1)
kr = KernelRidge(kernel='rbf', alpha=1e-1, gamma=1e-1)
train_sizes, train_scores_svr, test_scores_svr = \
	learning_curve(svr, X[:100], y[:100], train_sizes=np.linspace(0.1, 1, 10),
 				   scoring="mean_squared_error", cv=10)
train_sizes_abs, train_scores_kr, test_scores_kr = \
 	learning_curve(kr, X[:100], y[:100], train_sizes=np.linspace(0.1, 1, 10),
 				   scoring="mean_squared_error", cv=10)

plt.plot(train_sizes, test_scores_svr.mean(1), 'o-', color="r",
 		 label="SVR")
plt.plot(train_sizes, test_scores_kr.mean(1), 'o-', color="g",
		 label="KRR")
plt.xlabel("Train size")
plt.ylabel("Mean Squared Error")
plt.title('Learning curves')
plt.legend(loc="best")

plt.show()
<|endoftext|>


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

"""
PyOpenWorm
==========

OpenWorm Unified Data Abstract Layer.

Most statements correspond to some action on the database.
Some of these actions may be complex, but intuitively ``a.B()``, the Query form,
will query against the database for the value or values that are related to ``a`` through ``B``;
on the other hand, ``a.B(c)``, the Update form, will add a statement to the database that ``a``
relates to ``c`` through ``B``. For the Update form, a Relationship object describing the
relationship stated is returned as a side-effect of the update.

The Update form can also be accessed through the set() method of a Property and the Query form through the get()
method like::

    a.B.set(c)

and::

    a.B.get()

The get() method also allows for parameterizing the query in ways specific to the Property.

Relationship objects are key to the :class:`Evidence class <.Evidence>` for sourcing statements.
Relationships can themselves be members in a relationship, allowing for fairly complex hierarchical statements to
be made about entities.

Notes:

- Of course, when these methods communicate with an external database, they may fail due to the database being
  unavailable and the user should be notified if a connection cannot be established in a reasonable time. Also, some
  objects are created by querying the database; these may be made out-of-date in that case.

- ``a : {x_0,...,x_n}`` means ``a`` could have the value of any one of ``x_0`` through ``x_n``

Classes
-------

.. automodule:: PyOpenWorm.evidence
.. automodule:: PyOpenWorm.network
.. automodule:: PyOpenWorm.neuron
.. automodule:: PyOpenWorm.worm
.. automodule:: PyOpenWorm.muscle
.. automodule:: PyOpenWorm.connection
.. automodule:: PyOpenWorm.relationship
.. automodule:: PyOpenWorm.dataObject
.. automodule:: PyOpenWorm.data
.. automodule:: PyOpenWorm.cell
.. automodule:: PyOpenWorm.configure
"""

__version__ = '0.5.0-alhpa'
__author__ = 'Stephen Larson'

import traceback
from .configure import Configure,Configureable,ConfigValue,BadConf
from .data import Data,DataUser,propertyTypes
from .dataObject import *
from .cell import Cell
from .network import Network
from .neuron import Neuron
from .worm import Worm
from .relationship import Relationship
from .evidence import Evidence,EvidenceError
from .muscle import Muscle
from .quantity import Quantity
from .my_neuroml import NeuroML
from .connection import Connection

__import__('__main__').connected = False

def config():
    return Configureable.conf

def useTestConfig():
    cfg = {
            "connectomecsv" : "https://raw.github.com/openworm/data-viz/master/HivePlots/connectome.csv",
            "neuronscsv" : "https://raw.github.com/openworm/data-viz/master/HivePlots/neurons.csv",
            "rdf.source" : "default",
            "rdf.store" : "Sleepycat",
            "rdf.store_conf" : "db/worm.db",
            "user.email" : "jerry@cn.com",
            "rdf.upload_block_statement_count" : 50,
            "test_variable" : "test_value"
          }

    for x in cfg:
        Configureable.conf[x] = cfg[x]
    Configureable.conf = Data(Configureable.conf)

def loadConfig(f):
    """ Load configuration for the module """
    Configureable.conf = Data.open(f)
    return Configureable.conf

def disconnect(c=False):
    """ Close the database """
    m = __import__('__main__')
    if not m.connected:
        return

    if c == False:
        c = Configureable.conf
    if c != False:
        c.closeDatabase()
    m.connected = False

def loadData(data='OpenWormData/out.n3', dataFormat='n3'):
    if data:
        config()['rdf.graph'].parse(data, format=dataFormat)

def connect(configFile='PyOpenWorm/default.conf',
            conf=False,
            do_logging=False,
            data=False,
            dataFormat='n3'):
    """ Load desired configuration and open the database """
    import logging
    import atexit
    m = __import__('__main__')
    if m.connected == True:
        print "PyOpenWorm already connected"
        return

    if do_logging:
        logging.basicConfig(level=logging.DEBUG)

    if conf:
        Configureable.conf = conf
        if not isinstance(conf, Data):
            # Initializes a Data object with
            # the Configureable.conf
            Configureable.conf = Data()
    elif configFile:
        loadConfig(configFile)
    else:
        try:
            from pkg_resources import Requirement, resource_filename
            filename = resource_filename(Requirement.parse("PyOpenWorm"),"db/default.conf")
            Configureable.conf = Data.open(filename)
        except:
            logging.info("Couldn't load default configuration")
            traceback.print_exc()
            Configureable.conf = Data()

    Configureable.conf.openDatabase()
    logging.info("Connected to database")

    # have to register the right one to disconnect...
    atexit.register(disconnect)

    DataObject.register()
    Cell.register()
    Network.register()
    Neuron.register()
    Worm.register()
    Evidence.register()
    Muscle.register()
    Connection.register()
    SimpleProperty.register()
    Property.register()
    Relationship.register()

    m.connected = True
    if data:
        loadData(data, dataFormat)
<commit_msg>minor spelling fix<commit_after># -*- coding: utf-8 -*-

"""
PyOpenWorm
==========

OpenWorm Unified Data Abstract Layer.

Most statements correspond to some action on the database.
Some of these actions may be complex, but intuitively ``a.B()``, the Query form,
will query against the database for the value or values that are related to ``a`` through ``B``;
on the other hand, ``a.B(c)``, the Update form, will add a statement to the database that ``a``
relates to ``c`` through ``B``. For the Update form, a Relationship object describing the
relationship stated is returned as a side-effect of the update.

The Update form can also be accessed through the set() method of a Property and the Query form through the get()
method like::

    a.B.set(c)

and::

    a.B.get()

The get() method also allows for parameterizing the query in ways specific to the Property.

Relationship objects are key to the :class:`Evidence class <.Evidence>` for sourcing statements.
Relationships can themselves be members in a relationship, allowing for fairly complex hierarchical statements to
be made about entities.

Notes:

- Of course, when these methods communicate with an external database, they may fail due to the database being
  unavailable and the user should be notified if a connection cannot be established in a reasonable time. Also, some
  objects are created by querying the database; these may be made out-of-date in that case.

- ``a : {x_0,...,x_n}`` means ``a`` could have the value of any one of ``x_0`` through ``x_n``

Classes
-------

.. automodule:: PyOpenWorm.evidence
.. automodule:: PyOpenWorm.network
.. automodule:: PyOpenWorm.neuron
.. automodule:: PyOpenWorm.worm
.. automodule:: PyOpenWorm.muscle
.. automodule:: PyOpenWorm.connection
.. automodule:: PyOpenWorm.relationship
.. automodule:: PyOpenWorm.dataObject
.. automodule:: PyOpenWorm.data
.. automodule:: PyOpenWorm.cell
.. automodule:: PyOpenWorm.configure
"""

__version__ = '0.5.0-alpha'
__author__ = 'Stephen Larson'

import traceback
from .configure import Configure,Configureable,ConfigValue,BadConf
from .data import Data,DataUser,propertyTypes
from .dataObject import *
from .cell import Cell
from .network import Network
from .neuron import Neuron
from .worm import Worm
from .relationship import Relationship
from .evidence import Evidence,EvidenceError
from .muscle import Muscle
from .quantity import Quantity
from .my_neuroml import NeuroML
from .connection import Connection

__import__('__main__').connected = False

def config():
    return Configureable.conf

def useTestConfig():
    cfg = {
            "connectomecsv" : "https://raw.github.com/openworm/data-viz/master/HivePlots/connectome.csv",
            "neuronscsv" : "https://raw.github.com/openworm/data-viz/master/HivePlots/neurons.csv",
            "rdf.source" : "default",
            "rdf.store" : "Sleepycat",
            "rdf.store_conf" : "db/worm.db",
            "user.email" : "jerry@cn.com",
            "rdf.upload_block_statement_count" : 50,
            "test_variable" : "test_value"
          }

    for x in cfg:
        Configureable.conf[x] = cfg[x]
    Configureable.conf = Data(Configureable.conf)

def loadConfig(f):
    """ Load configuration for the module """
    Configureable.conf = Data.open(f)
    return Configureable.conf

def disconnect(c=False):
    """ Close the database """
    m = __import__('__main__')
    if not m.connected:
        return

    if c == False:
        c = Configureable.conf
    if c != False:
        c.closeDatabase()
    m.connected = False

def loadData(data='OpenWormData/out.n3', dataFormat='n3'):
    if data:
        config()['rdf.graph'].parse(data, format=dataFormat)

def connect(configFile='PyOpenWorm/default.conf',
            conf=False,
            do_logging=False,
            data=False,
            dataFormat='n3'):
    """ Load desired configuration and open the database """
    import logging
    import atexit
    m = __import__('__main__')
    if m.connected == True:
        print "PyOpenWorm already connected"
        return

    if do_logging:
        logging.basicConfig(level=logging.DEBUG)

    if conf:
        Configureable.conf = conf
        if not isinstance(conf, Data):
            # Initializes a Data object with
            # the Configureable.conf
            Configureable.conf = Data()
    elif configFile:
        loadConfig(configFile)
    else:
        try:
            from pkg_resources import Requirement, resource_filename
            filename = resource_filename(Requirement.parse("PyOpenWorm"),"db/default.conf")
            Configureable.conf = Data.open(filename)
        except:
            logging.info("Couldn't load default configuration")
            traceback.print_exc()
            Configureable.conf = Data()

    Configureable.conf.openDatabase()
    logging.info("Connected to database")

    # have to register the right one to disconnect...
    atexit.register(disconnect)

    DataObject.register()
    Cell.register()
    Network.register()
    Neuron.register()
    Worm.register()
    Evidence.register()
    Muscle.register()
    Connection.register()
    SimpleProperty.register()
    Property.register()
    Relationship.register()

    m.connected = True
    if data:
        loadData(data, dataFormat)
<|endoftext|>


<commit_before>from builtins import object
from datetime import timedelta

from bluebottle.members.models import CustomMemberFieldSettings
from .exporter import ExportModelResource
from ..impact.models import ImpactType
from ..segments.models import SegmentType

class ImpactMixin(object):

    def get_extra_fields(self):
        return super(ImpactMixin, self).get_extra_fields() + tuple([
            ("impact:{}".format(impact.slug), impact.name)
            for impact in ImpactType.objects.filter(active=True).all()
        ])

class SegmentMixin(object):
    segment_field = None

    def get_extra_fields(self):
        return super(SegmentMixin, self).get_extra_fields() + tuple([
            ("segment:{}".format(segment.slug), segment.name)
            for segment in SegmentType.objects.filter(is_active=True).all()
        ])

class UserFieldsMixin(object):
    user_field = ''

    def get_extra_fields(self):
        if self.user_field:
            user_path = self.user_field.replace('.', '__') + '__'
        else:
            user_path = ''

        return tuple([
            ("{}extra_{}".format(user_path, extra.name), extra.description)
            for extra in CustomMemberFieldSettings.objects.all()
        ]) + super().get_extra_fields()

class DateRangeResource(ExportModelResource):
    range_field = 'created'
    select_related = None

    def get_queryset(self):
        qs = super(DateRangeResource, self).get_queryset()
        if self.select_related:
            qs = qs.select_related(*self.select_related)
        frm, to = self.kwargs.get('from_date'), self.kwargs.get('to_date')
        to = to + timedelta(days=1)
        return qs.filter(**{'%s__range' % self.range_field: (frm, to)})

class UserResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    range_field = 'date_joined'
    select_related = ('location', 'location__group')

    def get_queryset(self):
        return super(UserResource, self).get_queryset().exclude(email='devteam+accounting@onepercentclub.com')

class InitiativeResource(DateRangeResource):
    select_related = (
        'owner', 'location', 'place',
    )

class PeriodActivityResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner',
    )

class PeriodParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'
    select_related = (
        'activity', 'activity__initiative',
    )

class DateActivityResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner'
    )

class DateActivitySlotResource(DateRangeResource):
    select_related = (
        'activity__initiative', 'activity', 'location', 'location__country',
    )

class DateParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'

    select_related = (
        'activity', 'activity__initiative',
    )

class SlotParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    range_field = 'participant__created'

    segment_field = 'contributor.user'
    user_field = 'contributor.user'

    select_related = (
        'slot', 'participant', 'participant__activity', 'participant__activity__initiative',
        'participant__user',
    )

class TimeContributionResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'contributor.user'
    user_field = 'contributor.user'

    select_related = (
        'contributor',
        'contributor__activity',
        'contributor__user',
        'contributor__activity__initiative',
    )

class FundingResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner'
    )

class DonationResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'

    select_related = (
        'activity', 'user'
    )

class DeedResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner'
    )

class DeedParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'
    select_related = (
        'activity', 'user', 'activity__initiative',
    )

class EffortContributionResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'contributor.user'
    user_field = 'contributor.user'

    select_related = (
        'contributor',
        'contributor__activity',
        'contributor__user',
        'contributor__activity__initiative',
    )
<commit_msg>Revert accidental commit<commit_after>from builtins import object
from datetime import timedelta

from bluebottle.members.models import CustomMemberFieldSettings
from .exporter import ExportModelResource
from ..impact.models import ImpactType
from ..segments.models import SegmentType

class ImpactMixin(object):

    def get_extra_fields(self):
        return super(ImpactMixin, self).get_extra_fields() + tuple([
            ("impact:{}".format(impact.slug), impact.name)
            for impact in ImpactType.objects.filter(active=True).all()
        ])

class SegmentMixin(object):
    segment_field = None

    def get_extra_fields(self):
        return super(SegmentMixin, self).get_extra_fields() + tuple([
            ("segment:{}".format(segment.slug), segment.name)
            for segment in SegmentType.objects.filter(is_active=True).all()
        ])

class UserFieldsMixin(object):
    user_field = ''

    def get_extra_fields(self):
        if self.user_field:
            user_path = self.user_field.replace('.', '__') + '__'
        else:
            user_path = ''

        return tuple([
            ("{}extra_{}".format(user_path, extra.name), extra.description)
            for extra in CustomMemberFieldSettings.objects.all()
        ]) + super().get_extra_fields()

class DateRangeResource(ExportModelResource):
    range_field = 'created'
    select_related = None

    def get_queryset(self):
        qs = super(DateRangeResource, self).get_queryset()
        if self.select_related:
            qs = qs.select_related(*self.select_related)
        frm, to = self.kwargs.get('from_date'), self.kwargs.get('to_date')
        to = to + timedelta(days=1)
        return qs.filter(**{'%s__range' % self.range_field: (frm, to)})

class UserResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    range_field = 'date_joined'
    select_related = ('location', 'location__group')

    def get_queryset(self):
        return super(UserResource, self).get_queryset().exclude(email='devteam+accounting@onepercentclub.com')

class InitiativeResource(DateRangeResource):
    select_related = (
        'owner', 'location', 'place',
    )

class PeriodActivityResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner',
    )

class PeriodParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'
    select_related = (
        'activity', 'activity__initiative',
    )

class DateActivityResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner'
    )

class DateActivitySlotResource(DateRangeResource):
    select_related = (
        'activity__initiative', 'activity', 'location', 'location__country',
    )

class DateParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'

    select_related = (
        'activity', 'activity__initiative',
    )

class SlotParticipantResource(DateRangeResource):
    range_field = 'participant__created'
    select_related = (
        'slot', 'participant', 'participant__activity', 'participant__activity__initiative',
        'participant__user',
    )

class TimeContributionResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'contributor.user'
    user_field = 'contributor.user'

    select_related = (
        'contributor',
        'contributor__activity',
        'contributor__user',
        'contributor__activity__initiative',
    )

class FundingResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner'
    )

class DonationResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'

    select_related = (
        'activity', 'user'
    )

class DeedResource(ImpactMixin, SegmentMixin, DateRangeResource):
    select_related = (
        'initiative', 'owner'
    )

class DeedParticipantResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'user'
    user_field = 'user'
    select_related = (
        'activity', 'user', 'activity__initiative',
    )

class EffortContributionResource(UserFieldsMixin, SegmentMixin, DateRangeResource):
    segment_field = 'contributor.user'
    user_field = 'contributor.user'

    select_related = (
        'contributor',
        'contributor__activity',
        'contributor__user',
        'contributor__activity__initiative',
    )
<|endoftext|>


<commit_before># Copyright 2014 NEC Corporation.  All rights reserved.
#
#    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.
import copy

from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
from tempest.lib.api_schema.response.compute.v2_1 import servers

# Compute microversion 2.3:
# 1. New attributes in 'os-extended-volumes:volumes_attached' dict.
#      'delete_on_termination'
# 2. New attributes in 'server' dict.
#      'OS-EXT-SRV-ATTR:reservation_id'
#      'OS-EXT-SRV-ATTR:launch_index'
#      'OS-EXT-SRV-ATTR:kernel_id'
#      'OS-EXT-SRV-ATTR:ramdisk_id'
#      'OS-EXT-SRV-ATTR:hostname'
#      'OS-EXT-SRV-ATTR:root_device_name'
#      'OS-EXT-SRV-ATTR:user_data'

server_detail = {
    'type': 'object',
    'properties': {
        'id': {'type': 'string'},
        'name': {'type': 'string'},
        'status': {'type': 'string'},
        'image': {'oneOf': [
            {'type': 'object',
                'properties': {
                    'id': {'type': 'string'},
                    'links': parameter_types.links
                },
                'additionalProperties': False,
                'required': ['id', 'links']},
            {'type': ['string', 'null']}
        ]},
        'flavor': {
            'type': 'object',
            'properties': {
                'id': {'type': 'string'},
                'links': parameter_types.links
            },
            'additionalProperties': False,
            'required': ['id', 'links']
        },
        'fault': {
            'type': 'object',
            'properties': {
                'code': {'type': 'integer'},
                'created': {'type': 'string'},
                'message': {'type': 'string'},
                'details': {'type': 'string'},
            },
            'additionalProperties': False,
            # NOTE(gmann): 'details' is not necessary to be present
            #  in the 'fault'. So it is not defined as 'required'.
            'required': ['code', 'created', 'message']
        },
        'user_id': {'type': 'string'},
        'tenant_id': {'type': 'string'},
        'created': {'type': 'string'},
        'updated': {'type': 'string'},
        'progress': {'type': 'integer'},
        'metadata': {'type': 'object'},
        'links': parameter_types.links,
        'addresses': parameter_types.addresses,
        'hostId': {'type': 'string'},
        'OS-DCF:diskConfig': {'type': 'string'},
        'accessIPv4': parameter_types.access_ip_v4,
        'accessIPv6': parameter_types.access_ip_v6,
        'key_name': {'type': ['string', 'null']},
        'security_groups': {'type': 'array'},
        'OS-SRV-USG:launched_at': {'type': ['string', 'null']},
        'OS-SRV-USG:terminated_at': {'type': ['string', 'null']},
        'OS-EXT-AZ:availability_zone': {'type': 'string'},
        'OS-EXT-STS:task_state': {'type': ['string', 'null']},
        'OS-EXT-STS:vm_state': {'type': 'string'},
        'OS-EXT-STS:power_state': parameter_types.power_state,
        'OS-EXT-SRV-ATTR:host': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:instance_name': {'type': 'string'},
        'OS-EXT-SRV-ATTR:hypervisor_hostname': {'type': ['string', 'null']},
        'config_drive': {'type': 'string'},
        # NOTE(gmann): new attributes in version 2.3
        'os-extended-volumes:volumes_attached': {
            'type': 'array',
            'items': {
                'type': 'object',
                'properties': {
                    'id': {'type': 'string'},
                    'delete_on_termination': {'type': 'boolean'}
                },
                'additionalProperties': False,
            },
        },
        'OS-EXT-SRV-ATTR:reservation_id': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:launch_index': {'type': 'integer'},
        'OS-EXT-SRV-ATTR:kernel_id': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:ramdisk_id': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:hostname': {'type': 'string'},
        'OS-EXT-SRV-ATTR:root_device_name': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:user_data': {'type': ['string', 'null']},
    },
    'additionalProperties': False,
    # NOTE(gmann): 'progress' attribute is present in the response
    # only when server's status is one of the progress statuses
    # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
    # 'fault' attribute is present in the response
    # only when server's status is one of the  "ERROR", "DELETED".
    # OS-DCF:diskConfig and accessIPv4/v6 are API
    # extensions, and some environments return a response
    # without these attributes.So these are not defined as 'required'.
    'required': ['id', 'name', 'status', 'image', 'flavor',
                 'user_id', 'tenant_id', 'created', 'updated',
                 'metadata', 'links', 'addresses', 'hostId']
}

server_detail['properties']['addresses']['patternProperties'][
    '^[a-zA-Z0-9-_.]+$']['items']['properties'].update({
        'OS-EXT-IPS:type': {'type': 'string'},
        'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
# NOTE(gmann)dd: Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
# attributes in server address. Those are API extension,
# and some environments return a response without
# these attributes. So they are not 'required'.

get_server = {
    'status_code': [200],
    'response_body': {
        'type': 'object',
        'properties': {
            'server': server_detail
        },
        'additionalProperties': False,
        'required': ['server']
    }
}

list_servers_detail = {
    'status_code': [200],
    'response_body': {
        'type': 'object',
        'properties': {
            'servers': {
                'type': 'array',
                'items': server_detail
            },
            'servers_links': parameter_types.links
        },
        'additionalProperties': False,
        # NOTE(gmann): servers_links attribute is not necessary to be
        # present always So it is not 'required'.
        'required': ['servers']
    }
}

list_servers = copy.deepcopy(servers.list_servers)
<commit_msg>Fill servers schema for microversion 2.3<commit_after># Copyright 2014 NEC Corporation.  All rights reserved.
#
#    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.
import copy

from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
from tempest.lib.api_schema.response.compute.v2_1 import servers

# Compute microversion 2.3:
# 1. New attributes in 'os-extended-volumes:volumes_attached' dict.
#      'delete_on_termination'
# 2. New attributes in 'server' dict.
#      'OS-EXT-SRV-ATTR:reservation_id'
#      'OS-EXT-SRV-ATTR:launch_index'
#      'OS-EXT-SRV-ATTR:kernel_id'
#      'OS-EXT-SRV-ATTR:ramdisk_id'
#      'OS-EXT-SRV-ATTR:hostname'
#      'OS-EXT-SRV-ATTR:root_device_name'
#      'OS-EXT-SRV-ATTR:user_data'

server_detail = {
    'type': 'object',
    'properties': {
        'id': {'type': 'string'},
        'name': {'type': 'string'},
        'status': {'type': 'string'},
        'image': {'oneOf': [
            {'type': 'object',
                'properties': {
                    'id': {'type': 'string'},
                    'links': parameter_types.links
                },
                'additionalProperties': False,
                'required': ['id', 'links']},
            {'type': ['string', 'null']}
        ]},
        'flavor': {
            'type': 'object',
            'properties': {
                'id': {'type': 'string'},
                'links': parameter_types.links
            },
            'additionalProperties': False,
            'required': ['id', 'links']
        },
        'fault': {
            'type': 'object',
            'properties': {
                'code': {'type': 'integer'},
                'created': {'type': 'string'},
                'message': {'type': 'string'},
                'details': {'type': 'string'},
            },
            'additionalProperties': False,
            # NOTE(gmann): 'details' is not necessary to be present
            #  in the 'fault'. So it is not defined as 'required'.
            'required': ['code', 'created', 'message']
        },
        'user_id': {'type': 'string'},
        'tenant_id': {'type': 'string'},
        'created': {'type': 'string'},
        'updated': {'type': 'string'},
        'progress': {'type': 'integer'},
        'metadata': {'type': 'object'},
        'links': parameter_types.links,
        'addresses': parameter_types.addresses,
        'hostId': {'type': 'string'},
        'OS-DCF:diskConfig': {'type': 'string'},
        'accessIPv4': parameter_types.access_ip_v4,
        'accessIPv6': parameter_types.access_ip_v6,
        'key_name': {'type': ['string', 'null']},
        'security_groups': {'type': 'array'},
        'OS-SRV-USG:launched_at': {'type': ['string', 'null']},
        'OS-SRV-USG:terminated_at': {'type': ['string', 'null']},
        'OS-EXT-AZ:availability_zone': {'type': 'string'},
        'OS-EXT-STS:task_state': {'type': ['string', 'null']},
        'OS-EXT-STS:vm_state': {'type': 'string'},
        'OS-EXT-STS:power_state': parameter_types.power_state,
        'OS-EXT-SRV-ATTR:host': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:instance_name': {'type': 'string'},
        'OS-EXT-SRV-ATTR:hypervisor_hostname': {'type': ['string', 'null']},
        'config_drive': {'type': 'string'},
        # NOTE(gmann): new attributes in version 2.3
        'os-extended-volumes:volumes_attached': {
            'type': 'array',
            'items': {
                'type': 'object',
                'properties': {
                    'id': {'type': 'string'},
                    'delete_on_termination': {'type': 'boolean'}
                },
                'additionalProperties': False,
            },
        },
        'OS-EXT-SRV-ATTR:reservation_id': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:launch_index': {'type': 'integer'},
        'OS-EXT-SRV-ATTR:kernel_id': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:ramdisk_id': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:hostname': {'type': 'string'},
        'OS-EXT-SRV-ATTR:root_device_name': {'type': ['string', 'null']},
        'OS-EXT-SRV-ATTR:user_data': {'type': ['string', 'null']},
    },
    'additionalProperties': False,
    # NOTE(gmann): 'progress' attribute is present in the response
    # only when server's status is one of the progress statuses
    # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
    # 'fault' attribute is present in the response
    # only when server's status is one of the  "ERROR", "DELETED".
    # OS-DCF:diskConfig and accessIPv4/v6 are API
    # extensions, and some environments return a response
    # without these attributes.So these are not defined as 'required'.
    'required': ['id', 'name', 'status', 'image', 'flavor',
                 'user_id', 'tenant_id', 'created', 'updated',
                 'metadata', 'links', 'addresses', 'hostId']
}

server_detail['properties']['addresses']['patternProperties'][
    '^[a-zA-Z0-9-_.]+$']['items']['properties'].update({
        'OS-EXT-IPS:type': {'type': 'string'},
        'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
# NOTE(gmann)dd: Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
# attributes in server address. Those are API extension,
# and some environments return a response without
# these attributes. So they are not 'required'.

get_server = {
    'status_code': [200],
    'response_body': {
        'type': 'object',
        'properties': {
            'server': server_detail
        },
        'additionalProperties': False,
        'required': ['server']
    }
}

list_servers_detail = {
    'status_code': [200],
    'response_body': {
        'type': 'object',
        'properties': {
            'servers': {
                'type': 'array',
                'items': server_detail
            },
            'servers_links': parameter_types.links
        },
        'additionalProperties': False,
        # NOTE(gmann): servers_links attribute is not necessary to be
        # present always So it is not 'required'.
        'required': ['servers']
    }
}

# NOTE: Below are the unchanged schema in this microversion. We need
# to keep this schema in this file to have the generic way to select the
# right schema based on self.schema_versions_info mapping in service client.
# ****** Schemas unchanged since microversion 2.1 ***
list_servers = copy.deepcopy(servers.list_servers)
update_server = copy.deepcopy(servers.update_server)
rebuild_server = copy.deepcopy(servers.rebuild_server)
rebuild_server_with_admin_pass = copy.deepcopy(
    servers.rebuild_server_with_admin_pass)
show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
<|endoftext|>


<commit_before>import ujson as json
from functools import wraps
from inspect import signature
from operator import itemgetter
from collections import OrderedDict
import pandas as pd

from .attributes import instance_attributes
from .attributes import json_attributes
from .helpers import create_doc_signature
from .helpers import flatten_dict

class JSONArray(object):
    typ = None

    def __new__(cls, data):
        try:
            return tuple(create_attribute(cls.typ, obj) for obj in data)
        except TypeError:
            msg = f'FAILED TO CREATE OBJECT: {cls.typ} FROM DATA: {data} DATA TYPE: {type(data)}'
            raise Exception(msg)

class Array(type):
    """Used to denote objects that are sent from OANDA in an array.
    Also used to correctly serialize objects.
    """

    def __new__(mcs, typ):
        return super().__new__(mcs, f'Array_{typ.__name__}', (JSONArray,), {'typ': typ})

def format_args(new):
    wraps(new)

    def wrap(cls, *args, **kwargs):
        def format():
            for name, value in kwargs.items():
                try:
                    yield instance_attributes[name], value
                except KeyError:
                    continue

        return new(cls, *args, **dict(format()))

    wrap.__annotations__ = new.__annotations__
    return wrap

class ORM(type):
    instance_attributes = {}
    json_attributes = {}

    def __init__(self, *args, **kwargs):
        super().__init__(self)

    def __new__(mcs, *args, **kwargs):
        class_obj = super().__new__(mcs, *args, **kwargs)
        mcs.instance_attributes = instance_attributes
        mcs.json_attributes = json_attributes

        # Create class signature
        sig = signature(class_obj)

        class_obj.__new__ = format_args(class_obj.__new__)

        # Update
        class_obj.__new__.__signature__ = sig

        # Create a pretty signature for documentation
        class_obj.__doc__ = create_doc_signature(class_obj, sig)

        # This is the overall template of the object.
        # Because Model objects are tuples the order of attributes
        # is important. As can been seen the order of attributes is
        # defined by the order of arguments in the signature
        class_obj.template = OrderedDict.fromkeys(sig.parameters)

        # Create getters for each attribute
        for index, attr in enumerate(class_obj.template):
            setattr(class_obj, attr, property(itemgetter(index)))

        return class_obj

class Model(tuple, metaclass=ORM):

    # Make attribute assignment impossible
    __slots__ = ()

    # The delimiter to use when flattening dictionaries
    _delimiter = '_'

    # Representation string used when generating a summary for this object
    _repr_format = ''

    # Format string used when generating a name for this object

    def __repr__(self):
        def information():
            for attribute in ('amount', 'financing', 'id', 'instrument', 'pl', 'price', 'reason', 'time', 'units'):
                try:
                    value = getattr(self, attribute)
                except IndexError:
                    continue
                if value is not None:
                    yield f'{attribute}={value}'

        return f'<{self.__class__.__name__}: {", ".join(information())}>'

    def __init__(self, *args, **kwargs):
        super().__init__()

    def __new__(cls, *args, **kwargs):

        # contains all the attributes the class contains
        cls._fields = []

        arguments = ((attr, cls.__new__.__annotations__[attr], kwargs[attr]) for attr in cls.template)

        def construct_object_data():
            for name, annotation, value in arguments:
                cls._fields.append(name)
                yield create_attribute(annotation, value) if value else value

        result = tuple.__new__(cls, tuple(construct_object_data()))
        return result

    def json_dict(self, float_to_string=True):
        def fields():
            for field in self._fields:
                attr = getattr(self, field)
                if attr is None:
                    continue
                if not isinstance(attr, (int, float, str)):
                    try:
                        attr = attr.json_dict(float_to_string)
                    except AttributeError:
                        try:
                            attr = [obj.json_dict(float_to_string) for obj in attr]
                        except AttributeError:
                            attr = [str(obj)
                                    if float_to_string and isinstance(obj, float)
                                    else obj
                                    for obj in attr]

                elif float_to_string and isinstance(attr, float):
                    attr = str(attr)
                yield field, attr

        return {self.__class__.json_attributes[field]: attr for field, attr in fields()}

    def json_data(self):
        return json.dumps(self.json_dict(float_to_string=True))

    def data(self, float_to_string=False):
        return flatten_dict(self.json_dict(float_to_string), self._delimiter)

    def series(self):
        def create_data():
            for key, value in self.data(float_to_string=False).items():
                if isinstance(value, str):
                    try:
                        value = int(value)
                    except ValueError:
                        pass
                yield key, value

        return pd.Series(dict(self.template, **dict(create_data())))

def create_attribute(typ, data):
    if typ is None:
        return
    elif isinstance(data, Model):
        result = data
    elif isinstance(data, dict):
        result = typ(**data)
    elif isinstance(data, tuple):
        result = typ(*data)
    else:
        result = typ(data)
    return result
<commit_msg>Added repr to base class<commit_after>import ujson as json
from functools import wraps
from inspect import signature
from operator import itemgetter
from collections import OrderedDict
import pandas as pd

from .attributes import instance_attributes
from .attributes import json_attributes
from .helpers import create_doc_signature
from .helpers import flatten_dict

class JSONArray(object):
    typ = None

    def __new__(cls, data):
        try:
            return tuple(create_attribute(cls.typ, obj) for obj in data)
        except TypeError:
            msg = f'FAILED TO CREATE OBJECT: {cls.typ} FROM DATA: {data} DATA TYPE: {type(data)}'
            raise Exception(msg)

class Array(type):
    """Used to denote objects that are sent from OANDA in an array.
    Also used to correctly serialize objects.
    """

    def __new__(mcs, typ):
        return super().__new__(mcs, f'Array_{typ.__name__}', (JSONArray,), {'typ': typ})

def format_args(new):
    wraps(new)

    def wrap(cls, *args, **kwargs):
        def format():
            for name, value in kwargs.items():
                try:
                    yield instance_attributes[name], value
                except KeyError:
                    continue

        return new(cls, *args, **dict(format()))

    wrap.__annotations__ = new.__annotations__
    return wrap

class ORM(type):
    instance_attributes = {}
    json_attributes = {}

    def __init__(self, *args, **kwargs):
        super().__init__(self)

    def __new__(mcs, *args, **kwargs):
        class_obj = super().__new__(mcs, *args, **kwargs)
        mcs.instance_attributes = instance_attributes
        mcs.json_attributes = json_attributes

        # Create class signature
        sig = signature(class_obj)

        class_obj.__new__ = format_args(class_obj.__new__)

        # Update
        class_obj.__new__.__signature__ = sig

        # Create a pretty signature for documentation
        class_obj.__doc__ = create_doc_signature(class_obj, sig)

        # This is the overall template of the object.
        # Because Model objects are tuples the order of attributes
        # is important. As can been seen the order of attributes is
        # defined by the order of arguments in the signature
        class_obj.template = OrderedDict.fromkeys(sig.parameters)

        # Create getters for each attribute
        for index, attr in enumerate(class_obj.template):
            setattr(class_obj, attr, property(itemgetter(index)))

        return class_obj

class Model(tuple, metaclass=ORM):

    # Make attribute assignment impossible
    __slots__ = ()

    # The delimiter to use when flattening dictionaries
    _delimiter = '_'

    # Representation string used when generating a summary for this object
    _repr_format = ''

    # Format string used when generating a name for this object

    def __repr__(self):
        def information():
            for attribute in ('amount', 'financing', 'id', 'instrument', 'pl', 'price', 'reason', 'time', 'units'):
                try:
                    value = getattr(self, attribute)
                except (IndexError, AttributeError):
                    continue
                if value is not None:
                    yield f'{attribute}={value}'

        return f'<{self.__class__.__name__}: {", ".join(information())}>'

    def __init__(self, *args, **kwargs):
        super().__init__()

    def __new__(cls, *args, **kwargs):

        # contains all the attributes the class contains
        cls._fields = []

        arguments = ((attr, cls.__new__.__annotations__[attr], kwargs[attr]) for attr in cls.template)

        def construct_object_data():
            for name, annotation, value in arguments:
                cls._fields.append(name)
                yield create_attribute(annotation, value) if value else value

        result = tuple.__new__(cls, tuple(construct_object_data()))
        return result

    def json_dict(self, float_to_string=True):
        def fields():
            for field in self._fields:
                attr = getattr(self, field)
                if attr is None:
                    continue
                if not isinstance(attr, (int, float, str)):
                    try:
                        attr = attr.json_dict(float_to_string)
                    except AttributeError:
                        try:
                            attr = [obj.json_dict(float_to_string) for obj in attr]
                        except AttributeError:
                            attr = [str(obj)
                                    if float_to_string and isinstance(obj, float)
                                    else obj
                                    for obj in attr]

                elif float_to_string and isinstance(attr, float):
                    attr = str(attr)
                yield field, attr

        return {self.__class__.json_attributes[field]: attr for field, attr in fields()}

    def json_data(self):
        return json.dumps(self.json_dict(float_to_string=True))

    def data(self, float_to_string=False):
        return flatten_dict(self.json_dict(float_to_string), self._delimiter)

    def series(self):
        def create_data():
            for key, value in self.data(float_to_string=False).items():
                if isinstance(value, str):
                    try:
                        value = int(value)
                    except ValueError:
                        pass
                yield key, value

        return pd.Series(dict(self.template, **dict(create_data())))

def create_attribute(typ, data):
    if typ is None:
        return
    elif isinstance(data, Model):
        result = data
    elif isinstance(data, dict):
        result = typ(**data)
    elif isinstance(data, tuple):
        result = typ(*data)
    else:
        result = typ(data)
    return result
<|endoftext|>


<commit_before>"""
Copyright (c) 2013 Mohd. Kamal Bin Mustafa

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import os
import sys
import urllib
import httplib
import subprocess
import cStringIO
import traceback
import posixpath
import mimetypes

from urlparse import urlparse
from wsgiref.simple_server import make_server
from SimpleHTTPServer import SimpleHTTPRequestHandler

HERE = os.path.abspath(os.path.dirname(__file__))

def parse_url(url):
    po = urlparse(url)
    file_path = po.path.lstrip('/')
    file_path_part = []
    path_info_part = []
    php_part_done = False
    for segment in file_path.split('/'):
        if '.php' in segment:
            php_part_done = True
            file_path_part.append(segment)
            continue
        if not php_part_done:
            file_path_part.append(segment)
        else:
            path_info_part.append(segment)

    path_info = '/'.join(path_info_part)
    file_path = '/'.join(file_path_part)
    query_string = po.query

    return file_path, path_info, query_string

class PHPApp(object):
    def __init__(self, doc_root=None):
        self.doc_root = doc_root

        if doc_root:
            self.cwd = os.path.join(HERE, doc_root)
        else:
            self.cwd = HERE

    def _abs_file_path(self, path):
        return os.path.join(self.cwd, path)

    def __call__(self, environ, start_response):
        content = None
        file_path, path_info, query_string = parse_url(environ['PATH_INFO'])

        extension = file_path.split('/')[-1][-3:]

        if extension != 'php':
            return self.serve_static(environ, start_response, self._abs_file_path(file_path))

        php_args = ['php5-cgi', self._abs_file_path(file_path)]
        php_env = {}
        # REDIRECT_STATUS must be set. See:
        # http://php.net/manual/en/security.cgi-bin.force-redirect.php
        php_env['REDIRECT_STATUS'] = '1'
        php_env['REQUEST_METHOD'] = environ.get('REQUEST_METHOD', 'GET')
        php_env['PATH_INFO'] = path_info
        php_env['QUERY_STRING'] = environ['QUERY_STRING']
        php_env['SCRIPT_FILENAME'] = os.path.join(HERE, self._abs_file_path(file_path))
        php_env['SCRIPT_NAME'] = ''
        php_env['HTTP_HOST'] = environ['HTTP_HOST']
        php_env['SERVER_SOFTWARE'] = 'phpdev.py'

        # Construct the partial URL that PHP expects for REQUEST_URI
        # (http://php.net/manual/en/reserved.variables.server.php) using part of
        # the process described in PEP-333
        # (http://www.python.org/dev/peps/pep-0333/#url-reconstruction).
        php_env['REQUEST_URI'] = urllib.quote(environ['PATH_INFO'])
        if php_env['QUERY_STRING']:
            php_env['REQUEST_URI'] += '?' + php_env['QUERY_STRING']

        if 'CONTENT_TYPE' in environ:
            php_env['CONTENT_TYPE'] = environ['CONTENT_TYPE']
            php_env['HTTP_CONTENT_TYPE'] = environ['CONTENT_TYPE']

        # POST data
        if 'CONTENT_LENGTH' in environ:
            if environ['CONTENT_LENGTH'].strip():
                php_env['CONTENT_LENGTH'] = environ['CONTENT_LENGTH']
                php_env['HTTP_CONTENT_LENGTH'] = environ['CONTENT_LENGTH']
                content = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))

        try:
            p = subprocess.Popen(php_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE, env=php_env, cwd=self.cwd)
        except Exception as e:
            start_response('500 Internal Server Error', [('Content-Type', 'text/html')])
            return [traceback.format_exc()]

        stdout, stderr = p.communicate(content)

        message = httplib.HTTPMessage(cStringIO.StringIO(stdout))
        assert 'Content-Type' in message, 'invalid CGI response: %r' % stdout

        if 'Status' in message:
            status = message['Status']
            del message['Status']
        else:
            status = '200 OK'

        # Ensures that we avoid merging repeat headers into a single header,
        # allowing use of multiple Set-Cookie headers.
        headers = []
        for name in message:
            for value in message.getheaders(name):
                headers.append((name, value))

        start_response(status, headers)
        return [message.fp.read()]

    def serve_static(self, environ, start_response, file_path):
        mimetype, encoding = mimetypes.guess_type(file_path)
        size = os.path.getsize(file_path)
        headers = [
            ("Content-type", mimetype),
            ("Content-length", str(size)),
        ]
        start_response("200 OK", headers)
        return self.send_file(file_path, size)

    def send_file(self, file_path, size):
        BLOCK_SIZE = 4096
        fh = open(file_path, 'r')
        while True:
            block = fh.read(BLOCK_SIZE)
            if not block:
                fh.close()
                break
            yield block

if __name__ == '__main__':
    application = PHPApp()
    server = make_server('0.0.0.0', 8080, application)
    print "Running at http://127.0.0.1:8080 ..."
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit()
<commit_msg>handle not found and None mimetype<commit_after>"""
Copyright (c) 2013 Mohd. Kamal Bin Mustafa

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import os
import sys
import urllib
import httplib
import subprocess
import cStringIO
import traceback
import posixpath
import mimetypes

from urlparse import urlparse
from wsgiref.simple_server import make_server
from SimpleHTTPServer import SimpleHTTPRequestHandler

HERE = os.path.abspath(os.path.dirname(__file__))

def parse_url(url):
    po = urlparse(url)
    file_path = po.path.lstrip('/')
    file_path_part = []
    path_info_part = []
    php_part_done = False
    for segment in file_path.split('/'):
        if '.php' in segment:
            php_part_done = True
            file_path_part.append(segment)
            continue
        if not php_part_done:
            file_path_part.append(segment)
        else:
            path_info_part.append(segment)

    path_info = '/'.join(path_info_part)
    file_path = '/'.join(file_path_part)
    query_string = po.query

    return file_path, path_info, query_string

class PHPApp(object):
    def __init__(self, doc_root=None):
        self.doc_root = doc_root

        if doc_root:
            self.cwd = os.path.join(HERE, doc_root)
        else:
            self.cwd = HERE

    def _abs_file_path(self, path):
        return os.path.join(self.cwd, path)

    def __call__(self, environ, start_response):
        content = None
        file_path, path_info, query_string = parse_url(environ['PATH_INFO'])

        extension = file_path.split('/')[-1][-3:]

        if extension != 'php':
            return self.serve_static(environ, start_response, self._abs_file_path(file_path))

        php_args = ['php5-cgi', self._abs_file_path(file_path)]
        php_env = {}
        # REDIRECT_STATUS must be set. See:
        # http://php.net/manual/en/security.cgi-bin.force-redirect.php
        php_env['REDIRECT_STATUS'] = '1'
        php_env['REQUEST_METHOD'] = environ.get('REQUEST_METHOD', 'GET')
        php_env['PATH_INFO'] = path_info
        php_env['QUERY_STRING'] = environ['QUERY_STRING']
        php_env['SCRIPT_FILENAME'] = os.path.join(HERE, self._abs_file_path(file_path))
        php_env['SCRIPT_NAME'] = ''
        php_env['HTTP_HOST'] = environ['HTTP_HOST']
        php_env['SERVER_SOFTWARE'] = 'phpdev.py'

        # Construct the partial URL that PHP expects for REQUEST_URI
        # (http://php.net/manual/en/reserved.variables.server.php) using part of
        # the process described in PEP-333
        # (http://www.python.org/dev/peps/pep-0333/#url-reconstruction).
        php_env['REQUEST_URI'] = urllib.quote(environ['PATH_INFO'])
        if php_env['QUERY_STRING']:
            php_env['REQUEST_URI'] += '?' + php_env['QUERY_STRING']

        if 'CONTENT_TYPE' in environ:
            php_env['CONTENT_TYPE'] = environ['CONTENT_TYPE']
            php_env['HTTP_CONTENT_TYPE'] = environ['CONTENT_TYPE']

        # POST data
        if 'CONTENT_LENGTH' in environ:
            if environ['CONTENT_LENGTH'].strip():
                php_env['CONTENT_LENGTH'] = environ['CONTENT_LENGTH']
                php_env['HTTP_CONTENT_LENGTH'] = environ['CONTENT_LENGTH']
                content = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))

        try:
            p = subprocess.Popen(php_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE, env=php_env, cwd=self.cwd)
        except Exception as e:
            start_response('500 Internal Server Error', [('Content-Type', 'text/html')])
            return [traceback.format_exc()]

        stdout, stderr = p.communicate(content)

        message = httplib.HTTPMessage(cStringIO.StringIO(stdout))
        assert 'Content-Type' in message, 'invalid CGI response: %r' % stdout

        if 'Status' in message:
            status = message['Status']
            del message['Status']
        else:
            status = '200 OK'

        # Ensures that we avoid merging repeat headers into a single header,
        # allowing use of multiple Set-Cookie headers.
        headers = []
        for name in message:
            for value in message.getheaders(name):
                headers.append((name, value))

        start_response(status, headers)
        return [message.fp.read()]

    def serve_static(self, environ, start_response, file_path):
        if not os.path.exists(file_path):
            start_response("404 Not Found", [('Content-type', 'text/plain')])
            return ['Not Found',]

        mimetype, encoding = mimetypes.guess_type(file_path)
        size = os.path.getsize(file_path)
        headers = [
            ("Content-type", mimetype if mimetype else 'text/plain'),
            ("Content-length", str(size)),
        ]

        start_response("200 OK", headers)
        return self.send_file(file_path, size)

    def send_file(self, file_path, size):
        BLOCK_SIZE = 4096
        fh = open(file_path, 'r')
        while True:
            block = fh.read(BLOCK_SIZE)
            if not block:
                fh.close()
                break
            yield block

if __name__ == '__main__':
    application = PHPApp()
    server = make_server('0.0.0.0', 8080, application)
    print "Running at http://127.0.0.1:8080 ..."
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#

from datetime import datetime, date, timedelta

ONE_DAY = timedelta(days=1)

DATE_RANGE_MIN = date(2018, 8, 25)
DATE_RANGE_MAX = date(2019, 7, 5)

def timenow():
    return datetime.now()

def today():
    return date.today()

def weekday():
    return date.today().weekday()

def tommorow():
    return today() + ONE_DAY

def this_week():
    return (today() - timedelta(weekday()),
            today() + timedelta(6 - weekday()))

def next_week():
    return (today() - timedelta(weekday()) + timedelta(7),
            today() + timedelta(6 - weekday()) + timedelta(7))

def next_next_week():
    return (today() - timedelta(weekday()) + timedelta(14),
            today() + timedelta(6 - weekday()) + timedelta(14))

def str_to_date_dict():
    return {'today': today(),
            'tmrw': tommorow(),
            'thisweek': this_week(),
            'nextweek': next_week(),
            'nextnextweek': next_next_week()}

def date_to_str_dict():
    return {d: s for s, d in str_to_date_dict().items()}

def str_to_words_dict():
    return {'today': 'today',
            'tmrw': 'tommorow',
            'thisweek': 'this week',
            'nextweek': 'next week',
            'nextnextweek': 'next next week'}

date_fmtstr = '%Y%m%d'

def int_to_dateobj(dateint):
    return datetime.strptime(str(dateint), date_fmtstr).date()

def dateobj_to_int(dateobj):
    return int(dateobj.strftime(date_fmtstr))

def date_range_iterator(start_date, end_date):
    # both sides inclusive: [start, end]
    for n in range(int((end_date - start_date).days) + 1):
        yield start_date + timedelta(n)
<commit_msg>updated date range<commit_after>#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#

from datetime import datetime, date, timedelta

ONE_DAY = timedelta(days=1)

DATE_RANGE_MIN = date(2019, 8, 25)
DATE_RANGE_MAX = date(2020, 7, 5)

def timenow():
    return datetime.now()

def today():
    return date.today()

def weekday():
    return date.today().weekday()

def tommorow():
    return today() + ONE_DAY

def this_week():
    return (today() - timedelta(weekday()),
            today() + timedelta(6 - weekday()))

def next_week():
    return (today() - timedelta(weekday()) + timedelta(7),
            today() + timedelta(6 - weekday()) + timedelta(7))

def next_next_week():
    return (today() - timedelta(weekday()) + timedelta(14),
            today() + timedelta(6 - weekday()) + timedelta(14))

def str_to_date_dict():
    return {'today': today(),
            'tmrw': tommorow(),
            'thisweek': this_week(),
            'nextweek': next_week(),
            'nextnextweek': next_next_week()}

def date_to_str_dict():
    return {d: s for s, d in str_to_date_dict().items()}

def str_to_words_dict():
    return {'today': 'today',
            'tmrw': 'tommorow',
            'thisweek': 'this week',
            'nextweek': 'next week',
            'nextnextweek': 'next next week'}

date_fmtstr = '%Y%m%d'

def int_to_dateobj(dateint):
    return datetime.strptime(str(dateint), date_fmtstr).date()

def dateobj_to_int(dateobj):
    return int(dateobj.strftime(date_fmtstr))

def date_range_iterator(start_date, end_date):
    # both sides inclusive: [start, end]
    for n in range(int((end_date - start_date).days) + 1):
        yield start_date + timedelta(n)
<|endoftext|>


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

# modDMXthread.py for limux environments
# uses http://www.erwinrol.com/open-dmx-usb-linux-driver/
# you may have to rmmod ftdi_soi, which will bork any other usb-serial
# unless you are more gifted in the kernel hacking department than me
# This has been tested with a FTDI chip and this board:
# CelestialAudio DMX-32

import sys
import serial

# import struct

import time
import math
import colorsys
import Queue
import threading

class sendThread(threading.Thread):
    """Process that listens to queue and if there is a message on it
    (array of bytes), sends it out the serial port in DMX protocol"""
    def __init__(self, ser, queue):
        threading.Thread.__init__(self)
        self.ser = ser
        self.queue = queue

    def run(self):
        while True:
            # get data from queue
            msg = self.queue.get()

           # start the packet
            #self.ser.sendBreak(duration=0.0005)

            # and send it
            self.ser.write(msg)
            self.ser.flush()
            # self.ser.drainOutput()
            self.queue.task_done()

    def flush(self):
        while self.queue.qsize() > 0:
            self.queue.get()
            self.queue.task_done()

class DMXUniverse(object):
    """Class to hold and manage buffer of DMX information and to queue
    it to sendThread worker process"""
    def __init__(self, portname):
        self.portname = portname
        self.verbose = False
        self.check = True  # False to disable range assertions

        # make the byte buffer that will hold the output data
        nullstr = u'00 ' * 513  # must start with null byte
        self.buf = bytearray.fromhex(nullstr)

        # output queue for serial port thread
        self.queue = Queue.Queue()

        self.s = open(portname,'w')
        #self.s = serial.Serial(port=portname, baudrate=38400,
        #                       writeTimeout=1.0,
        #                       stopbits=serial.STOPBITS_TWO)

        # start serial output thread
        self.sendthread = sendThread(self.s, self.queue)
        self.sendthread.setDaemon(True)
        self.sendthread.start()

    def set_chan_int(self, DMX_channel, DMX_value):
        """set this absolute DMX channel to value (absolute channel number)"""

        if self.verbose:
            print 'setting DMX %d to %d' % (DMX_channel, DMX_value)
            sys.stdout.flush()
        if self.check: # are we being picky?
            assert DMX_channel >= 0
            assert DMX_channel < 512
            assert DMX_value < 256
            assert DMX_value >= 0
        self.buf[DMX_channel + 1] = DMX_value

    def __str__(self):
        return '<DMXUniverse %s>' % self.name

    def printbuf(self, start=0, stop=512):
        """print out buffer contents for debugging"""
        for i in range(start, stop):
            if self.buf[i] > 0:
                print 'chan %d val: %d' % (i, self.buf[i])
                sys.stdout.flush()

    def print_buffer(self, start, end):
        """for debugging mostly, oops, duplicate, fix"""
        for i in range(start, end):
            print 'chan %3d val %3d' % (i, int(self.buf[i + 1]))

    def c2int(self, color):
        """convert floating point normalized value [0.0-1.0] to byte"""
        if color > 1.0:
            color = 1.0
        if color < 0:
            color = 0
        return int(color * 255)

    def set_chan_float(self, chan, fval):
        """set the given DMX channel to the given float [0-1] value"""
        self.set_chan_int(chan, self.c2int(fval))

    def send_buffer(self):
        """Queue buffer to DMX output"""
        if self.s:
            qs = self.queue.qsize()
            if qs > 10: # buffer is filling up, print warning
                print 'queue %d, skipping frame' % qs
                sys.stdout.flush()
            else:
                #print 'sending buffer length ' + str(len(self.buf))
                #sys.stdout.flush()
                self.queue.put(self.buf, block=False)

# if running from the console, do some test stuff from the command line
if __name__ == '__main__':

    univ = DMXUniverse('/dev/dmx0')
    if len(sys.argv) < 4:
        print """usage: DMXthread start_chan end_chan val
            sets all DMX channels between start and end-1 to val"""
        exit()
    univ.verbose = True
    start = int(sys.argv[1])
    end = int(sys.argv[2])
    val = int(sys.argv[3])
    for c in range(start, end):
        univ.set_chan_int(c, val)
    while(1):
        univ.send_buffer()
        time.sleep(0.1)
    # don't kill thread until we've done the work!
    time.sleep(0.1)

<commit_msg>remove dep on serial<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

# modDMXthread.py for limux environments
# uses http://www.erwinrol.com/open-dmx-usb-linux-driver/
# you may have to rmmod ftdi_soi, which will bork any other usb-serial
# unless you are more gifted in the kernel hacking department than me
# This has been tested with a FTDI chip and this board:
# CelestialAudio DMX-32

import sys
#import serial

# import struct

import time
import math
import colorsys
import Queue
import threading

class sendThread(threading.Thread):
    """Process that listens to queue and if there is a message on it
    (array of bytes), sends it out the serial port in DMX protocol"""
    def __init__(self, ser, queue):
        threading.Thread.__init__(self)
        self.ser = ser
        self.queue = queue

    def run(self):
        while True:
            # get data from queue
            msg = self.queue.get()

           # start the packet
            #self.ser.sendBreak(duration=0.0005)

            # and send it
            self.ser.write(msg)
            self.ser.flush()
            # self.ser.drainOutput()
            self.queue.task_done()

    def flush(self):
        while self.queue.qsize() > 0:
            self.queue.get()
            self.queue.task_done()

class DMXUniverse(object):
    """Class to hold and manage buffer of DMX information and to queue
    it to sendThread worker process"""
    def __init__(self, portname):
        self.portname = portname
        self.verbose = False
        self.check = True  # False to disable range assertions

        # make the byte buffer that will hold the output data
        nullstr = u'00 ' * 513  # must start with null byte
        self.buf = bytearray.fromhex(nullstr)

        # output queue for serial port thread
        self.queue = Queue.Queue()

        self.s = open(portname,'w')
        #self.s = serial.Serial(port=portname, baudrate=38400,
        #                       writeTimeout=1.0,
        #                       stopbits=serial.STOPBITS_TWO)

        # start serial output thread
        self.sendthread = sendThread(self.s, self.queue)
        self.sendthread.setDaemon(True)
        self.sendthread.start()

    def set_chan_int(self, DMX_channel, DMX_value):
        """set this absolute DMX channel to value (absolute channel number)"""

        if self.verbose:
            print 'setting DMX %d to %d' % (DMX_channel, DMX_value)
            sys.stdout.flush()
        if self.check: # are we being picky?
            assert DMX_channel >= 0
            assert DMX_channel < 512
            assert DMX_value < 256
            assert DMX_value >= 0
        self.buf[DMX_channel + 1] = DMX_value

    def __str__(self):
        return '<DMXUniverse %s>' % self.name

    def printbuf(self, start=0, stop=512):
        """print out buffer contents for debugging"""
        for i in range(start, stop):
            if self.buf[i] > 0:
                print 'chan %d val: %d' % (i, self.buf[i])
                sys.stdout.flush()

    def print_buffer(self, start, end):
        """for debugging mostly, oops, duplicate, fix"""
        for i in range(start, end):
            print 'chan %3d val %3d' % (i, int(self.buf[i + 1]))

    def c2int(self, color):
        """convert floating point normalized value [0.0-1.0] to byte"""
        if color > 1.0:
            color = 1.0
        if color < 0:
            color = 0
        return int(color * 255)

    def set_chan_float(self, chan, fval):
        """set the given DMX channel to the given float [0-1] value"""
        self.set_chan_int(chan, self.c2int(fval))

    def send_buffer(self):
        """Queue buffer to DMX output"""
        if self.s:
            qs = self.queue.qsize()
            if qs > 10: # buffer is filling up, print warning
                print 'queue %d, skipping frame' % qs
                sys.stdout.flush()
            else:
                #print 'sending buffer length ' + str(len(self.buf))
                #sys.stdout.flush()
                self.queue.put(self.buf, block=False)

# if running from the console, do some test stuff from the command line
if __name__ == '__main__':

    univ = DMXUniverse('/dev/dmx0')
    if len(sys.argv) < 4:
        print """usage: DMXthread start_chan end_chan val
            sets all DMX channels between start and end-1 to val"""
        exit()
    univ.verbose = True
    start = int(sys.argv[1])
    end = int(sys.argv[2])
    val = int(sys.argv[3])
    for c in range(start, end):
        univ.set_chan_int(c, val)
    while(1):
        univ.send_buffer()
        time.sleep(0.1)
    # don't kill thread until we've done the work!
    time.sleep(0.1)

<|endoftext|>


<commit_before>version_info = (4, 0, 0)
__version__ = '.'.join(map(str, version_info))
<commit_msg>Bump to v5.0.0dev<commit_after>version_info = (5, 0, 0, 'dev')
__version__ = '.'.join(map(str, version_info))
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""
The full public woven api
"""
from woven.deployment import deploy_files, mkdirs
from woven.deployment import upload_template, run_once_per_host_version

from woven.environment import deployment_root, set_env, patch_project, server_state, set_server_state
from woven.environment import project_name, project_fullname, project_version

from woven.project import deploy_static, deploy_public, deploy_project, deploy_db, deploy_templates

from woven.ubuntu import add_user, apt_get_install, apt_get_purge
from woven.ubuntu import install_packages, upgrade_ubuntu, setup_ufw, disable_root
from woven.ubuntu import uncomment_sources, restrict_ssh, upload_ssh_key
from woven.ubuntu import change_ssh_port, set_timezone, ubuntu_version, upload_etc

from woven.virtualenv import activate, active_version
from woven.virtualenv import mkvirtualenv, rmvirtualenv, pip_install_requirements

from woven.webservers import deploy_wsgi, deploy_webconf, start_webservers, stop_webservers, reload_webservers

def deploy():
    """
    deploy a versioned project on the host
    """
    deploy_funcs = [deploy_project,deploy_templates, deploy_static, deploy_public,  deploy_webconf, deploy_wsgi]
    if not patch_project():
        deploy_funcs = [deploy_db,mkvirtualenv,pip_install_requirements] + deploy_funcs
    for func in deploy_funcs: func()

def setupnode(rollback=False, overwrite=False):
    """
    Install a baseline host. Can be run multiple times

    rollback=True to teardown the installation
    This is just used to prevent having to rollback a virtual machine
    """

    #either fabric or manage.py will setup the roles & hosts env
    #setup_environ handles passing all the project settings into env
    #and any woven.global_settings not already defined.
    if not rollback:
        port_changed = change_ssh_port()
        #We need to assume that if the port does not get changed that
        #it has already been done and thus we do not need to disable root
        if port_changed:
            disable_root()
        upload_ssh_key()
        restrict_ssh()
        uncomment_sources()
        upgrade_ubuntu()
        setup_ufw()
        install_packages(overwrite=overwrite)
        upload_etc()
        set_timezone()
        stop_webservers()
        start_webservers()

    else:
        #rollback in reverse order of installation
        #The only things we don't rollback are the updates
        set_timezone(rollback)
        install_packages(rollback)
        setup_ufw(rollback)
        uncomment_sources(rollback)
        restrict_ssh(rollback)
        upload_ssh_key(rollback)
        disable_root(rollback)
        change_ssh_port(rollback)

<commit_msg>removed rollback from api<commit_after>#!/usr/bin/env python
"""
The full public woven api
"""
from woven.deployment import deploy_files, mkdirs
from woven.deployment import upload_template, run_once_per_host_version

from woven.environment import deployment_root, set_env, patch_project, server_state, set_server_state

from woven.project import deploy_static, deploy_public, deploy_project, deploy_db, deploy_templates

from woven.ubuntu import add_user, apt_get_install, apt_get_purge
from woven.ubuntu import install_packages, upgrade_ubuntu, setup_ufw, disable_root
from woven.ubuntu import uncomment_sources, restrict_ssh, upload_ssh_key
from woven.ubuntu import change_ssh_port, set_timezone, ubuntu_version, upload_etc

from woven.virtualenv import activate, active_version
from woven.virtualenv import mkvirtualenv, rmvirtualenv, pip_install_requirements

from woven.webservers import deploy_wsgi, deploy_webconf, start_webservers, stop_webservers, reload_webservers

def deploy():
    """
    deploy a versioned project on the host
    """
    deploy_funcs = [deploy_project,deploy_templates, deploy_static, deploy_public,  deploy_webconf, deploy_wsgi]
    if not patch_project():
        deploy_funcs = [deploy_db,mkvirtualenv,pip_install_requirements] + deploy_funcs
    for func in deploy_funcs: func()

def setupnode(overwrite=False):
    """
    Install a baseline host. Can be run multiple times

    """

    #either fabric or manage.py will setup the roles & hosts env
    #setup_environ handles passing all the project settings into env
    #and any woven.global_settings not already defined.
    disable_root()
    port_changed = change_ssh_port()

    upload_ssh_key()
    restrict_ssh()
    uncomment_sources()
    upgrade_ubuntu()
    setup_ufw()
    install_packages(overwrite=overwrite)
    upload_etc()
    set_timezone()
    stop_webservers()
    start_webservers()

<|endoftext|>


<commit_before># This file is part of Indico.
# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals

from wtforms.fields.core import BooleanField

from indico.core.plugins import IndicoPlugin
from indico.modules.vc import VCPluginMixin
from indico.modules.vc.plugins import VCRoomFormBase
from indico.util.i18n import _
from indico.web.forms.widgets import SwitchWidget

class VCRoomForm(VCRoomFormBase):
    show_phone_numbers = BooleanField(_('What is your favorite color?'),
                                      widget=SwitchWidget(),
                                      description=_("Yes. It doesn't make any sense."))

class DummyPlugin(VCPluginMixin, IndicoPlugin):
    """Dummy

    Dummy Video conferencing plugin
    """
    configurable = True
    vc_room_form = VCRoomForm

    @property
    def logo_url(self):
        return "http://fc05.deviantart.net/fs70/f/2011/257/7/7/_dummy__vector_by_phlum-d49u7mk.png"
<commit_msg>VC/Dummy: Fix import<commit_after># This file is part of Indico.
# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals

from wtforms.fields.core import BooleanField

from indico.core.plugins import IndicoPlugin
from indico.modules.vc import VCPluginMixin
from indico.modules.vc.forms import VCRoomFormBase
from indico.util.i18n import _
from indico.web.forms.widgets import SwitchWidget

class VCRoomForm(VCRoomFormBase):
    show_phone_numbers = BooleanField(_('What is your favorite color?'),
                                      widget=SwitchWidget(),
                                      description=_("Yes. It doesn't make any sense."))

class DummyPlugin(VCPluginMixin, IndicoPlugin):
    """Dummy

    Dummy Video conferencing plugin
    """
    configurable = True
    vc_room_form = VCRoomForm

    @property
    def logo_url(self):
        return "http://fc05.deviantart.net/fs70/f/2011/257/7/7/_dummy__vector_by_phlum-d49u7mk.png"
<|endoftext|>