<commit_before># Authors: Gilles Louppe, Mathieu Blondel, Maheshakya Wijewardena
# License: BSD 3 clause

import numpy as np
import numbers

from .base import SelectorMixin
from ..base import BaseEstimator, clone, MetaEstimatorMixin

from ..exceptions import NotFittedError
from ..utils.metaestimators import if_delegate_has_method

def _get_feature_importances(estimator, norm_order=1):
    """Retrieve or aggregate feature importances from estimator"""
    importances = getattr(estimator, "feature_importances_", None)

    coef_ = getattr(estimator, "coef_", None)
    if importances is None and coef_ is not None:
        if estimator.coef_.ndim == 1:
            importances = np.abs(coef_)

        else:
            importances = np.linalg.norm(coef_, axis=0,
                                         ord=norm_order)

    elif importances is None:
        raise ValueError(
            "The underlying estimator %s has no `coef_` or "
            "`feature_importances_` attribute. Either pass a fitted estimator"
            " to SelectFromModel or call fit before calling transform."
            % estimator.__class__.__name__)

    return importances

def _calculate_threshold(estimator, importances, threshold):
    """Interpret the threshold value"""

    if threshold is None:
        # determine default from estimator
        est_name = estimator.__class__.__name__
        if ((hasattr(estimator, "penalty") and estimator.penalty == "l1") or
                "Lasso" in est_name):
            # the natural default threshold is 0 when l1 penalty was used
            threshold = 1e-5
        else:
            threshold = "mean"

    if isinstance(threshold, str):
        if "*" in threshold:
            scale, reference = threshold.split("*")
            scale = float(scale.strip())
            reference = reference.strip()

            if reference == "median":
                reference = np.median(importances)
            elif reference == "mean":
                reference = np.mean(importances)
            else:
                raise ValueError("Unknown reference: " + reference)

            threshold = scale * reference

        elif threshold == "median":
            threshold = np.median(importances)

        elif threshold == "mean":
            threshold = np.mean(importances)

        else:
            raise ValueError("Expected threshold='mean' or threshold='median' "
                             "got %s" % threshold)

    else:
        threshold = float(threshold)

    return threshold

class SelectFromModel(MetaEstimatorMixin, SelectorMixin, BaseEstimator):
    """Meta-transformer for selecting features based on importance weights.

    .. versionadded:: 0.17

    Parameters
    ----------
    estimator : object
        The base estimator from which the transformer is built.
        This can be both a fitted (if ``prefit`` is set to True)
        or a non-fitted estimator. The estimator must have either a
        ``feature_importances_`` or ``coef_`` attribute after fitting.

    threshold : string, float, optional default None
        The threshold value to use for feature selection. Features whose
        importance is greater or equal are kept while the others are
        discarded. If "median" (resp. "mean"), then the ``threshold`` value is
        the median (resp. the mean) of the feature importances. A scaling
        factor (e.g., "1.25*mean") may also be used. If None and if the
        estimator has a parameter penalty set to l1, either explicitly
        or implicitly (e.g, Lasso), the threshold used is 1e-5.
        Otherwise, "mean" is used by default.

    prefit : bool, default False
        Whether a prefit model is expected to be passed into the constructor
        directly or not. If True, ``transform`` must be called directly
        and SelectFromModel cannot be used with ``cross_val_score``,
        ``GridSearchCV`` and similar utilities that clone the estimator.
        Otherwise train the model using ``fit`` and then ``transform`` to do
        feature selection.

    norm_order : non-zero int, inf, -inf, default 1
        Order of the norm used to filter the vectors of coefficients below
        ``threshold`` in the case where the ``coef_`` attribute of the
        estimator is of dimension 2.

    max_features : int or None, optional
        The maximum number of features selected scoring above ``threshold``.
        To disable ``threshold`` and only select based on ``max_features``,
        set ``threshold=-np.inf``.

        .. versionadded:: 0.20

    Attributes
    ----------
    estimator_ : an estimator
        The base estimator from which the transformer is built.
        This is stored only when a non-fitted estimator is passed to the
        ``SelectFromModel``, i.e when prefit is False.

    threshold_ : float
        The threshold value used for feature selection.
    """
    def __init__(self, estimator, threshold=None, prefit=False,
                 norm_order=1, max_features=None):
        self.estimator = estimator
        self.threshold = threshold
        self.prefit = prefit
        self.norm_order = norm_order
        self.max_features = max_features

    def _get_support_mask(self):
        # SelectFromModel can directly call on transform.
        if self.prefit:
            estimator = self.estimator
        elif hasattr(self, 'estimator_'):
            estimator = self.estimator_
        else:
            raise ValueError('Either fit the model before transform or set'
                             ' "prefit=True" while passing the fitted'
                             ' estimator to the constructor.')
        scores = _get_feature_importances(estimator, self.norm_order)
        threshold = _calculate_threshold(estimator, scores, self.threshold)
        if self.max_features is not None:
            mask = np.zeros_like(scores, dtype=bool)
            candidate_indices = \
                np.argsort(-scores, kind='mergesort')[:self.max_features]
            mask[candidate_indices] = True
        else:
            mask = np.ones_like(scores, dtype=bool)
        mask[scores < threshold] = False
        return mask

    def fit(self, X, y=None, **fit_params):
        """Fit the SelectFromModel meta-transformer.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            The training input samples.

        y : array-like, shape (n_samples,)
            The target values (integers that correspond to classes in
            classification, real numbers in regression).

        **fit_params : Other estimator specific parameters

        Returns
        -------
        self : object
        """
        if self.max_features is not None:
            if not isinstance(self.max_features, numbers.Integral):
                raise TypeError("'max_features' should be an integer between"
                                " 0 and {} features. Got {!r} instead."
                                .format(X.shape[1], self.max_features))
            elif self.max_features < 0 or self.max_features > X.shape[1]:
                raise ValueError("'max_features' should be 0 and {} features."
                                 "Got {} instead."
                                 .format(X.shape[1], self.max_features))

        if self.prefit:
            raise NotFittedError(
                "Since 'prefit=True', call transform directly")
        self.estimator_ = clone(self.estimator)
        self.estimator_.fit(X, y, **fit_params)
        return self

    @property
    def threshold_(self):
        scores = _get_feature_importances(self.estimator_, self.norm_order)
        return _calculate_threshold(self.estimator, scores, self.threshold)

    @if_delegate_has_method('estimator')
    def partial_fit(self, X, y=None, **fit_params):
        """Fit the SelectFromModel meta-transformer only once.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            The training input samples.

        y : array-like, shape (n_samples,)
            The target values (integers that correspond to classes in
            classification, real numbers in regression).

        **fit_params : Other estimator specific parameters

        Returns
        -------
        self : object
        """
        if self.prefit:
            raise NotFittedError(
                "Since 'prefit=True', call transform directly")
        if not hasattr(self, "estimator_"):
            self.estimator_ = clone(self.estimator)
        self.estimator_.partial_fit(X, y, **fit_params)
        return self
<commit_msg>DOC Add SelectFromModel example (#15194)<commit_after># Authors: Gilles Louppe, Mathieu Blondel, Maheshakya Wijewardena
# License: BSD 3 clause

import numpy as np
import numbers

from .base import SelectorMixin
from ..base import BaseEstimator, clone, MetaEstimatorMixin

from ..exceptions import NotFittedError
from ..utils.metaestimators import if_delegate_has_method

def _get_feature_importances(estimator, norm_order=1):
    """Retrieve or aggregate feature importances from estimator"""
    importances = getattr(estimator, "feature_importances_", None)

    coef_ = getattr(estimator, "coef_", None)
    if importances is None and coef_ is not None:
        if estimator.coef_.ndim == 1:
            importances = np.abs(coef_)

        else:
            importances = np.linalg.norm(coef_, axis=0,
                                         ord=norm_order)

    elif importances is None:
        raise ValueError(
            "The underlying estimator %s has no `coef_` or "
            "`feature_importances_` attribute. Either pass a fitted estimator"
            " to SelectFromModel or call fit before calling transform."
            % estimator.__class__.__name__)

    return importances

def _calculate_threshold(estimator, importances, threshold):
    """Interpret the threshold value"""

    if threshold is None:
        # determine default from estimator
        est_name = estimator.__class__.__name__
        if ((hasattr(estimator, "penalty") and estimator.penalty == "l1") or
                "Lasso" in est_name):
            # the natural default threshold is 0 when l1 penalty was used
            threshold = 1e-5
        else:
            threshold = "mean"

    if isinstance(threshold, str):
        if "*" in threshold:
            scale, reference = threshold.split("*")
            scale = float(scale.strip())
            reference = reference.strip()

            if reference == "median":
                reference = np.median(importances)
            elif reference == "mean":
                reference = np.mean(importances)
            else:
                raise ValueError("Unknown reference: " + reference)

            threshold = scale * reference

        elif threshold == "median":
            threshold = np.median(importances)

        elif threshold == "mean":
            threshold = np.mean(importances)

        else:
            raise ValueError("Expected threshold='mean' or threshold='median' "
                             "got %s" % threshold)

    else:
        threshold = float(threshold)

    return threshold

class SelectFromModel(MetaEstimatorMixin, SelectorMixin, BaseEstimator):
    """Meta-transformer for selecting features based on importance weights.

    .. versionadded:: 0.17

    Parameters
    ----------
    estimator : object
        The base estimator from which the transformer is built.
        This can be both a fitted (if ``prefit`` is set to True)
        or a non-fitted estimator. The estimator must have either a
        ``feature_importances_`` or ``coef_`` attribute after fitting.

    threshold : string, float, optional default None
        The threshold value to use for feature selection. Features whose
        importance is greater or equal are kept while the others are
        discarded. If "median" (resp. "mean"), then the ``threshold`` value is
        the median (resp. the mean) of the feature importances. A scaling
        factor (e.g., "1.25*mean") may also be used. If None and if the
        estimator has a parameter penalty set to l1, either explicitly
        or implicitly (e.g, Lasso), the threshold used is 1e-5.
        Otherwise, "mean" is used by default.

    prefit : bool, default False
        Whether a prefit model is expected to be passed into the constructor
        directly or not. If True, ``transform`` must be called directly
        and SelectFromModel cannot be used with ``cross_val_score``,
        ``GridSearchCV`` and similar utilities that clone the estimator.
        Otherwise train the model using ``fit`` and then ``transform`` to do
        feature selection.

    norm_order : non-zero int, inf, -inf, default 1
        Order of the norm used to filter the vectors of coefficients below
        ``threshold`` in the case where the ``coef_`` attribute of the
        estimator is of dimension 2.

    max_features : int or None, optional
        The maximum number of features selected scoring above ``threshold``.
        To disable ``threshold`` and only select based on ``max_features``,
        set ``threshold=-np.inf``.

        .. versionadded:: 0.20

    Attributes
    ----------
    estimator_ : an estimator
        The base estimator from which the transformer is built.
        This is stored only when a non-fitted estimator is passed to the
        ``SelectFromModel``, i.e when prefit is False.

    threshold_ : float
        The threshold value used for feature selection.

    Examples
    --------
    >>> from sklearn.feature_selection import SelectFromModel
    >>> from sklearn.linear_model import LogisticRegression
    >>> X = [[ 0.87, -1.34,  0.31 ],
    ...      [-2.79, -0.02, -0.85 ],
    ...      [-1.34, -0.48, -2.55 ],
    ...      [ 1.92,  1.48,  0.65 ]]
    >>> y = [0, 1, 0, 1]
    >>> selector = SelectFromModel(estimator=LogisticRegression()).fit(X, y)
    >>> selector.estimator_.coef_
    array([[-0.3252302 ,  0.83462377,  0.49750423]])
    >>> selector.threshold_
    0.55245...
    >>> selector.get_support()
    array([False,  True, False])
    >>> selector.transform(X)
    array([[-1.34],
           [-0.02],
           [-0.48],
           [ 1.48]])
    """
    def __init__(self, estimator, threshold=None, prefit=False,
                 norm_order=1, max_features=None):
        self.estimator = estimator
        self.threshold = threshold
        self.prefit = prefit
        self.norm_order = norm_order
        self.max_features = max_features

    def _get_support_mask(self):
        # SelectFromModel can directly call on transform.
        if self.prefit:
            estimator = self.estimator
        elif hasattr(self, 'estimator_'):
            estimator = self.estimator_
        else:
            raise ValueError('Either fit the model before transform or set'
                             ' "prefit=True" while passing the fitted'
                             ' estimator to the constructor.')
        scores = _get_feature_importances(estimator, self.norm_order)
        threshold = _calculate_threshold(estimator, scores, self.threshold)
        if self.max_features is not None:
            mask = np.zeros_like(scores, dtype=bool)
            candidate_indices = \
                np.argsort(-scores, kind='mergesort')[:self.max_features]
            mask[candidate_indices] = True
        else:
            mask = np.ones_like(scores, dtype=bool)
        mask[scores < threshold] = False
        return mask

    def fit(self, X, y=None, **fit_params):
        """Fit the SelectFromModel meta-transformer.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            The training input samples.

        y : array-like, shape (n_samples,)
            The target values (integers that correspond to classes in
            classification, real numbers in regression).

        **fit_params : Other estimator specific parameters

        Returns
        -------
        self : object
        """
        if self.max_features is not None:
            if not isinstance(self.max_features, numbers.Integral):
                raise TypeError("'max_features' should be an integer between"
                                " 0 and {} features. Got {!r} instead."
                                .format(X.shape[1], self.max_features))
            elif self.max_features < 0 or self.max_features > X.shape[1]:
                raise ValueError("'max_features' should be 0 and {} features."
                                 "Got {} instead."
                                 .format(X.shape[1], self.max_features))

        if self.prefit:
            raise NotFittedError(
                "Since 'prefit=True', call transform directly")
        self.estimator_ = clone(self.estimator)
        self.estimator_.fit(X, y, **fit_params)
        return self

    @property
    def threshold_(self):
        scores = _get_feature_importances(self.estimator_, self.norm_order)
        return _calculate_threshold(self.estimator, scores, self.threshold)

    @if_delegate_has_method('estimator')
    def partial_fit(self, X, y=None, **fit_params):
        """Fit the SelectFromModel meta-transformer only once.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            The training input samples.

        y : array-like, shape (n_samples,)
            The target values (integers that correspond to classes in
            classification, real numbers in regression).

        **fit_params : Other estimator specific parameters

        Returns
        -------
        self : object
        """
        if self.prefit:
            raise NotFittedError(
                "Since 'prefit=True', call transform directly")
        if not hasattr(self, "estimator_"):
            self.estimator_ = clone(self.estimator)
        self.estimator_.partial_fit(X, y, **fit_params)
        return self
<|endoftext|>


<commit_before>import sys
import ast
import socket

class Client(object):
    def __init__(self, player, addr=None, port=None):
        self.player = player
        self.running = False
        self.receiver = {'player': self.handle_player,
                         'decline': self.handle_decline,
                         'error': self.handle_error,
                         'illegal': self.handle_illegal,
                         'update': self.handle_update,
                         'action': self.handle_action,
                         'winners': self.handle_winners,}

        self.addr = addr if addr is not None else '127.0.0.1'
        self.port = port if port is not None else 4242

    def run(self):
        self.socket = socket.create_connection((self.addr, self.port))
        self.running = True
        while self.running:
            message = self.socket.recv(4096)
            messages = message.rstrip().split('\r\n')
            for message in messages:
                for action in self.receiver:
                    if message.startswith(action):
                        msg_contents = message[len(action)+1:]
                        if msg_contents:
                            msg_contents = ast.literal_eval(msg_contents)
                        self.receiver[action](msg_contents)
                        break
                else:
                    raise ValueError(
                        "Unexpected message from server: {0!r}".format(message))

    def parse_item(self, item):
        result = ast.literal_eval(item)
        return result

    def handle_player(self, msg):
        print "You are player #{0}.".format(msg)
        self.player.player = msg

    def handle_decline(self, msg):
        print msg
        self.running = False

    def handle_error(self, msg):
        print msg # FIXME: do something useful

    def handle_illegal(self, msg):
        print msg # FIXME: do something useful

    def handle_update(self, msg):
        action, state = msg
        self.player.update(state)
        print self.player.display(state, action)

    def handle_action(self, msg):
        action = self.player.get_action()
        self.socket.sendall("play {0!r}\r\n".format(action))

    def handle_winners(self, msg):
        print self.player.winner_message(msg)
        self.running = False

class HumanPlayer(object):
    def __init__(self, board):
        self.board = board
        self.player = None
        self.states = []

    def update(self, state):
        self.states.append(state)

    def display(self, state, action):
        return self.board.display(state, action)

    def winner_message(self, msg):
        return self.board.winner_message(msg)

    def get_action(self):
        while True:
            notation = raw_input("Please enter your action: ")
            action = self.board.pack_action(notation)
            if action is None:
                continue
            if self.board.is_legal(self.states, action):
                break
        return action
<commit_msg>Send and accept unpacked json representations over the wire<commit_after>import json
import socket
import sys

class Client(object):
    def __init__(self, player, addr=None, port=None):
        self.player = player
        self.running = False
        self.receiver = {'player': self.handle_player,
                         'decline': self.handle_decline,
                         'error': self.handle_error,
                         'illegal': self.handle_illegal,
                         'update': self.handle_update}

        self.addr = addr if addr is not None else '127.0.0.1'
        self.port = port if port is not None else 4242

    def run(self):
        self.socket = socket.create_connection((self.addr, self.port))
        self.running = True
        while self.running:
            message = self.socket.recv(4096)
            messages = message.rstrip().split('\r\n')
            for message in messages:
                data = json.loads(message)
                if data['type'] not in self.receiver:
                    raise ValueError(
                        "Unexpected message from server: {0!r}".format(message))

                self.receiver[data['type']](data)

    def handle_player(self, data):
        player = data['message']
        print "You are player #{0}.".format(player)
        self.player.player = player

    def handle_decline(self, data):
        print data['message']
        self.running = False

    def handle_error(self, data):
        print data['message'] # FIXME: do something useful

    def handle_illegal(self, data):
        print data['message'] # FIXME: do something useful

    def handle_update(self, data):
        state = data['state']
        action = data.get('last_action', {}).get('notation') or ''
        self.player.update(state)

        print self.player.display(state, action)
        if data.get('winners') is not None:
            print self.player.winner_message(data['winners'])
            self.running = False
        elif data['state']['player'] == self.player.player:
            action = self.player.get_action()
            self.send({'type': 'action', 'message': action})

    def send(self, data):
        self.socket.sendall("{0}\r\n".format(json.dumps(data)))

class HumanPlayer(object):
    def __init__(self, board):
        self.board = board
        self.player = None
        self.history = []

    def update(self, state):
        self.history.append(self.board.pack_state(state))

    def display(self, state, action):
        state = self.board.pack_state(state)
        action = self.board.pack_action(action)
        return self.board.display(state, action)

    def winner_message(self, winners):
        return self.board.winner_message(winners)

    def get_action(self):
        while True:
            notation = raw_input("Please enter your action: ")
            action = self.board.pack_action(notation)
            if action is None:
                continue
            if self.board.is_legal(self.history, action):
                break
        return notation
<|endoftext|>


<commit_before>import logging
import operator

try:
    NullHandler = logging.NullHandler
except AttributeError:
    class NullHandler(logging.Handler):
        def emit(self, record):
            pass

log = logging.getLogger("statzlogger")
log.addHandler(NullHandler())

class StatzHandler(logging.Handler):

    def __init__(self, level=logging.NOTSET):
        logging.Handler.__init__(self, level=level)
        self.indices = {}

    def getindices(self, record):
        """Return a list of indices for a given record.

        The list of indices will either contain the record's *index* attribute
        or a list generated from its iterable *indices* attribute. If both
        attributes are present, *index* will be added to *indices*. If no
        indices are defined, the resulting list will be [None].
        """
        index = getattr(record, "index", None)
        indices = list(getattr(record, "indices", []))
        if index is not None:
            indices.append(index)
        if not indices:
            indices = [None]

        return indices

    def getvalue(self, record):
        return record.msg

    def emit(self, record):
        for index in self.getindices(record):
            value = self.getvalue(record)
            self.emitvalue(value, index)

    def emitvalue(self, value, index):
        self.indices[index] = value

class Sum(StatzHandler):

    def __init__(self, level=logging.NOTSET, default=0):
        StatzHandler.__init__(self, level=level)
        self.default = default

    def emitvalue(self, value, index):
        value = self.indices.setdefault(index, self.default) + value
        StatzHandler.emitvalue(self, value, index)

class Collection(Sum):

    def __init__(self, level=logging.NOTSET, default=[]):
        Sum.__init__(self, level=level, default=default)

    def getvalue(self, record):
        return [Sum.getvalue(self, record)]

class Maximum(Collection):

    def __init__(self, level=logging.NOTSET, size=None, weight=1, reverse=True):
        Collection.__init__(self, level=level, default=[])
        self.size = size
        self.weight = weight
        self.reverse = reverse

    def getvalue(self, record):
        (value,) = Collection.getvalue(self, record)
        weight = getattr(record, "weight", self.weight)
        if callable(weight):
            weight = weight(value)
        return [(value, weight)]

    def emitvalue(self, value, index):
        Collection.emitvalue(self, value, index)
        self.indices[index] = sorted(self.indices[index],
                key=operator.itemgetter(1),
                reverse=self.reverse)[:self.size]

class Minimum(Maximum):

    def __init__(self, level=logging.NOTSET, size=None, weight=1, reverse=False):
        Maximum.__init__(self, level=level, size=size, weight=weight, reverse=reverse)

class Top(StatzHandler):
    pass
<commit_msg>Make it easier to change operator in Sum.<commit_after>import logging
import operator

try:
    NullHandler = logging.NullHandler
except AttributeError:
    class NullHandler(logging.Handler):
        def emit(self, record):
            pass

log = logging.getLogger("statzlogger")
log.addHandler(NullHandler())

class StatzHandler(logging.Handler):

    def __init__(self, level=logging.NOTSET):
        logging.Handler.__init__(self, level=level)
        self.indices = {}

    def getindices(self, record):
        """Return a list of indices for a given record.

        The list of indices will either contain the record's *index* attribute
        or a list generated from its iterable *indices* attribute. If both
        attributes are present, *index* will be added to *indices*. If no
        indices are defined, the resulting list will be [None].
        """
        index = getattr(record, "index", None)
        indices = list(getattr(record, "indices", []))
        if index is not None:
            indices.append(index)
        if not indices:
            indices = [None]

        return indices

    def getvalue(self, record):
        return record.msg

    def emit(self, record):
        for index in self.getindices(record):
            value = self.getvalue(record)
            self.emitvalue(value, index)

    def emitvalue(self, value, index):
        self.indices[index] = value

class Sum(StatzHandler):

    def __init__(self, level=logging.NOTSET, default=0, op=operator.add):
        StatzHandler.__init__(self, level=level)
        self.default = default
        self.op = op

    def emitvalue(self, value, index):
        value = self.op(self.indices.setdefault(index, self.default), value)
        StatzHandler.emitvalue(self, value, index)

class Collection(Sum):

    def __init__(self, level=logging.NOTSET, default=[]):
        Sum.__init__(self, level=level, default=default)

    def getvalue(self, record):
        return [Sum.getvalue(self, record)]

class Maximum(Collection):

    def __init__(self, level=logging.NOTSET, size=None, weight=1, reverse=True):
        Collection.__init__(self, level=level, default=[])
        self.size = size
        self.weight = weight
        self.reverse = reverse

    def getvalue(self, record):
        (value,) = Collection.getvalue(self, record)
        weight = getattr(record, "weight", self.weight)
        if callable(weight):
            weight = weight(value)
        return [(value, weight)]

    def emitvalue(self, value, index):
        Collection.emitvalue(self, value, index)
        self.indices[index] = sorted(self.indices[index],
                key=operator.itemgetter(1),
                reverse=self.reverse)[:self.size]

class Minimum(Maximum):

    def __init__(self, level=logging.NOTSET, size=None, weight=1, reverse=False):
        Maximum.__init__(self, level=level, size=size, weight=weight, reverse=reverse)

class Top(StatzHandler):
    pass
<|endoftext|>


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

# Copyright 2013 Jacek Mitręga

# 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.

from __future__ import unicode_literals

from collections import OrderedDict
import json
import logging
import pprint
import sys

import skype
import kde

logger = logging.getLogger(__name__)

class StdupDesktop(object):

    def __init__(self, conn, room, name, video):
        self.conn = conn
        self.room = room
        self.name = name
        self.participants = OrderedDict()
        self.skype = skype.SkypeCaller(self, video)
        self.kde = kde.KdeWindowManager()
        self._opened()
        logger.info('Connection established.')

    def _opened(self):
        self._send_msg('join', room=self.room, name=self.name)

    def received_message(self, msg):
        try:
            data = json.loads(msg.data)
        except Exception as e:
            logger.error('Message JSON parse error: {}'.format(msg))
            return

        try:
            handler_fn = 'on_' + data['msg']
        except KeyError as e:
            logger.error('Message structure error: {}'.format(msg))
            return

        try:
            handler = getattr(self, handler_fn, None)
            if handler:
                handler(msg, data)
            else:
                self.default_handler(msg, data)
        except Exception as e:
            logger.exception('Message handler error: {}'.format(msg))

    def closed(self, code, reason=None):
        pass

    def _send_msg(self, msg, **data):
        data['msg'] = msg
        self.conn.send(json.dumps(data))

    # ===== Message Handlers ===== #

    def default_handler(self, msg, data):
        logger.error('unhandled message: {}'.format(msg))

    def on_join(self, msg, data):
        logger.info('join: {}'.format(msg))
        self._send_msg('welcome', name=self.name)
        self._add_participant(msg, data)

    def on_welcome(self, msg, data):
        logger.info('welcome: {}'.format(data.get('name')))
        self._add_participant(msg, data)

    def on_keepalive(self, msg, data):
        logger.info('keepalive')
        self._send_msg('alive', name=self.name)

    def on_alive(self, msg, data):
        logger.info('alive: {}'.format(data.get('name')))
        self._add_participant(msg, data)

    def on_set(self, msg, data):
        logger.info('set: {}'.format(data))

    def on_call(self, msg, data):
        logger.info('call')
        contacts = filter(None,
                          [p.get('contact', None)
                           for p in self.participants.values()])
        self.kde.show()
        self.skype.place_call(contacts)

    def on_hangup(self, msg, data):
        logger.info('call')
        self.kde.hide()
        self.skype.finish_call()

    # ===== Participants ===== #

    def _add_participant(self, msg, data):
        name = data['name']
        participant = {
            'name': name,
            'contact': data.get('contact', None),
        }
        self.participants[name] = participant
        parts = pprint.pformat(self.participants)
        logger.info('* current participants: \n{}'.format(parts))
<commit_msg>Handle START & STOP - just log<commit_after># -*- coding: utf-8 -*-

# Copyright 2013 Jacek Mitręga

# 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.

from __future__ import unicode_literals

from collections import OrderedDict
import json
import logging
import pprint
import sys

import skype
import kde

logger = logging.getLogger(__name__)

class StdupDesktop(object):

    def __init__(self, conn, room, name, video):
        self.conn = conn
        self.room = room
        self.name = name
        self.participants = OrderedDict()
        self.skype = skype.SkypeCaller(self, video)
        self.kde = kde.KdeWindowManager()
        self._opened()
        logger.info('Connection established.')

    def _opened(self):
        self._send_msg('join', room=self.room, name=self.name)

    def received_message(self, msg):
        try:
            data = json.loads(msg.data)
        except Exception as e:
            logger.error('Message JSON parse error: {}'.format(msg))
            return

        try:
            handler_fn = 'on_' + data['msg']
        except KeyError as e:
            logger.error('Message structure error: {}'.format(msg))
            return

        try:
            handler = getattr(self, handler_fn, None)
            if handler:
                handler(msg, data)
            else:
                self.default_handler(msg, data)
        except Exception as e:
            logger.exception('Message handler error: {}'.format(msg))

    def closed(self, code, reason=None):
        pass

    def _send_msg(self, msg, **data):
        data['msg'] = msg
        self.conn.send(json.dumps(data))

    # ===== Message Handlers ===== #

    def default_handler(self, msg, data):
        logger.error('unhandled message: {}'.format(msg))

    def on_join(self, msg, data):
        logger.info('join: {}'.format(msg))
        self._send_msg('welcome', name=self.name)
        self._add_participant(msg, data)

    def on_welcome(self, msg, data):
        logger.info('welcome: {}'.format(data.get('name')))
        self._add_participant(msg, data)

    def on_keepalive(self, msg, data):
        logger.info('keepalive')
        self._send_msg('alive', name=self.name)

    def on_alive(self, msg, data):
        logger.info('alive: {}'.format(data.get('name')))
        self._add_participant(msg, data)

    def on_set(self, msg, data):
        logger.info('set: {}'.format(data))

    def on_start(self, msg, data):
        logger.info('start')

    def on_stop(self, msg, data):
        logger.info('stop')

    def on_call(self, msg, data):
        logger.info('call')
        contacts = filter(None,
                          [p.get('contact', None)
                           for p in self.participants.values()])
        self.kde.show()
        self.skype.place_call(contacts)

    def on_hangup(self, msg, data):
        logger.info('call')
        self.kde.hide()
        self.skype.finish_call()

    # ===== Participants ===== #

    def _add_participant(self, msg, data):
        name = data['name']
        participant = {
            'name': name,
            'contact': data.get('contact', None),
        }
        self.participants[name] = participant
        parts = pprint.pformat(self.participants)
        logger.info('* current participants: \n{}'.format(parts))
<|endoftext|>


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

import sys
import decimal

decimal.getcontext().prec = 8

def header():
    svgHeadRow1 = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"
    svgHeadRow2 = "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20001102//EN\""
    svgHeadRow3 = "\"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd\">"
    svgHeadRow4 = "<svg width=\"84cm\" height=\"350cm\">"
    svgHead = (svgHeadRow1, svgHeadRow2, svgHeadRow3, svgHeadRow4)
    return svgHead

def footer():
    svgFootRow1 = "</svg>"
    svgFootRow2 = "\n"
    svgFoot = (svgFootRow1, svgFootRow2)
    return svgFoot

def openFile():
    '''
    sun-data file format:
        timestamp, ir, full, lux_msb, lux_lsb
    '''
    with open(sys.argv[1],"r") as f:
        contents = f.read()
        f.close()
    lines = contents.splitlines()
    return (lines,sys.argv[1],len(lines))

def setXcoord(step,prev):
    # change x value with step when we store previous value in prev
    value = "x=\"" + str(decimal.Decimal(step) + decimal.Decimal(prev)) + "cm\""
    return value

def setYcoord(step,prev):
    # change x value with step when we store previous value in prev
    #decimal.getcontext().prec = 3
    value = "y=\"" + str(decimal.Decimal(step) + decimal.Decimal(prev)) + "cm\""
    return value

def createGroup(subset,coordX,coordY,stepY,ff):
    # create group start from startRow and ends at endRow with stepY and X coordinate at coordX
    prev = coordY
    rows = []

    startRow = int(subset[0])
    endRow = int(subset[1])

    svgGroupStart = "<g fill=\"#808080\" font-size=\"12pt\" style=\"font-family:Arial\">"
    svgGroupEnd = "</g>"

    rows.append(svgGroupStart)

    for i in range(startRow,endRow):
       svgRow = "<text " + setXcoord(coordX,0) + " " + setYcoord(stepY,prev) + ">" + ff[i] + "</text>"
       prev = prev + stepY
       rows.append(svgRow)

    rows.append(svgGroupEnd)
    return rows

def writeToFile(ff,data1,data2,data3,data4,data5,data6,data7,data8,data9,data10,data11,data12,data13,data14):
    # write to SVG file
    newFile = ff[1] + ".svg"
    ffw = open(newFile, 'w')

    head = header()
    for i in range(0,len(head)):
        ffw.write(head[i] + "\n")

    for i in range(0,len(data1)):
        ffw.write(data1[i] + "\n")

    for i in range(0,len(data2)):
        ffw.write(data2[i] + "\n")

    for i in range(0,len(data3)):
        ffw.write(data3[i] + "\n")

    for i in range(0,len(data4)):
        ffw.write(data4[i] + "\n")

    for i in range(0,len(data5)):
        ffw.write(data5[i] + "\n")

    for i in range(0,len(data6)):
        ffw.write(data6[i] + "\n")

    for i in range(0,len(data7)):
        ffw.write(data7[i] + "\n")

    for i in range(0,len(data8)):
        ffw.write(data8[i] + "\n")

    for i in range(0,len(data9)):
        ffw.write(data9[i] + "\n")

    for i in range(0,len(data10)):
        ffw.write(data10[i] + "\n")

    for i in range(0,len(data11)):
        ffw.write(data11[i] + "\n")

    for i in range(0,len(data12)):
        ffw.write(data12[i] + "\n")

    for i in range(0,len(data13)):
        ffw.write(data13[i] + "\n")

    for i in range(0,len(data14)):
        ffw.write(data14[i] + "\n")

    foot = footer()
    for i in range(0,len(foot)):
        ffw.write(foot[i] + "\n")

    ffw.close()

def startStopGenerator(noOfRows,noOfCols):
    # generate tuple((start1,stop1),(start2,stop2),(start3,stop3,...(startN,stopN))
    ll = ['none'] * noOfCols
    for i in range(0,noOfCols):
        if i == 0:
            ll[i] = (0,noOfRows)
        else:
            ll[i] = (((noOfRows*i)+1),((noOfRows*(i+1))+1))
    print(ll)
    return(ll)

def main():
    ff = openFile()

    # @Pepa set desired number of columns here
    setNumOfColumns = 14

    #print(ff[2])
    #print(ff[2]/14)
    #print(round(ff[2]/14))
    noOfRows = round(ff[2]/setNumOfColumns)
    subset = startStopGenerator(noOfRows,setNumOfColumns)
    #print(subset[0])
    #print(subset[0][1])

    # @Pepa change here 'coordX' of the columns, initial Y coord - 'coordY' and the step between the rows 'stepY' below
    # createGroup(subset,     coordX(cm),coordY(cm),stepY(cm),ff):
    col1 = createGroup(subset[0],      1,   10.0,   0.5,   ff[0])
    col2 = createGroup(subset[1],      6,   10.0,   0.5,   ff[0])
    col3 = createGroup(subset[2],     12,   10.0,   0.5,   ff[0])
    col4 = createGroup(subset[3],     18,   10.0,   0.5,   ff[0])
    col5 = createGroup(subset[4],     24,   10.0,   0.5,   ff[0])
    col6 = createGroup(subset[5],     30,   10.0,   0.5,   ff[0])
    col7 = createGroup(subset[6],     36,   10.0,   0.5,   ff[0])
    col8 = createGroup(subset[7],     42,   10.0,   0.5,   ff[0])
    col9 = createGroup(subset[8],     48,   10.0,   0.5,   ff[0])
    col10 = createGroup(subset[9],    54,   10.0,   0.5,   ff[0])
    col11 = createGroup(subset[10],   60,   10.0,   0.5,   ff[0])
    col12 = createGroup(subset[11],   66,   10.0,   0.5,   ff[0])
    col13 = createGroup(subset[12],   72,   10.0,   0.5,   ff[0])
    col14 = createGroup(subset[13],   78,   10.0,   0.5,   ff[0])

    #for i in range(0,len(rows)):
    #    print(rows[i])

    print("Writing to file: " + ff[1] + ".svg")
    writeToFile(ff,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12,col13,col14)
    print("Done")

if __name__ == "__main__":
    main()
<commit_msg>working fill option with print<commit_after>#!/usr/bin/env python

import sys
import decimal

# lux color table
# from https://en.wikipedia.org/wiki/Lux
# range 0 - 20 lux
lux_0_20 = "fill=\"black\""
# range 20 - 50 lux
lux_20_50 = "fill=\"gray\""
# range 50 - 80 lux
lux_50_80 = "fill=\"pink\""
# range 80 - 100 lux
lux_80_100 = "fill=\"green\""
# range 100 - 320 lux
lux_100_320 = "fill=\"brown\""
# range 320 - 500 lux
lux_320_500 = "fill=\"yellow\""
# range 500 - 1000 lux
lux_500_1000 = "fill=\"blue\""
# range 1000 - 10000 lux
lux_1k_10k = "fill=\"magenta\""
# range > 10k
lux_10k = "fill=\"white\""

# set decimal precision
decimal.getcontext().prec = 8

def header():
    svgHeadRow1 = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"
    svgHeadRow2 = "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20001102//EN\""
    svgHeadRow3 = "\"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd\">"
    svgHeadRow4 = "<svg width=\"84cm\" height=\"350cm\">"
    svgHead = (svgHeadRow1, svgHeadRow2, svgHeadRow3, svgHeadRow4)
    return svgHead

def footer():
    svgFootRow1 = "</svg>"
    svgFootRow2 = "\n"
    svgFoot = (svgFootRow1, svgFootRow2)
    return svgFoot

def openFile():
    '''
    sun-data file format:
        timestamp, ir, full, lux_msb, lux_lsb
    '''
    with open(sys.argv[1],"r") as f:
        contents = f.read()
        f.close()
    lines = contents.splitlines()
    return (lines,sys.argv[1],len(lines))

def setXcoord(step,prev):
    # change x value with step when we store previous value in prev
    value = "x=\"" + str(decimal.Decimal(step) + decimal.Decimal(prev)) + "cm\""
    return value

def setYcoord(step,prev):
    # change x value with step when we store previous value in prev
    #decimal.getcontext().prec = 3
    value = "y=\"" + str(decimal.Decimal(step) + decimal.Decimal(prev)) + "cm\""
    return value

def createGroup(subset,coordX,coordY,stepY,ff):
    # create group start from startRow and ends at endRow with stepY and X coordinate at coordX
    prev = coordY
    rows = []

    startRow = int(subset[0])
    endRow = int(subset[1])

    svgGroupStart = "<g fill=\"#808080\" font-size=\"12pt\" style=\"font-family:Arial\">"
    svgGroupEnd = "</g>"

    rows.append(svgGroupStart)

    for i in range(startRow,endRow):
       svgRow = "<text " + setXcoord(coordX,0) + " " + setYcoord(stepY,prev) + ">" + ff[i] + "</text>"
       setColor(ff[i])
       prev = prev + stepY
       rows.append(svgRow)

    rows.append(svgGroupEnd)
    return rows

def writeToFile(ff,data1,data2,data3,data4,data5,data6,data7,data8,data9,data10,data11,data12,data13,data14):
    # write to SVG file
    newFile = ff[1] + ".svg"
    ffw = open(newFile, 'w')

    head = header()
    for i in range(0,len(head)):
        ffw.write(head[i] + "\n")

    for i in range(0,len(data1)):
        ffw.write(data1[i] + "\n")

    for i in range(0,len(data2)):
        ffw.write(data2[i] + "\n")

    for i in range(0,len(data3)):
        ffw.write(data3[i] + "\n")

    for i in range(0,len(data4)):
        ffw.write(data4[i] + "\n")

    for i in range(0,len(data5)):
        ffw.write(data5[i] + "\n")

    for i in range(0,len(data6)):
        ffw.write(data6[i] + "\n")

    for i in range(0,len(data7)):
        ffw.write(data7[i] + "\n")

    for i in range(0,len(data8)):
        ffw.write(data8[i] + "\n")

    for i in range(0,len(data9)):
        ffw.write(data9[i] + "\n")

    for i in range(0,len(data10)):
        ffw.write(data10[i] + "\n")

    for i in range(0,len(data11)):
        ffw.write(data11[i] + "\n")

    for i in range(0,len(data12)):
        ffw.write(data12[i] + "\n")

    for i in range(0,len(data13)):
        ffw.write(data13[i] + "\n")

    for i in range(0,len(data14)):
        ffw.write(data14[i] + "\n")

    foot = footer()
    for i in range(0,len(foot)):
        ffw.write(foot[i] + "\n")

    ffw.close()

def startStopGenerator(noOfRows,noOfCols):
    # generate tuple((start1,stop1),(start2,stop2),(start3,stop3,...(startN,stopN))
    ll = ['none'] * noOfCols
    for i in range(0,noOfCols):
        if i == 0:
            ll[i] = (0,noOfRows)
        else:
            ll[i] = (((noOfRows*i)+1),((noOfRows*(i+1))+1))
    print(ll)
    return(ll)

def setColor(ff):
    # get ff[i] and return string with proper fill color
    cc = ff.split()
    cc_to_int = int(cc[2])

    if 0 <= cc_to_int <= 19:
        print(lux_0_20)

    if 20 <= cc_to_int <= 49:
        print(lux_20_50)

    if 50 <= cc_to_int <= 79:
        print(lux_50_80)

    if 80 <= cc_to_int <= 99:
        print(lux_80_100)

    if 100 <= cc_to_int <= 319:
        print(lux_100_320)

    if 320 <= cc_to_int <= 499:
        print(lux_320_500)

    if 500 <= cc_to_int <= 999:
        print(lux_500_1000)

    if 1000 <= cc_to_int <= 9999:
        print(lux_1k_10k)

    if cc_to_int > 9999:
        print(lux_10k)

    return 0

def main():
    ff = openFile()

    # @Pepa set desired number of columns here
    setNumOfColumns = 14

    #print(ff[2])
    #print(ff[2]/14)
    #print(round(ff[2]/14))
    noOfRows = round(ff[2]/setNumOfColumns)
    subset = startStopGenerator(noOfRows,setNumOfColumns)
    #print(subset[0])
    #print(subset[0][1])

    # @Pepa change here 'coordX' of the columns, initial Y coord - 'coordY' and the step between the rows 'stepY' below
    # createGroup(subset,     coordX(cm),coordY(cm),stepY(cm),ff):
    col1 = createGroup(subset[0],      1,   10.0,   0.5,   ff[0])
    col2 = createGroup(subset[1],      6,   10.0,   0.5,   ff[0])
    col3 = createGroup(subset[2],     12,   10.0,   0.5,   ff[0])
    col4 = createGroup(subset[3],     18,   10.0,   0.5,   ff[0])
    col5 = createGroup(subset[4],     24,   10.0,   0.5,   ff[0])
    col6 = createGroup(subset[5],     30,   10.0,   0.5,   ff[0])
    col7 = createGroup(subset[6],     36,   10.0,   0.5,   ff[0])
    col8 = createGroup(subset[7],     42,   10.0,   0.5,   ff[0])
    col9 = createGroup(subset[8],     48,   10.0,   0.5,   ff[0])
    col10 = createGroup(subset[9],    54,   10.0,   0.5,   ff[0])
    col11 = createGroup(subset[10],   60,   10.0,   0.5,   ff[0])
    col12 = createGroup(subset[11],   66,   10.0,   0.5,   ff[0])
    col13 = createGroup(subset[12],   72,   10.0,   0.5,   ff[0])
    col14 = createGroup(subset[13],   78,   10.0,   0.5,   ff[0])

    #for i in range(0,len(rows)):
    #    print(rows[i])

    print("Writing to file: " + ff[1] + ".svg")
    writeToFile(ff,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12,col13,col14)
    print("Done")

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


<commit_before>from Validation.onlineValidation import project_exists, sample_exists
from wx.lib.pubsub import pub
import logging
from Exceptions.ProjectError import ProjectError
from API.pubsub import send_message
from os import path
import json

class RunUploaderTopics(object):
    start_online_validation = "start_online_validation"
    online_validation_failure = "online_validation_failure"
    start_checking_samples = "start_checking_samples"
    start_uploading_samples = "start_uploading_samples"
    finished_uploading_samples = "finished_uploading_samples"

def upload_run_to_server(api, sequencing_run, progress_callback):
    """Upload a single run to the server.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to upload to the server
    progress_callback -- the function to call for indicating upload progress

    Publishes messages:
    start_online_validation -- when running an online validation (checking project ids) starts
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    start_checking_samples -- when initially checking to see which samples should be created on the server
    start_uploading_samples (params: sheet_dir) -- when actually initiating upload of the samples in the run
    finished_uploading_samples (params: sheet_dir) -- when uploading the samples has completed
    """

    filename = path.join(sequencing_run.sample_sheet_dir,
                         ".miseqUploaderInfo")

    def _handle_upload_sample_complete(sample):
        """Handle the event that happens when a sample has finished uploading.

        """

        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            if not 'uploaded_samples' in uploader_info:
                uploader_info['uploaded_samples'] = list()

            uploader_info['uploaded_samples'].append(sample.get_id())
        with open(filename, 'wb') as writer:
            json.dump(uploader_info, writer)
        logging.info("Finished updating info file.")

    def _sample_already_uploaded(sample):
        """Check whether or not a sample was already uploaded
        """
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            try:
                logging.info("Checking if {} was already uploaded in {}.".format(sample.get_id(), uploader_info['uploaded_samples']))
                return sample.get_id() in uploader_info['uploaded_samples']
            except KeyError:
                logging.info("sample {} was not uploaded.".format(sample.get_id()))
                return False

    # do online validation first.
    _online_validation(api, sequencing_run)
    # then do actual uploading

    if not path.exists(filename):
        logging.info("Going to create a new sequencing run on the server.")
        run_on_server = api.create_seq_run(sequencing_run.metadata)
        run_id = run_on_server["resource"]["identifier"]
        _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Uploading")
    else:
        logging.info("Resuming upload.")
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            run_id = uploader_info['Upload ID']

    send_message(RunUploaderTopics.start_checking_samples)
    logging.info("Starting to check samples. [{}]".format(len(sequencing_run.sample_list)))
    # only send samples that aren't already on the server
    samples_to_create = filter(lambda sample: not sample_exists(api, sample), sequencing_run.sample_list)
    logging.info("Sending samples to server: [{}].".format(", ".join([str(x) for x in samples_to_create])))
    api.send_samples(samples_to_create)

    pub.subscribe(_handle_upload_sample_complete, 'completed_uploading_sample')

    samples_to_upload = filter(lambda sample: not _sample_already_uploaded(sample), sequencing_run.sample_list)
    skipped_samples = filter(lambda sample: _sample_already_uploaded(sample), sequencing_run.sample_list)

    send_message("start_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir,
                                               skipped_sample_ids = [sample.get_id() for sample in skipped_samples],
                                               run_id = run_id)
    send_message(sequencing_run.sample_sheet_name + ".upload_started")

    logging.info("About to start uploading samples.")
    api.send_sequence_files(samples_list = samples_to_upload,
                                 callback = progress_callback, upload_id = run_id)
    send_message("finished_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir)
    send_message(sequencing_run.sample_sheet_name + ".upload_complete")
    api.set_seq_run_complete(run_id)
    _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Complete")

def _online_validation(api, sequencing_run):
    """Do online validation for the specified sequencing run.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to validate

    Publishes messages:
    start_online_validation -- when running online validation
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    """
    send_message("start_online_validation")
    for sample in sequencing_run.sample_list:
        if not project_exists(api, sample.get_project_id()):
            send_message("online_validation_failure", project_id=sample.get_project_id(), sample_id=sample.get_id())
            raise ProjectError("The Sample_Project: {pid} doesn't exist in IRIDA for Sample_Id: {sid}".format(
                    sid=sample.get_id(),
                    pid=sample.get_project_id()))

def _create_miseq_uploader_info_file(sample_sheet_dir, upload_id, upload_status):

    """
    creates a .miseqUploaderInfo file
    Contains Upload ID and Upload Status
    Upload ID is is the SequencingRun's identifier in IRIDA
    Upload Status will either be "Complete" or the last sequencing file
    that was uploaded.
    If there was an error with the upload then the last sequencing file
    uploaded will be written so that the program knows from which point to
    resume when the upload is restarted

    arguments:
        upload_status -- string that's either "Complete" or
                         string list of completed sequencing file path
                         uploads if upload was interrupted
                         used to know which files still need to be uploaded
                         when resuming upload

    no return value
    """

    filename = path.join(sample_sheet_dir,
                         ".miseqUploaderInfo")
    info = {
        "Upload ID": upload_id,
        "Upload Status": upload_status
    }
    with open(filename, "wb") as writer:
        json.dump(info, writer)
<commit_msg>Use the named topics from sequencing run instead of composing them by hand.<commit_after>from Validation.onlineValidation import project_exists, sample_exists
from wx.lib.pubsub import pub
import logging
from Exceptions.ProjectError import ProjectError
from API.pubsub import send_message
from os import path
import json

class RunUploaderTopics(object):
    start_online_validation = "start_online_validation"
    online_validation_failure = "online_validation_failure"
    start_checking_samples = "start_checking_samples"
    start_uploading_samples = "start_uploading_samples"
    finished_uploading_samples = "finished_uploading_samples"

def upload_run_to_server(api, sequencing_run, progress_callback):
    """Upload a single run to the server.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to upload to the server
    progress_callback -- the function to call for indicating upload progress

    Publishes messages:
    start_online_validation -- when running an online validation (checking project ids) starts
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    start_checking_samples -- when initially checking to see which samples should be created on the server
    start_uploading_samples (params: sheet_dir) -- when actually initiating upload of the samples in the run
    finished_uploading_samples (params: sheet_dir) -- when uploading the samples has completed
    """

    filename = path.join(sequencing_run.sample_sheet_dir,
                         ".miseqUploaderInfo")

    def _handle_upload_sample_complete(sample):
        """Handle the event that happens when a sample has finished uploading.

        """

        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            if not 'uploaded_samples' in uploader_info:
                uploader_info['uploaded_samples'] = list()

            uploader_info['uploaded_samples'].append(sample.get_id())
        with open(filename, 'wb') as writer:
            json.dump(uploader_info, writer)
        logging.info("Finished updating info file.")

    def _sample_already_uploaded(sample):
        """Check whether or not a sample was already uploaded
        """
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            try:
                logging.info("Checking if {} was already uploaded in {}.".format(sample.get_id(), uploader_info['uploaded_samples']))
                return sample.get_id() in uploader_info['uploaded_samples']
            except KeyError:
                logging.info("sample {} was not uploaded.".format(sample.get_id()))
                return False

    # do online validation first.
    _online_validation(api, sequencing_run)
    # then do actual uploading

    if not path.exists(filename):
        logging.info("Going to create a new sequencing run on the server.")
        run_on_server = api.create_seq_run(sequencing_run.metadata)
        run_id = run_on_server["resource"]["identifier"]
        _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Uploading")
    else:
        logging.info("Resuming upload.")
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            run_id = uploader_info['Upload ID']

    send_message(RunUploaderTopics.start_checking_samples)
    logging.info("Starting to check samples. [{}]".format(len(sequencing_run.sample_list)))
    # only send samples that aren't already on the server
    samples_to_create = filter(lambda sample: not sample_exists(api, sample), sequencing_run.sample_list)
    logging.info("Sending samples to server: [{}].".format(", ".join([str(x) for x in samples_to_create])))
    api.send_samples(samples_to_create)

    pub.subscribe(_handle_upload_sample_complete, 'completed_uploading_sample')

    samples_to_upload = filter(lambda sample: not _sample_already_uploaded(sample), sequencing_run.sample_list)
    skipped_samples = filter(lambda sample: _sample_already_uploaded(sample), sequencing_run.sample_list)

    send_message("start_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir,
                                               skipped_sample_ids = [sample.get_id() for sample in skipped_samples],
                                               run_id = run_id)
    send_message(sequencing_run.upload_started_topic)

    logging.info("About to start uploading samples.")
    api.send_sequence_files(samples_list = samples_to_upload,
                                 callback = progress_callback, upload_id = run_id)
    send_message("finished_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir)
    send_message(sequencing_run.upload_completed_topic)
    api.set_seq_run_complete(run_id)
    _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Complete")

def _online_validation(api, sequencing_run):
    """Do online validation for the specified sequencing run.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to validate

    Publishes messages:
    start_online_validation -- when running online validation
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    """
    send_message("start_online_validation")
    for sample in sequencing_run.sample_list:
        if not project_exists(api, sample.get_project_id()):
            send_message("online_validation_failure", project_id=sample.get_project_id(), sample_id=sample.get_id())
            raise ProjectError("The Sample_Project: {pid} doesn't exist in IRIDA for Sample_Id: {sid}".format(
                    sid=sample.get_id(),
                    pid=sample.get_project_id()))

def _create_miseq_uploader_info_file(sample_sheet_dir, upload_id, upload_status):

    """
    creates a .miseqUploaderInfo file
    Contains Upload ID and Upload Status
    Upload ID is is the SequencingRun's identifier in IRIDA
    Upload Status will either be "Complete" or the last sequencing file
    that was uploaded.
    If there was an error with the upload then the last sequencing file
    uploaded will be written so that the program knows from which point to
    resume when the upload is restarted

    arguments:
        upload_status -- string that's either "Complete" or
                         string list of completed sequencing file path
                         uploads if upload was interrupted
                         used to know which files still need to be uploaded
                         when resuming upload

    no return value
    """

    filename = path.join(sample_sheet_dir,
                         ".miseqUploaderInfo")
    info = {
        "Upload ID": upload_id,
        "Upload Status": upload_status
    }
    with open(filename, "wb") as writer:
        json.dump(info, writer)
<|endoftext|>


<commit_before>from Validation.onlineValidation import project_exists, sample_exists
from Exceptions.ProjectError import ProjectError
from API.pubsub import send_message

from os import path
from wx.lib.pubsub import pub

import json
import logging
import threading

class RunUploaderTopics(object):
    start_online_validation = "start_online_validation"
    online_validation_failure = "online_validation_failure"
    start_checking_samples = "start_checking_samples"
    start_uploading_samples = "start_uploading_samples"
    finished_uploading_samples = "finished_uploading_samples"

class RunUploader(threading.Thread):
    """A convenience thread wrapper for uploading runs to the server."""

    def __init__(self, api, runs, name='RunUploaderThread'):
        """Initialize a `RunUploader`.

        Args:
            api: an initialized connection to IRIDA.
            runs: a list of runs to upload to the server.
            name: the name of the thread.
        """
        self._stop_event = threading.Event()
        self._sleep_period = 1.0
        self._api = api
        self._runs = runs
        threading.Thread.__init__(self, name=name)

    def run(self):
        """Initiate upload. The upload happens serially, one run at a time."""
        for run in self._runs:
            upload_run_to_server(api=self._api, sequencing_run=run, progress_callback=None)

    def join(self, timeout=None):
        """Kill the thread.

        This will politely ask the API to terminate connections.

        Args:
            timeout: the length of time to wait before bailing out.
        """
        logging.info("Going to try killing connections on exit.")
        self._api._kill_connections()
        threading.Thread.join(self, timeout)

class RunUploaderTopics(object):
    start_online_validation = "start_online_validation"
    online_validation_failure = "online_validation_failure"
    start_checking_samples = "start_checking_samples"
    start_uploading_samples = "start_uploading_samples"
    finished_uploading_samples = "finished_uploading_samples"

def upload_run_to_server(api, sequencing_run, progress_callback):
    """Upload a single run to the server.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to upload to the server
    progress_callback -- the function to call for indicating upload progress

    Publishes messages:
    start_online_validation -- when running an online validation (checking project ids) starts
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    start_checking_samples -- when initially checking to see which samples should be created on the server
    start_uploading_samples (params: sheet_dir) -- when actually initiating upload of the samples in the run
    finished_uploading_samples (params: sheet_dir) -- when uploading the samples has completed
    """

    filename = path.join(sequencing_run.sample_sheet_dir,
                         ".miseqUploaderInfo")

    def _handle_upload_sample_complete(sample):
        """Handle the event that happens when a sample has finished uploading.

        """

        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            if not 'uploaded_samples' in uploader_info:
                uploader_info['uploaded_samples'] = list()

            uploader_info['uploaded_samples'].append(sample.get_id())
        with open(filename, 'wb') as writer:
            json.dump(uploader_info, writer)
        logging.info("Finished updating info file.")

    def _sample_already_uploaded(sample):
        """Check whether or not a sample was already uploaded
        """
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            try:
                logging.info("Checking if {} was already uploaded in {}.".format(sample.get_id(), uploader_info['uploaded_samples']))
                return sample.get_id() in uploader_info['uploaded_samples']
            except KeyError:
                logging.info("sample {} was not uploaded.".format(sample.get_id()))
                return False

    # do online validation first.
    _online_validation(api, sequencing_run)
    # then do actual uploading

    if not path.exists(filename):
        logging.info("Going to create a new sequencing run on the server.")
        run_on_server = api.create_seq_run(sequencing_run.metadata)
        run_id = run_on_server["resource"]["identifier"]
        _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Uploading")
    else:
        logging.info("Resuming upload.")
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            run_id = uploader_info['Upload ID']

    send_message(RunUploaderTopics.start_checking_samples)
    logging.info("Starting to check samples. [{}]".format(len(sequencing_run.sample_list)))
    # only send samples that aren't already on the server
    samples_to_create = filter(lambda sample: not sample_exists(api, sample), sequencing_run.sample_list)
    logging.info("Sending samples to server: [{}].".format(", ".join([str(x) for x in samples_to_create])))
    api.send_samples(samples_to_create)

    pub.subscribe(_handle_upload_sample_complete, 'completed_uploading_sample')

    samples_to_upload = filter(lambda sample: not _sample_already_uploaded(sample), sequencing_run.sample_list)
    skipped_samples = filter(lambda sample: _sample_already_uploaded(sample), sequencing_run.sample_list)

    send_message("start_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir,
                                               skipped_sample_ids = [sample.get_id() for sample in skipped_samples],
                                               run_id = run_id)
    send_message(sequencing_run.upload_started_topic)

    logging.info("About to start uploading samples.")
    try:
        api.send_sequence_files(samples_list = samples_to_upload,
                                     callback = progress_callback, upload_id = run_id)
        send_message("finished_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir)
        send_message(sequencing_run.upload_completed_topic)
        api.set_seq_run_complete(run_id)
        _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Complete")
    except Exception as e:
        logging.exception("Encountered error while uploading files to server, updating status of run to error state.")
        api.set_seq_run_error(run_id)

def _online_validation(api, sequencing_run):
    """Do online validation for the specified sequencing run.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to validate

    Publishes messages:
    start_online_validation -- when running online validation
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    """
    send_message("start_online_validation")
    for sample in sequencing_run.sample_list:
        if not project_exists(api, sample.get_project_id()):
            send_message("online_validation_failure", project_id=sample.get_project_id(), sample_id=sample.get_id())
            raise ProjectError("The Sample_Project: {pid} doesn't exist in IRIDA for Sample_Id: {sid}".format(
                    sid=sample.get_id(),
                    pid=sample.get_project_id()))

def _create_miseq_uploader_info_file(sample_sheet_dir, upload_id, upload_status):

    """
    creates a .miseqUploaderInfo file
    Contains Upload ID and Upload Status
    Upload ID is is the SequencingRun's identifier in IRIDA
    Upload Status will either be "Complete" or the last sequencing file
    that was uploaded.
    If there was an error with the upload then the last sequencing file
    uploaded will be written so that the program knows from which point to
    resume when the upload is restarted

    arguments:
        upload_status -- string that's either "Complete" or
                         string list of completed sequencing file path
                         uploads if upload was interrupted
                         used to know which files still need to be uploaded
                         when resuming upload

    no return value
    """

    filename = path.join(sample_sheet_dir,
                         ".miseqUploaderInfo")
    info = {
        "Upload ID": upload_id,
        "Upload Status": upload_status
    }
    with open(filename, "wb") as writer:
        json.dump(info, writer)
<commit_msg>Remove unused data member.<commit_after>from Validation.onlineValidation import project_exists, sample_exists
from Exceptions.ProjectError import ProjectError
from API.pubsub import send_message

from os import path
from wx.lib.pubsub import pub

import json
import logging
import threading

class RunUploaderTopics(object):
    start_online_validation = "start_online_validation"
    online_validation_failure = "online_validation_failure"
    start_checking_samples = "start_checking_samples"
    start_uploading_samples = "start_uploading_samples"
    finished_uploading_samples = "finished_uploading_samples"

class RunUploader(threading.Thread):
    """A convenience thread wrapper for uploading runs to the server."""

    def __init__(self, api, runs, name='RunUploaderThread'):
        """Initialize a `RunUploader`.

        Args:
            api: an initialized connection to IRIDA.
            runs: a list of runs to upload to the server.
            name: the name of the thread.
        """
        self._stop_event = threading.Event()
        self._api = api
        self._runs = runs
        threading.Thread.__init__(self, name=name)

    def run(self):
        """Initiate upload. The upload happens serially, one run at a time."""
        for run in self._runs:
            upload_run_to_server(api=self._api, sequencing_run=run, progress_callback=None)

    def join(self, timeout=None):
        """Kill the thread.

        This will politely ask the API to terminate connections.

        Args:
            timeout: the length of time to wait before bailing out.
        """
        logging.info("Going to try killing connections on exit.")
        self._api._kill_connections()
        threading.Thread.join(self, timeout)

class RunUploaderTopics(object):
    start_online_validation = "start_online_validation"
    online_validation_failure = "online_validation_failure"
    start_checking_samples = "start_checking_samples"
    start_uploading_samples = "start_uploading_samples"
    finished_uploading_samples = "finished_uploading_samples"

def upload_run_to_server(api, sequencing_run, progress_callback):
    """Upload a single run to the server.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to upload to the server
    progress_callback -- the function to call for indicating upload progress

    Publishes messages:
    start_online_validation -- when running an online validation (checking project ids) starts
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    start_checking_samples -- when initially checking to see which samples should be created on the server
    start_uploading_samples (params: sheet_dir) -- when actually initiating upload of the samples in the run
    finished_uploading_samples (params: sheet_dir) -- when uploading the samples has completed
    """

    filename = path.join(sequencing_run.sample_sheet_dir,
                         ".miseqUploaderInfo")

    def _handle_upload_sample_complete(sample):
        """Handle the event that happens when a sample has finished uploading.

        """

        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            if not 'uploaded_samples' in uploader_info:
                uploader_info['uploaded_samples'] = list()

            uploader_info['uploaded_samples'].append(sample.get_id())
        with open(filename, 'wb') as writer:
            json.dump(uploader_info, writer)
        logging.info("Finished updating info file.")

    def _sample_already_uploaded(sample):
        """Check whether or not a sample was already uploaded
        """
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            logging.info(uploader_info)
            try:
                logging.info("Checking if {} was already uploaded in {}.".format(sample.get_id(), uploader_info['uploaded_samples']))
                return sample.get_id() in uploader_info['uploaded_samples']
            except KeyError:
                logging.info("sample {} was not uploaded.".format(sample.get_id()))
                return False

    # do online validation first.
    _online_validation(api, sequencing_run)
    # then do actual uploading

    if not path.exists(filename):
        logging.info("Going to create a new sequencing run on the server.")
        run_on_server = api.create_seq_run(sequencing_run.metadata)
        run_id = run_on_server["resource"]["identifier"]
        _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Uploading")
    else:
        logging.info("Resuming upload.")
        with open(filename, "rb") as reader:
            uploader_info = json.load(reader)
            run_id = uploader_info['Upload ID']

    send_message(RunUploaderTopics.start_checking_samples)
    logging.info("Starting to check samples. [{}]".format(len(sequencing_run.sample_list)))
    # only send samples that aren't already on the server
    samples_to_create = filter(lambda sample: not sample_exists(api, sample), sequencing_run.sample_list)
    logging.info("Sending samples to server: [{}].".format(", ".join([str(x) for x in samples_to_create])))
    api.send_samples(samples_to_create)

    pub.subscribe(_handle_upload_sample_complete, 'completed_uploading_sample')

    samples_to_upload = filter(lambda sample: not _sample_already_uploaded(sample), sequencing_run.sample_list)
    skipped_samples = filter(lambda sample: _sample_already_uploaded(sample), sequencing_run.sample_list)

    send_message("start_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir,
                                               skipped_sample_ids = [sample.get_id() for sample in skipped_samples],
                                               run_id = run_id)
    send_message(sequencing_run.upload_started_topic)

    logging.info("About to start uploading samples.")
    try:
        api.send_sequence_files(samples_list = samples_to_upload,
                                     callback = progress_callback, upload_id = run_id)
        send_message("finished_uploading_samples", sheet_dir = sequencing_run.sample_sheet_dir)
        send_message(sequencing_run.upload_completed_topic)
        api.set_seq_run_complete(run_id)
        _create_miseq_uploader_info_file(sequencing_run.sample_sheet_dir, run_id, "Complete")
    except Exception as e:
        logging.exception("Encountered error while uploading files to server, updating status of run to error state.")
        api.set_seq_run_error(run_id)

def _online_validation(api, sequencing_run):
    """Do online validation for the specified sequencing run.

    Arguments:
    api -- the API object to use for interacting with the server
    sequencing_run -- the run to validate

    Publishes messages:
    start_online_validation -- when running online validation
    online_validation_failure (params: project_id, sample_id) -- when the online validation fails
    """
    send_message("start_online_validation")
    for sample in sequencing_run.sample_list:
        if not project_exists(api, sample.get_project_id()):
            send_message("online_validation_failure", project_id=sample.get_project_id(), sample_id=sample.get_id())
            raise ProjectError("The Sample_Project: {pid} doesn't exist in IRIDA for Sample_Id: {sid}".format(
                    sid=sample.get_id(),
                    pid=sample.get_project_id()))

def _create_miseq_uploader_info_file(sample_sheet_dir, upload_id, upload_status):

    """
    creates a .miseqUploaderInfo file
    Contains Upload ID and Upload Status
    Upload ID is is the SequencingRun's identifier in IRIDA
    Upload Status will either be "Complete" or the last sequencing file
    that was uploaded.
    If there was an error with the upload then the last sequencing file
    uploaded will be written so that the program knows from which point to
    resume when the upload is restarted

    arguments:
        upload_status -- string that's either "Complete" or
                         string list of completed sequencing file path
                         uploads if upload was interrupted
                         used to know which files still need to be uploaded
                         when resuming upload

    no return value
    """

    filename = path.join(sample_sheet_dir,
                         ".miseqUploaderInfo")
    info = {
        "Upload ID": upload_id,
        "Upload Status": upload_status
    }
    with open(filename, "wb") as writer:
        json.dump(info, writer)
<|endoftext|>


<commit_before>from __future__ import absolute_import, division, print_function

import contextlib
import os
import os.path

import fabric.api

@contextlib.contextmanager
def cd(path):
    current_path = os.path.abspath(os.curdir)
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(current_path)

@contextlib.contextmanager
def ssh_host(host):
    current_value = fabric.api.env.host_string
    fabric.api.env.host_string = host
    try:
        yield
    finally:
        fabric.api.env.host_string = current_value
<commit_msg>remove unneeded import<commit_after>from __future__ import absolute_import, division, print_function

import contextlib
import os

import fabric.api

@contextlib.contextmanager
def cd(path):
    current_path = os.path.abspath(os.curdir)
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(current_path)

@contextlib.contextmanager
def ssh_host(host):
    current_value = fabric.api.env.host_string
    fabric.api.env.host_string = host
    try:
        yield
    finally:
        fabric.api.env.host_string = current_value
<|endoftext|>


<commit_before>from django.views.generic import TemplateView, CreateView, DeleteView
from django.core.urlresolvers import reverse
from django.http.response import HttpResponseRedirect
from django.db.models import Sum
from django.shortcuts import get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from tasks.models import Project, Task, Comment, TimeLog, TaskState
from tasks.forms import ProjectForm, CommentTimeLogForm
from tasks.utils import (
    get_total_project_spend_time, annotate_total_time_per_task,
    LoginRequired,
)

class ProjectDetailView(LoginRequired, TemplateView):

    template_name = 'tasks/project_detail.html'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        project = self.get_project()
        tasks = self.get_tasks(project)
        total_project_spend_time = get_total_project_spend_time(tasks)
        annotate_total_time_per_task(tasks)

        context.update({
            'project': project, 'tasks': tasks,
            'total_project_spend_time': total_project_spend_time,
        })

        return context

    def get_project(self):
        user = self.request.user
        try:
            pk = int(self.kwargs.get('pk'))
            project = get_object_or_404(Project, id=pk, user=user)
        except ValueError:
            project = None

        return project

    def get_tasks(self, project):
        page = self.request.GET.get('page')
        task_list = Task.objects.filter(project=project).select_related()
        paginator = Paginator(task_list, 15)
        try:
            tasks = paginator.page(page)
        except PageNotAnInteger:
            tasks = paginator.page(1)
        except EmptyPage:
            tasks = paginator.page(paginator.num_pages)

        return tasks

class ProjectCreateView(LoginRequired, CreateView):

    model = Project
    template_name = 'tasks/project_form.html'
    form_class = ProjectForm

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update({'user': self.request.user})

        return kwargs

    def get_success_url(self):
        return reverse('tasks-project-detail', args=[self.object.id])

class ProjectDeleteView(LoginRequired, DeleteView):

    model = Project
    template_name = 'tasks/project_delete_confirm.html'

    def get_object(self):
        pk = self.kwargs.get('pk')
        user = self.request.user
        obj = get_object_or_404(Project, id=pk, user=user, default=False)

        return obj

    def get_success_url(self):
        return reverse('tasks-home')

class TasksHomeView(LoginRequired, TemplateView):

    template_name = 'tasks/tasks_home.html'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        user = self.request.user
        general_project = Project.objects.get(name='General', user=user)
        tasks = Task.objects.filter(project__user=user).select_related()[:15]
        total_project_spend_time = get_total_project_spend_time(tasks)
        annotate_total_time_per_task(tasks)
        context.update({
            'project': general_project, 'tasks': tasks,
            'total_project_spend_time': total_project_spend_time,
        })

        return context

class TaskCreateView(LoginRequired, CreateView):

    model = Task
    template_name = 'tasks/task_form.html'
    fields = ['name', 'description', 'priority', 'category']

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context.update({'project': self.get_project()})

        return context

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.project = self.get_project()
        self.object.state = TaskState.objects.get(name='New')
        self.object.save()

        return super().form_valid(form)

    def get_project(self):
        user = self.request.user
        id = self.kwargs.get('project_pk')
        project = get_object_or_404(Project, pk=id, user=user)

        return project

    def get_success_url(self):
        return reverse('tasks-project-detail', args=[self.object.project.id])

class TaskDetailView(LoginRequired, TemplateView):

    template_name = 'tasks/task_detail.html'

    def get(self, request, *args, **kwargs):
        self.task = self.get_task()
        comment_time_log_form = self.get_comment_time_log_form()

        return self.render_to_response(self.get_context_data(
            comment_time_log_form=comment_time_log_form
        ))

    def post(self, request, *args, **kwargs):
        self.task = self.get_task()
        comment_time_log_form = self.get_comment_time_log_form()
        if comment_time_log_form.is_valid():
            comment_time_log_form.save(self.task)
            response = HttpResponseRedirect(reverse(
                'tasks-task-detail', args=[self.task.id]
            ))
        else:
            response = self.render_to_response(
                self.get_context_data(comment_time_log_form=comment_time_log_form)
            )

        return response

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        comments = self.get_comments()
        total_spend_time = (
            TimeLog.objects.filter(comment__task=self.task)
            .aggregate(Sum('spend_time'))
        )['spend_time__sum']
        context.update({
            'task': self.task, 'comments': comments,
            'total_spend_time': total_spend_time,
        })

        return context

    def get_task(self):
        pk = self.kwargs.get('task_pk')
        user = self.request.user
        task = get_object_or_404(Task, id=pk, project__user=user)

        return task

    def get_comments(self):
        comments = (
            Comment.objects.all().filter(task=self.task).select_related('timelog')
        )

        return comments

    def get_comment_time_log_form(self):
        initial = {'state': self.task.state.id}
        if self.request.method == 'POST':
            comment_time_log_form = CommentTimeLogForm(
                self.request.POST, initial=initial
            )
        else:
            comment_time_log_form = CommentTimeLogForm(initial=initial)

        return comment_time_log_form
<commit_msg>Show only not closed task on home page<commit_after>from django.views.generic import TemplateView, CreateView, DeleteView
from django.core.urlresolvers import reverse
from django.http.response import HttpResponseRedirect
from django.db.models import Sum
from django.shortcuts import get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from tasks.models import Project, Task, Comment, TimeLog, TaskState
from tasks.forms import ProjectForm, CommentTimeLogForm
from tasks.utils import (
    get_total_project_spend_time, annotate_total_time_per_task,
    LoginRequired,
)

class ProjectDetailView(LoginRequired, TemplateView):

    template_name = 'tasks/project_detail.html'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        project = self.get_project()
        tasks = self.get_tasks(project)
        total_project_spend_time = get_total_project_spend_time(tasks)
        annotate_total_time_per_task(tasks)

        context.update({
            'project': project, 'tasks': tasks,
            'total_project_spend_time': total_project_spend_time,
        })

        return context

    def get_project(self):
        user = self.request.user
        try:
            pk = int(self.kwargs.get('pk'))
            project = get_object_or_404(Project, id=pk, user=user)
        except ValueError:
            project = None

        return project

    def get_tasks(self, project):
        page = self.request.GET.get('page')
        task_list = Task.objects.filter(project=project).select_related()
        paginator = Paginator(task_list, 15)
        try:
            tasks = paginator.page(page)
        except PageNotAnInteger:
            tasks = paginator.page(1)
        except EmptyPage:
            tasks = paginator.page(paginator.num_pages)

        return tasks

class ProjectCreateView(LoginRequired, CreateView):

    model = Project
    template_name = 'tasks/project_form.html'
    form_class = ProjectForm

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update({'user': self.request.user})

        return kwargs

    def get_success_url(self):
        return reverse('tasks-project-detail', args=[self.object.id])

class ProjectDeleteView(LoginRequired, DeleteView):

    model = Project
    template_name = 'tasks/project_delete_confirm.html'

    def get_object(self):
        pk = self.kwargs.get('pk')
        user = self.request.user
        obj = get_object_or_404(Project, id=pk, user=user, default=False)

        return obj

    def get_success_url(self):
        return reverse('tasks-home')

class TasksHomeView(LoginRequired, TemplateView):

    template_name = 'tasks/tasks_home.html'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        user = self.request.user
        general_project = Project.objects.get(name='General', user=user)
        not_closed_states = TaskState.objects.exclude(name='Closed')
        tasks = (
            Task.objects.filter(project__user=user, state=not_closed_states)
            .select_related()[:15]
        )
        total_project_spend_time = get_total_project_spend_time(tasks)
        annotate_total_time_per_task(tasks)
        context.update({
            'project': general_project, 'tasks': tasks,
            'total_project_spend_time': total_project_spend_time,
        })

        return context

class TaskCreateView(LoginRequired, CreateView):

    model = Task
    template_name = 'tasks/task_form.html'
    fields = ['name', 'description', 'priority', 'category']

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context.update({'project': self.get_project()})

        return context

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.project = self.get_project()
        self.object.state = TaskState.objects.get(name='New')
        self.object.save()

        return super().form_valid(form)

    def get_project(self):
        user = self.request.user
        id = self.kwargs.get('project_pk')
        project = get_object_or_404(Project, pk=id, user=user)

        return project

    def get_success_url(self):
        return reverse('tasks-project-detail', args=[self.object.project.id])

class TaskDetailView(LoginRequired, TemplateView):

    template_name = 'tasks/task_detail.html'

    def get(self, request, *args, **kwargs):
        self.task = self.get_task()
        comment_time_log_form = self.get_comment_time_log_form()

        return self.render_to_response(self.get_context_data(
            comment_time_log_form=comment_time_log_form
        ))

    def post(self, request, *args, **kwargs):
        self.task = self.get_task()
        comment_time_log_form = self.get_comment_time_log_form()
        if comment_time_log_form.is_valid():
            comment_time_log_form.save(self.task)
            response = HttpResponseRedirect(reverse(
                'tasks-task-detail', args=[self.task.id]
            ))
        else:
            response = self.render_to_response(
                self.get_context_data(comment_time_log_form=comment_time_log_form)
            )

        return response

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        comments = self.get_comments()
        total_spend_time = (
            TimeLog.objects.filter(comment__task=self.task)
            .aggregate(Sum('spend_time'))
        )['spend_time__sum']
        context.update({
            'task': self.task, 'comments': comments,
            'total_spend_time': total_spend_time,
        })

        return context

    def get_task(self):
        pk = self.kwargs.get('task_pk')
        user = self.request.user
        task = get_object_or_404(Task, id=pk, project__user=user)

        return task

    def get_comments(self):
        comments = (
            Comment.objects.all().filter(task=self.task).select_related('timelog')
        )

        return comments

    def get_comment_time_log_form(self):
        initial = {'state': self.task.state.id}
        if self.request.method == 'POST':
            comment_time_log_form = CommentTimeLogForm(
                self.request.POST, initial=initial
            )
        else:
            comment_time_log_form = CommentTimeLogForm(initial=initial)

        return comment_time_log_form
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import json, argparse, os, httplib2
from apiclient.discovery import build
# Get Credentials
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage

def create_oauth_authorize_file(json_key_file):
    if os.path.isfile(json_key_file):
        print 'Accepted... Loading JSON Key File.'
        try:
            # Get Secret Data from JSON File.
            json_data = json.loads(open(key_file_path).read())
            OAUTH_SCOPE = 'https://www.googleapis.com/auth/drive'
            CLIENT_ID = json_data['installed']['client_id']
            CLIENT_SECRET = json_data['installed']['client_secret']
            REDIRECT_URI = json_data['installed']['redirect_uris'][0]
            # Get authorize file.
            flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, redirect_uri=REDIRECT_URI)
            authorize_url = flow.step1_get_authorize_url()
            print 'Go to the following link in your browser: ' + authorize_url
            code = raw_input('Enter verification code: ').strip()
            credentials = flow.step2_exchange(code)
            storage = Storage('credentials_file')
            storage.put(credentials)

        except:
            print 'exception'
    else:
        print 'Not Accepted, No Available File.'

def create_google_drive_session(path_to_credentials_file):
    try:
        storage = Storage(path_to_credentials_file)
        credentials = storage.get()
        http = credentials.authorize(httplib2.Http())
        service = build('drive', 'v2', http=http)
        response = service.files().list().execute()
        print response
        for line in response:
            print line

    except:
        print 'Error'

if __name__ == "__main__":
    # --
    parser = argparse.ArgumentParser(description='Google Drive API.')
    parser.add_argument('-k', '--key', help='input google drive api json key.')

    args = parser.parse_args()
    # parser key file
    key_file_path = args.key
    if os.path.isfile('credentials_file'):
        print 'Find credentials file, now start service.'
        create_google_drive_session('credentials_file')

    else:
        print 'No credentials file, now create one.'
        create_oauth_authorize_file(key_file_path)
<commit_msg>PyDrive, make things easier<commit_after># -*- coding: utf-8 -*-
import json, argparse, os, httplib2
from apiclient.discovery import build
# Get Credentials
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.client import OAuth2Credentials
from oauth2client.file import Storage
# PyDrive
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

def create_oauth_authorize_file(json_key_file):
    if os.path.isfile(json_key_file):
        print 'Accepted... Loading JSON Key File.'
        try:
            # Get Secret Data from JSON File.
            json_data = json.loads(open(key_file_path).read())
            OAUTH_SCOPE = 'https://www.googleapis.com/auth/drive'
            CLIENT_ID = json_data['installed']['client_id']
            CLIENT_SECRET = json_data['installed']['client_secret']
            REDIRECT_URI = json_data['installed']['redirect_uris'][0]
            # Get authorize file.
            flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, redirect_uri=REDIRECT_URI)
            authorize_url = flow.step1_get_authorize_url()
            print 'Go to the following link in your browser: ' + authorize_url
            code = raw_input('Enter verification code: ').strip()
            credentials = flow.step2_exchange(code)
            storage = Storage('credentials_file')
            storage.put(credentials)

        except:
            print 'exception'
    else:
        print 'Not Accepted, No Available File.'

def create_google_drive_session(path_to_credentials_file):
    try:
        storage = Storage(path_to_credentials_file)
        credentials = storage.get()
        http = credentials.authorize(httplib2.Http())
        service = build('drive', 'v2', http=http)
        response = service.files().list().execute()

    except:
        print 'Error'

if __name__ == "__main__":
    # --
    parser = argparse.ArgumentParser(description='Google Drive API.')
    parser.add_argument('-k', '--key', help='input google drive api json key.')

    args = parser.parse_args()
    # parser key file
    key_file_path = args.key
    if os.path.isfile('credentials_file'):
        print 'Find credentials file, now start service.'
        gauth = GoogleAuth()
        gauth.credentials= OAuth2Credentials.from_json(open('credentials_file').read())
        drive = GoogleDrive(gauth)
        file_list = drive.ListFile({'q': "'root' in parents"}).GetList()
        for file1 in file_list:
          print 'title: %s, id: %s' % (file1['title'], file1['id'])

    else:
        print 'No credentials file, now create one.'
        create_oauth_authorize_file(key_file_path)
<|endoftext|>