<commit_before># -*- encoding: utf8 -*-
#
# Copyright (c) 2007 The PyAMF Project. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

"""
Remoting client implementation.

@author: U{Nick Joyce<mailto:nick@boxdesign.co.uk>}

@since: 0.1.0
"""

import httplib, urlparse

import pyamf
from pyamf import remoting

#: Default AMF client type.
#: @see: L{ClientTypes<pyamf.ClientTypes>}
DEFAULT_CLIENT_TYPE = pyamf.ClientTypes.Flash6

class ServiceMethodProxy(object):
    """
    Serves as a proxy for calling a service method.

    @ivar service: The parent service.
    @type service: L{ServiceProxy}
    @ivar name: The name of the method
    @type name: C{str} or C{None}

    @see: L{ServiceProxy.__getattr__}
    """

    def __init__(self, service, name):
        self.service = service
        self.name = name

    def __call__(self, *args):
        """
        Inform the proxied service that this function has been called
        """
        return self.service._call(self, args)

    def __str__(self):
        """
        Returns the full service name, including the method name if there is
        one.
        """
        service_name = str(self.service)

        if self.name is not None:
            service_name = '%s.%s' % (service_name, self.name)

        return service_name

class ServiceProxy(object):
    """
    Serves as a service object proxy for RPC calls. Generates
    L{ServiceMethodProxy} objects for method calls.

    @ivar _gw: The parent gateway.
    @type _gw: L{RemotingService}
    @ivar _name: The name of the service.
    @type _name: C{str}
    @ivar _auto_execute: If set to C{True}, when a service method is called,
        the AMF request is immediately sent to the remote gateway and a
        response is returned. If set to C{False}, a L{RequestWrapper} is
        returned, waiting for the underlying gateway to fire the
        {execute<L{RemotingService.execute}>} method.

    @see: L{RequestWrapper} for more info.
    """

    def __init__(self, gw, name, auto_execute=True):
        self._gw = gw
        self._name = name
        self._auto_execute = auto_execute

    def __getattr__(self, name):
        return ServiceMethodProxy(self, name)

    def _call(self, method_proxy, args):
        """
        Executed when a L{ServiceMethodProxy} is called. Adds a request to the
        underlying gateway. If _auto_execute is set to C{True}, then the
        request is immediately called on the remote gateway.
        """
        request = self._gw.addRequest(method_proxy, args)

        if self._auto_execute:
            response = self._gw.execute_single(request)

            # XXX nick: What to do about Fault objects here?
            return response.body

        return request

    def __call__(self, *args):
        """
        This allows services to be 'called' without a method name.
        """
        return self._call(ServiceMethodProxy(self, None), args)

    def __str__(self):
        """
        Returns a string representation of the name of the service.
        """
        return self._name

class RequestWrapper(object):
    """
    A container object that wraps a service method request.

    @ivar gw: The underlying gateway
    @type gw: L{RemotingService}
    @ivar id: The id of the request
    @type id: C{str}
    @ivar service: The service proxy
    @type service: L{ServiceProxy}
    @ivar args: The args used to invoke the call
    @type args: C{list}
    """

    def __init__(self, gw, id_, service, args):
        self.gw = gw
        self.id = id_
        self.service = service
        self.args = args

    def __str__(self):
        return str(self.id)

    def setResponse(self, response):
        """
        A response has been received by the gateway
        """
        # XXX nick: What to do about Fault objects here?
        self.response = response
        self.result = self.response.body

    def _get_result(self):
        """
        Returns the result of the called remote request. If the request has not
        yet been called, an exception is raised.
        """
        if not hasattr(self, '_result'):
            raise AttributeError, "'RequestWrapper' object has no attribute 'result'"

        return self._result

    def _set_result(self, result):
        self._result = result

    result = property(_get_result, _set_result)

class RemotingService(object):
    """
    Acts as a client for AMF calls.

    @ivar url: The url of the remote gateway. Accepts http or https as schemes
    @type url: C{str}
    @ivar requests: The list of pending requests to process
    @type requests: C{list}
    @ivar request_number: A unique identifier for an tracking the number of
        requests.
    @ivar amf_version: The AMF version to use. See L{pyamf.ENCODING_TYPES}
    @type amf_version: C{int}
    @ivar client_type: The client type. See L{pyamf.ClientTypes}
    @ivar connection: The underlying connection to the remoting server.
    @type connection: C{httplib.HTTPConnection} or C{httplib.HTTPSConnection}
    """

    def __init__(self, url, amf_version=pyamf.AMF0, client_type=DEFAULT_CLIENT_TYPE):
        self.url = urlparse.urlparse(url)
        self.requests = []
        self.request_number = 1
        self._root_url = urlparse.urlunparse(['', ''] + list(self.url[2:]))

        self.amf_version = amf_version
        self.client_type = client_type

        port = None
        hostname = None

        if hasattr(self.url, 'port'):
            if self.url.port is not None:
                port = self.url.port
        else:
            if ':' not in self.url[1]:
                port = None
            else:
                hostname, port = self.url[1].rsplit(':', 1)
                port = int(port)

        if hostname is None:
            if hasattr(self.url, 'hostname'):
                hostname = self.url.hostname

        if self.url[0] == 'http':
            if port is None:
                port = 80

            self.connection = httplib.HTTPConnection(hostname, port)
        elif self.url[0] == 'https':
            if port is None:
                port = 443

            self.connection = httplib.HTTPSConnection(hostname, port)
        else:
            raise ValueError, 'Unknown scheme'

    def getService(self, name, auto_execute=True):
        """
        Returns a L{ServiceProxy} for the supplied name. Sets up an object that
        can have method calls made to it that build the AMF requests.
        """
        if not isinstance(name, basestring):
            raise TypeError, 'string type required'

        return ServiceProxy(self, name, auto_execute)

    def getRequest(self, id_):
        """
        Gets a request based on the id
        """
        for request in self.requests:
            if request.id == id_:
                return request

        raise LookupError, "request %s not found" % id_

    def addRequest(self, service, *args):
        """
        Adds a request to be sent to the remoting gateway
        """
        wrapper = RequestWrapper(self, '/%d' % self.request_number,
            service, args)

        self.request_number += 1
        self.requests.append(wrapper)

        return wrapper

    def removeRequest(self, service, *args):
        """
        Removes a request from the pending request list
        """
        if isinstance(service, RequestWrapper):
            del self.requests[self.requests.index(service)]

            return

        for request in self.requests:
            if request.service == service and request.args == args:
                del self.requests[self.requests.index(request)]

                return

        raise LookupError, "request not found"

    def getAMFRequest(self, requests):
        """
        Builds an AMF request L{envelope<pyamf.remoting.Envelope>} from a
        supplied list of requests
        """
        envelope = remoting.Envelope(self.amf_version, self.client_type)

        for request in requests:
            service = request.service
            args = request.args

            envelope[request.id] = remoting.Request(str(service), args)

        return envelope

    def execute_single(self, request):
        """
        Builds, sends and handles the response to a single request, returning
        the response.
        """
        body = remoting.encode(self.getAMFRequest([request]))

        self.connection.request('POST', self._root_url, body.getvalue())

        envelope = self._getResponse()
        self.removeRequest(request)

        return envelope[request.id]

    def execute(self):
        """
        Builds, sends and handles the responses to all requests listed in
        C{self.requests}.
        """
        body = remoting.encode(self.getAMFRequest(self.requests))

        self.connection.request('POST', self._root_url, body.getvalue())

        envelope = self._getResponse()

        for response in envelope:
            request = self.getRequest(response[0])
            response = response[1]

            request.setResponse(response)

            self.removeRequest(request)

    def _getResponse(self):
        """
        Gets and handles the http response from the remote gateway
        """
        http_response = self.connection.getresponse()

        if http_response.status != 200:
            raise remoting.RemotingError, "HTTP Gateway reported status %d" % (
                http_response.status,)

        content_type = http_response.getheader('Content-Type')

        if content_type != remoting.CONTENT_TYPE:
            raise remoting.RemotingError, "Incorrect mime type received."

        content_length = http_response.getheader('Content-Length')
        bytes = ''

        if content_length is None:
            bytes = http_response.read()
        else:
            bytes = http_response.read(content_length)

        return remoting.decode(bytes)
<commit_msg>Epydoc fix.<commit_after># -*- encoding: utf8 -*-
#
# Copyright (c) 2007 The PyAMF Project. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

"""
Remoting client implementation.

@author: U{Nick Joyce<mailto:nick@boxdesign.co.uk>}

@since: 0.1.0
"""

import httplib, urlparse

import pyamf
from pyamf import remoting

#: Default AMF client type.
#: @see: L{ClientTypes<pyamf.ClientTypes>}
DEFAULT_CLIENT_TYPE = pyamf.ClientTypes.Flash6

class ServiceMethodProxy(object):
    """
    Serves as a proxy for calling a service method.

    @ivar service: The parent service.
    @type service: L{ServiceProxy}
    @ivar name: The name of the method
    @type name: C{str} or C{None}

    @see: L{ServiceProxy.__getattr__}
    """

    def __init__(self, service, name):
        self.service = service
        self.name = name

    def __call__(self, *args):
        """
        Inform the proxied service that this function has been called.
        """
        return self.service._call(self, args)

    def __str__(self):
        """
        Returns the full service name, including the method name if there is
        one.
        """
        service_name = str(self.service)

        if self.name is not None:
            service_name = '%s.%s' % (service_name, self.name)

        return service_name

class ServiceProxy(object):
    """
    Serves as a service object proxy for RPC calls. Generates
    L{ServiceMethodProxy} objects for method calls.

    @ivar _gw: The parent gateway.
    @type _gw: L{RemotingService}
    @ivar _name: The name of the service.
    @type _name: C{str}
    @ivar _auto_execute: If set to C{True}, when a service method is called,
        the AMF request is immediately sent to the remote gateway and a
        response is returned. If set to C{False}, a L{RequestWrapper} is
        returned, waiting for the underlying gateway to fire the
        L{execute<RemotingService.execute>} method.

    @see: L{RequestWrapper} for more info.
    """

    def __init__(self, gw, name, auto_execute=True):
        self._gw = gw
        self._name = name
        self._auto_execute = auto_execute

    def __getattr__(self, name):
        return ServiceMethodProxy(self, name)

    def _call(self, method_proxy, args):
        """
        Executed when a L{ServiceMethodProxy} is called. Adds a request to
        the underlying gateway. If C{_auto_execute} is set to C{True}, then
        the request is immediately called on the remote gateway.
        """
        request = self._gw.addRequest(method_proxy, args)

        if self._auto_execute:
            response = self._gw.execute_single(request)

            # XXX nick: What to do about Fault objects here?
            return response.body

        return request

    def __call__(self, *args):
        """
        This allows services to be 'called' without a method name.
        """
        return self._call(ServiceMethodProxy(self, None), args)

    def __str__(self):
        """
        Returns a string representation of the name of the service.
        """
        return self._name

class RequestWrapper(object):
    """
    A container object that wraps a service method request.

    @ivar gw: The underlying gateway.
    @type gw: L{RemotingService}
    @ivar id: The id of the request.
    @type id: C{str}
    @ivar service: The service proxy.
    @type service: L{ServiceProxy}
    @ivar args: The args used to invoke the call.
    @type args: C{list}
    """

    def __init__(self, gw, id_, service, args):
        self.gw = gw
        self.id = id_
        self.service = service
        self.args = args

    def __str__(self):
        return str(self.id)

    def setResponse(self, response):
        """
        A response has been received by the gateway
        """
        # XXX nick: What to do about Fault objects here?
        self.response = response
        self.result = self.response.body

    def _get_result(self):
        """
        Returns the result of the called remote request. If the request has not
        yet been called, an exception is raised.
        """
        if not hasattr(self, '_result'):
            raise AttributeError, "'RequestWrapper' object has no attribute 'result'"

        return self._result

    def _set_result(self, result):
        self._result = result

    result = property(_get_result, _set_result)

class RemotingService(object):
    """
    Acts as a client for AMF calls.

    @ivar url: The url of the remote gateway. Accepts http or https as schemes.
    @type url: C{str}
    @ivar requests: The list of pending requests to process.
    @type requests: C{list}
    @ivar request_number: A unique identifier for an tracking the number of
        requests.
    @ivar amf_version: The AMF version to use.
        See L{ENCODING_TYPES<pyamf.ENCODING_TYPES>}.
    @type amf_version: C{int}
    @ivar client_type: The client type. See L{ClientTypes<pyamf.ClientTypes>}.
    @ivar connection: The underlying connection to the remoting server.
    @type connection: C{httplib.HTTPConnection} or C{httplib.HTTPSConnection}

    @raise ValueError: Unknown scheme.
    """

    def __init__(self, url, amf_version=pyamf.AMF0, client_type=DEFAULT_CLIENT_TYPE):
        self.url = urlparse.urlparse(url)
        self.requests = []
        self.request_number = 1
        self._root_url = urlparse.urlunparse(['', ''] + list(self.url[2:]))

        self.amf_version = amf_version
        self.client_type = client_type

        port = None
        hostname = None

        if hasattr(self.url, 'port'):
            if self.url.port is not None:
                port = self.url.port
        else:
            if ':' not in self.url[1]:
                port = None
            else:
                hostname, port = self.url[1].rsplit(':', 1)
                port = int(port)

        if hostname is None:
            if hasattr(self.url, 'hostname'):
                hostname = self.url.hostname

        if self.url[0] == 'http':
            if port is None:
                port = 80

            self.connection = httplib.HTTPConnection(hostname, port)
        elif self.url[0] == 'https':
            if port is None:
                port = 443

            self.connection = httplib.HTTPSConnection(hostname, port)
        else:
            raise ValueError, 'Unknown scheme'

    def getService(self, name, auto_execute=True):
        """
        Returns a L{ServiceProxy} for the supplied name. Sets up an object that
        can have method calls made to it that build the AMF requests.

        @raise TypeError: string type required for C{name}.
        """
        if not isinstance(name, basestring):
            raise TypeError, 'string type required'

        return ServiceProxy(self, name, auto_execute)

    def getRequest(self, id_):
        """
        Gets a request based on the id.
        """
        for request in self.requests:
            if request.id == id_:
                return request

        raise LookupError, "request %s not found" % id_

    def addRequest(self, service, *args):
        """
        Adds a request to be sent to the remoting gateway.
        """
        wrapper = RequestWrapper(self, '/%d' % self.request_number,
            service, args)

        self.request_number += 1
        self.requests.append(wrapper)

        return wrapper

    def removeRequest(self, service, *args):
        """
        Removes a request from the pending request list.

        @raise LookupError: Request not found.
        """
        if isinstance(service, RequestWrapper):
            del self.requests[self.requests.index(service)]

            return

        for request in self.requests:
            if request.service == service and request.args == args:
                del self.requests[self.requests.index(request)]

                return

        raise LookupError, "request not found"

    def getAMFRequest(self, requests):
        """
        Builds an AMF request L{envelope<pyamf.remoting.Envelope>} from a
        supplied list of requests.
        """
        envelope = remoting.Envelope(self.amf_version, self.client_type)

        for request in requests:
            service = request.service
            args = request.args

            envelope[request.id] = remoting.Request(str(service), args)

        return envelope

    def execute_single(self, request):
        """
        Builds, sends and handles the response to a single request, returning
        the response.
        """
        body = remoting.encode(self.getAMFRequest([request]))

        self.connection.request('POST', self._root_url, body.getvalue())

        envelope = self._getResponse()
        self.removeRequest(request)

        return envelope[request.id]

    def execute(self):
        """
        Builds, sends and handles the responses to all requests listed in
        C{self.requests}.
        """
        body = remoting.encode(self.getAMFRequest(self.requests))

        self.connection.request('POST', self._root_url, body.getvalue())

        envelope = self._getResponse()

        for response in envelope:
            request = self.getRequest(response[0])
            response = response[1]

            request.setResponse(response)

            self.removeRequest(request)

    def _getResponse(self):
        """
        Gets and handles the HTTP response from the remote gateway.

        @raise RemotingError: Incorrect MIME-type received.
        """
        http_response = self.connection.getresponse()

        if http_response.status != 200:
            raise remoting.RemotingError, "HTTP Gateway reported status %d" % (
                http_response.status,)

        content_type = http_response.getheader('Content-Type')

        if content_type != remoting.CONTENT_TYPE:
            raise remoting.RemotingError, "Incorrect MIME type received."

        content_length = http_response.getheader('Content-Length')
        bytes = ''

        if content_length is None:
            bytes = http_response.read()
        else:
            bytes = http_response.read(content_length)

        return remoting.decode(bytes)
<|endoftext|>


<commit_before>from rest_framework import serializers

from .models import (
    Convention,
    Contest,
    Contestant,
    Group,
    Performance,
    Note,
)

from django.contrib.auth import get_user_model
User = get_user_model()

class PerformanceSerializer(serializers.ModelSerializer):
    round = serializers.CharField(
        source='get_round_display',
    )

    class Meta:
        model = Performance
        lookup_field = 'slug'
        fields = (
            'id',
            'round',
            'queue',
            'session',
            'stagetime',
            'place',
            'song1',
            'mus1',
            'prs1',
            'sng1',
            'song2',
            'mus2',
            'prs2',
            'sng2',
            'mus1_score',
            'prs1_score',
            'sng1_score',
            'song1_points',
            'song1_score',
            'mus2_score',
            'prs2_score',
            'sng2_score',
            'song2_points',
            'song2_score',
            'points',
            'score',
        )

class GroupSerializer(serializers.ModelSerializer):

    kind = serializers.CharField(
        source='get_kind_display',
    )

    chapterName = serializers.CharField(
        source='chapter_name',
    )

    # lead = serializers.StringRelatedField()

    # tenor = serializers.StringRelatedField()

    # baritone = serializers.StringRelatedField()

    # bass = serializers.StringRelatedField()

    class Meta:
        model = Group
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'kind',
            'location',
            'website',
            'facebook',
            'twitter',
            'email',
            'phone',
            'picture',
            'description',
            'notes',
            'chapterName',
            # 'lead',
            # 'tenor',
            # 'baritone',
            # 'bass',
            'bsmdb',
            # 'contestants',
        )

class ContestantSerializer(serializers.ModelSerializer):
    contest = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    performances = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True,
    )

    district = serializers.StringRelatedField()

    group = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    lead = serializers.StringRelatedField()

    tenor = serializers.StringRelatedField()

    baritone = serializers.StringRelatedField()

    bass = serializers.StringRelatedField()

    director = serializers.StringRelatedField()

    # group = GroupSerializer(
    #     read_only=True,
    # )

    # performances = PerformanceSerializer(
    #     read_only=True,
    #     many=True,
    # )

    class Meta:
        model = Contestant
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'contest',
            'group',
            'district',
            'seed',
            'prelim',
            'place',
            'score',
            'queue',
            'stagetime',
            'quarters_place',
            'quarters_score',
            'semis_place',
            'semis_score',
            'finals_place',
            'finals_score',
            'director',
            'lead',
            'tenor',
            'baritone',
            'bass',
            'men',
            'performances',
        )

class ContestSerializer(serializers.ModelSerializer):
    contestants = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    level_display = serializers.CharField(
        source='get_level_display',
    )

    kind_display = serializers.CharField(
        source='get_kind_display',
    )

    year_display = serializers.CharField(
        source='get_year_display',
    )

    district = serializers.StringRelatedField()

    class Meta:
        model = Contest
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'level_display',
            'kind_display',
            'year_display',
            'district',
            'panel',
            'scoresheet_pdf',
            'contestants',
            'is_active',
            'is_complete',
        )

class ConventionSerializer(serializers.ModelSerializer):
    contests = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    # contests = ContestSerializer(
    #     read_only=True,
    #     many=True,
    # )

    year = serializers.CharField(
        source='get_year_display',
    )

    class Meta:
        model = Convention
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'dates',
            'year',
            'timezone',
            'contests',
            'is_active',
        )

class NoteSerializer(serializers.ModelSerializer):
    performance = serializers.SlugRelatedField(
        # read_only=True,
        queryset=Performance.objects.all(),
        slug_field='slug',
    )

    user = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        # read_only=True,
    )

    class Meta:
        model = Note
        fields = (
            'id',
            'text',
            'performance',
            'user',
        )

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = (
            'id',
            'email',
            'username',
        )
<commit_msg>TODO marker for get_foo_display issue [ci skip]<commit_after>from rest_framework import serializers

from .models import (
    Convention,
    Contest,
    Contestant,
    Group,
    Performance,
    Note,
)

from django.contrib.auth import get_user_model
User = get_user_model()

class PerformanceSerializer(serializers.ModelSerializer):
    round = serializers.CharField(
        source='get_round_display',
    )

    class Meta:
        model = Performance
        lookup_field = 'slug'
        fields = (
            'id',
            'round',
            'queue',
            'session',
            'stagetime',
            'place',
            'song1',
            'mus1',
            'prs1',
            'sng1',
            'song2',
            'mus2',
            'prs2',
            'sng2',
            'mus1_score',
            'prs1_score',
            'sng1_score',
            'song1_points',
            'song1_score',
            'mus2_score',
            'prs2_score',
            'sng2_score',
            'song2_points',
            'song2_score',
            'points',
            'score',
        )

class GroupSerializer(serializers.ModelSerializer):

    kind = serializers.CharField(
        source='get_kind_display',
    )

    chapterName = serializers.CharField(
        source='chapter_name',
    )

    # lead = serializers.StringRelatedField()

    # tenor = serializers.StringRelatedField()

    # baritone = serializers.StringRelatedField()

    # bass = serializers.StringRelatedField()

    class Meta:
        model = Group
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'kind',
            'location',
            'website',
            'facebook',
            'twitter',
            'email',
            'phone',
            'picture',
            'description',
            'notes',
            'chapterName',
            # 'lead',
            # 'tenor',
            # 'baritone',
            # 'bass',
            'bsmdb',
            # 'contestants',
        )

class ContestantSerializer(serializers.ModelSerializer):
    contest = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    performances = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True,
    )

    district = serializers.StringRelatedField()

    group = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    lead = serializers.StringRelatedField()

    tenor = serializers.StringRelatedField()

    baritone = serializers.StringRelatedField()

    bass = serializers.StringRelatedField()

    director = serializers.StringRelatedField()

    # group = GroupSerializer(
    #     read_only=True,
    # )

    # performances = PerformanceSerializer(
    #     read_only=True,
    #     many=True,
    # )

    class Meta:
        model = Contestant
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'contest',
            'group',
            'district',
            'seed',
            'prelim',
            'place',
            'score',
            'queue',
            'stagetime',
            'quarters_place',
            'quarters_score',
            'semis_place',
            'semis_score',
            'finals_place',
            'finals_score',
            'director',
            'lead',
            'tenor',
            'baritone',
            'bass',
            'men',
            'performances',
        )

class ContestSerializer(serializers.ModelSerializer):
    contestants = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    # TODO - Weird!

    level_display = serializers.CharField(
        source='get_level_display',
    )

    kind_display = serializers.CharField(
        source='get_kind_display',
    )

    year_display = serializers.CharField(
        source='get_year_display',
    )

    district = serializers.StringRelatedField()

    class Meta:
        model = Contest
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'level_display',
            'kind_display',
            'year_display',
            'district',
            'panel',
            'scoresheet_pdf',
            'contestants',
            'is_active',
            'is_complete',
        )

class ConventionSerializer(serializers.ModelSerializer):
    contests = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    # contests = ContestSerializer(
    #     read_only=True,
    #     many=True,
    # )

    year = serializers.CharField(
        source='get_year_display',
    )

    class Meta:
        model = Convention
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'dates',
            'year',
            'timezone',
            'contests',
            'is_active',
        )

class NoteSerializer(serializers.ModelSerializer):
    performance = serializers.SlugRelatedField(
        # read_only=True,
        queryset=Performance.objects.all(),
        slug_field='slug',
    )

    user = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        # read_only=True,
    )

    class Meta:
        model = Note
        fields = (
            'id',
            'text',
            'performance',
            'user',
        )

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = (
            'id',
            'email',
            'username',
        )
<|endoftext|>


<commit_before>from rest_framework import serializers

from .models import (
    Convention,
    Contest,
    Contestant,
    Group,
    Performance,
    Note,
)

from django.contrib.auth import get_user_model
User = get_user_model()

class PerformanceSerializer(serializers.ModelSerializer):
    round = serializers.CharField(
        source='get_round_display',
    )

    kind = serializers.CharField(
        source='contestant.contest.get_kind_display',
    )

    prelim = serializers.FloatField(
        source='contestant.prelim',
    )

    group = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
        source='contestant.group',
    )

    class Meta:
        model = Performance
        lookup_field = 'slug'
        fields = (
            'id',
            'round',
            'kind',
            'prelim',
            'group',
            'queue',
            'session',
            'stagetime',
            'place',
            'song1',
            'mus1',
            'prs1',
            'sng1',
            'song2',
            'mus2',
            'prs2',
            'sng2',
            'men',
            'mus1_rata',
            'prs1_rata',
            'sng1_rata',
            'song1_raw',
            'song1_rata',
            'mus2_rata',
            'prs2_rata',
            'sng2_rata',
            'song2_raw',
            'song2_rata',
            'total_raw',
            'score',
        )

class GroupSerializer(serializers.ModelSerializer):

    kind = serializers.CharField(
        source='get_kind_display',
    )

    chapterName = serializers.CharField(
        source='chapter_name',
    )

    # lead = serializers.StringRelatedField()

    # tenor = serializers.StringRelatedField()

    # baritone = serializers.StringRelatedField()

    # bass = serializers.StringRelatedField()

    class Meta:
        model = Group
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'kind',
            'location',
            'website',
            'facebook',
            'twitter',
            'email',
            'phone',
            'picture',
            'description',
            'director',
            'chapterName',
            # 'lead',
            # 'tenor',
            # 'baritone',
            # 'bass',
            'bsmdb',
            # 'contestants',
        )

class ContestantSerializer(serializers.ModelSerializer):
    contest = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    performances = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True,
    )

    district = serializers.StringRelatedField()

    group = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    # group = GroupSerializer(
    #     read_only=True,
    # )

    # performances = PerformanceSerializer(
    #     read_only=True,
    #     many=True,
    # )

    class Meta:
        model = Contestant
        lookup_field = 'slug'
        fields = (
            'id',
            'slug',
            'contest',
            'group',
            'district',
            'seed',
            'prelim',
            'place',
            'score',
            'queue',
            'stagetime',
            'quarters_place',
            'quarters_score',
            'semis_place',
            'semis_score',
            'finals_place',
            'finals_score',
            'performances',
        )

class ContestSerializer(serializers.ModelSerializer):
    contestants = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    level = serializers.CharField(
        source='get_level_display',
    )

    kind = serializers.CharField(
        source='get_kind_display',
    )

    year = serializers.CharField(
        source='get_year_display',
    )

    district = serializers.StringRelatedField()

    class Meta:
        model = Contest
        lookup_field = 'slug'
        fields = (
            'id',
            'slug',
            'level',
            'kind',
            'year',
            'district',
            'panel',
            'scoresheet_pdf',
            'contestants',
            'is_active',
            'is_complete',
        )

class ConventionSerializer(serializers.ModelSerializer):
    contests = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    # contests = ContestSerializer(
    #     read_only=True,
    #     many=True,
    # )

    year = serializers.CharField(
        source='get_year_display',
    )

    class Meta:
        model = Convention
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'dates',
            'year',
            'timezone',
            'contests',
            'is_active',
        )

class NoteSerializer(serializers.ModelSerializer):
    performance = serializers.SlugRelatedField(
        # read_only=True,
        queryset=Performance.objects.all(),
        slug_field='slug',
    )

    user = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        # read_only=True,
    )

    class Meta:
        model = Note
        fields = (
            'id',
            'text',
            'performance',
            'user',
        )

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = (
            'id',
            'email',
            'username',
        )
<commit_msg>Update Serializers<commit_after>from rest_framework import serializers

from .models import (
    Convention,
    Contest,
    Contestant,
    Group,
    Performance,
    Note,
)

from django.contrib.auth import get_user_model
User = get_user_model()

class PerformanceSerializer(serializers.ModelSerializer):
    round = serializers.CharField(
        source='get_round_display',
    )

    kind = serializers.CharField(
        source='contestant.contest.get_kind_display',
    )

    prelim = serializers.FloatField(
        source='contestant.prelim',
    )

    group = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
        source='contestant.group',
    )

    class Meta:
        model = Performance
        lookup_field = 'slug'
        fields = (
            'id',
            'round',
            'kind',
            'prelim',
            'group',
            'queue',
            'session',
            'stagetime',
            'place',
            'song1',
            'mus1',
            'prs1',
            'sng1',
            'song2',
            'mus2',
            'prs2',
            'sng2',
            'men',
            'mus1_rata',
            'prs1_rata',
            'sng1_rata',
            'song1_raw',
            'song1_rata',
            'mus2_rata',
            'prs2_rata',
            'sng2_rata',
            'song2_raw',
            'song2_rata',
            'total_raw',
            'score',
        )

class GroupSerializer(serializers.ModelSerializer):

    kind = serializers.CharField(
        source='get_kind_display',
    )

    chapterName = serializers.CharField(
        source='chapter_name',
    )

    # lead = serializers.StringRelatedField()

    # tenor = serializers.StringRelatedField()

    # baritone = serializers.StringRelatedField()

    # bass = serializers.StringRelatedField()

    class Meta:
        model = Group
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'kind',
            'location',
            'website',
            'facebook',
            'twitter',
            'email',
            'phone',
            'picture',
            'description',
            'chapterName',
            # 'lead',
            # 'tenor',
            # 'baritone',
            # 'bass',
            'bsmdb',
            # 'contestants',
        )

class ContestantSerializer(serializers.ModelSerializer):
    contest = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    performances = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True,
    )

    district = serializers.StringRelatedField()

    group = serializers.SlugRelatedField(
        read_only=True,
        slug_field='slug',
    )

    lead = serializers.StringRelatedField()

    tenor = serializers.StringRelatedField()

    baritone = serializers.StringRelatedField()

    bass = serializers.StringRelatedField()

    director = serializers.StringRelatedField()

    # group = GroupSerializer(
    #     read_only=True,
    # )

    # performances = PerformanceSerializer(
    #     read_only=True,
    #     many=True,
    # )

    class Meta:
        model = Contestant
        lookup_field = 'slug'
        fields = (
            'id',
            'slug',
            'contest',
            'group',
            'district',
            'seed',
            'prelim',
            'place',
            'score',
            'queue',
            'stagetime',
            'quarters_place',
            'quarters_score',
            'semis_place',
            'semis_score',
            'finals_place',
            'finals_score',
            'director',
            'lead',
            'tenor',
            'baritone',
            'bass',
            'performances',
        )

class ContestSerializer(serializers.ModelSerializer):
    contestants = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    level = serializers.CharField(
        source='get_level_display',
    )

    kind = serializers.CharField(
        source='get_kind_display',
    )

    year = serializers.CharField(
        source='get_year_display',
    )

    district = serializers.StringRelatedField()

    class Meta:
        model = Contest
        lookup_field = 'slug'
        fields = (
            'id',
            'slug',
            'level',
            'kind',
            'year',
            'district',
            'panel',
            'scoresheet_pdf',
            'contestants',
            'is_active',
            'is_complete',
        )

class ConventionSerializer(serializers.ModelSerializer):
    contests = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='slug',
    )

    # contests = ContestSerializer(
    #     read_only=True,
    #     many=True,
    # )

    year = serializers.CharField(
        source='get_year_display',
    )

    class Meta:
        model = Convention
        lookup_field = 'slug'
        fields = (
            'id',
            'url',
            'slug',
            'name',
            'dates',
            'year',
            'timezone',
            'contests',
            'is_active',
        )

class NoteSerializer(serializers.ModelSerializer):
    performance = serializers.SlugRelatedField(
        # read_only=True,
        queryset=Performance.objects.all(),
        slug_field='slug',
    )

    user = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        # read_only=True,
    )

    class Meta:
        model = Note
        fields = (
            'id',
            'text',
            'performance',
            'user',
        )

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = (
            'id',
            'email',
            'username',
        )
<|endoftext|>


<commit_before># Copyright 2006 Andrey Golovizin
#
# This file is part of pybtex.
#
# pybtex is free software; you can redistribute it and/or modify
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# pybtex is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pybtex; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
# USA

try:
    import cElementTree as ET
except ImportError:
    from elementtree import ElementTree as ET
from pybtex.core import Entry, Person
from pybtex.database.input import ParserBase

bibtexns = '{http://bibtexml.sf.net/}'
file_extension = 'bibtexml'

def remove_ns(s):
    if s.startswith(bibtexns):
        return s[len(bibtexns):]

class Parser(ParserBase):
    def parse_file(self, file):
        self.entries = {}
        t = ET.parse(file)
        for entry in t.findall(bibtexns + 'entry'):
            self.process_entry(entry)
        return self.entries

    def process_entry(self, entry):
        def process_person(person_entry, role):
            persons = person_entry.findall(bibtexns + 'person')
            if persons:
                for person in persons:
                    process_person(person, role)
            else:
                text = person_entry.text.strip()
                if text:
                    e.add_person(Person(text), role)
                else:
                    names = {}
                    for name in person_entry.getchildren():
                        names[remove_ns(name.tag)] = name.text
                    e.add_person(Person(**names), role)

        id_ = entry.get('id')
        item = entry.getchildren()[0]
        type = remove_ns(item.tag)
        e = Entry(type)
        for field in item.getchildren():
            field_name = remove_ns(field.tag)
            if field_name in Person.valid_roles:
                process_person(field, field_name)
            else:
                e.fields[field_name] = field.text.strip()
        self.entries[id_] = e
<commit_msg>try to import xml.etree (python-2.5) if ElementTree is not present<commit_after># Copyright 2006 Andrey Golovizin
#
# This file is part of pybtex.
#
# pybtex is free software; you can redistribute it and/or modify
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# pybtex is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pybtex; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
# USA

try:
    import cElementTree as ET
except ImportError:
    try:
        from elementtree import ElementTree as ET
    except ImportError:
        from xml.etree import ElementTree as ET
from pybtex.core import Entry, Person
from pybtex.database.input import ParserBase

bibtexns = '{http://bibtexml.sf.net/}'
file_extension = 'bibtexml'

def remove_ns(s):
    if s.startswith(bibtexns):
        return s[len(bibtexns):]

class Parser(ParserBase):
    def parse_file(self, file):
        self.entries = {}
        t = ET.parse(file)
        for entry in t.findall(bibtexns + 'entry'):
            self.process_entry(entry)
        return self.entries

    def process_entry(self, entry):
        def process_person(person_entry, role):
            persons = person_entry.findall(bibtexns + 'person')
            if persons:
                for person in persons:
                    process_person(person, role)
            else:
                text = person_entry.text.strip()
                if text:
                    e.add_person(Person(text), role)
                else:
                    names = {}
                    for name in person_entry.getchildren():
                        names[remove_ns(name.tag)] = name.text
                    e.add_person(Person(**names), role)

        id_ = entry.get('id')
        item = entry.getchildren()[0]
        type = remove_ns(item.tag)
        e = Entry(type)
        for field in item.getchildren():
            field_name = remove_ns(field.tag)
            if field_name in Person.valid_roles:
                process_person(field, field_name)
            else:
                e.fields[field_name] = field.text.strip()
        self.entries[id_] = e
<|endoftext|>


<commit_before>"""
Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
"""

import subprocess
import filecmp
import os
import nose.tools
import json

from conf import const

def print_debug_msg(sid=0, msg=""):
    """
    provide general print interface
    """
    print "@%d======================%s" % (sid, msg)

def exe_and_check_res(cmd):
    """
    execute cmd and check result
    """

    print cmd
    ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    nose.tools.assert_equal(ret.stderr.readlines(), [])

def clear_env():
    """
    clear env
    """

    print_debug_msg(4, "delete table_test001 and table_test002, clear env")

    cmd = "./teracli disable table_test001"
    exe_and_check_res(cmd)

    cmd = "./teracli drop table_test001"
    exe_and_check_res(cmd)

    cmd = "./teracli disable table_test002"
    exe_and_check_res(cmd)

    cmd = "./teracli drop table_test002"
    exe_and_check_res(cmd)

def cleanup():
    ret = subprocess.Popen(const.teracli_binary + ' disable test',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())
    ret = subprocess.Popen(const.teracli_binary + ' drop test',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

    files = os.listdir('.')
    for f in files:
        if f.endswith('.out'):
            os.remove(f)

def cluster_op(op):
    if op == 'kill':
        print 'kill cluster'
        ret = subprocess.Popen(const.kill_script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())
    elif op == 'launch':
        print 'launch cluster'
        ret = subprocess.Popen(const.launch_script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())
    else:
        print 'unknown argument'
        nose.tools.assert_true(False)

def create_kv_table():
    print 'print kv table'
    cleanup()
    ret = subprocess.Popen(const.teracli_binary + ' create test', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def create_singleversion_table():
    print 'print single version table'
    cleanup()
    ret = subprocess.Popen(const.teracli_binary + ' create "test{cf0, cf1}"',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def create_multiversion_table():
    print 'print multi version table'
    cleanup()
    ret = subprocess.Popen(const.teracli_binary + ' create "test{cf0<maxversions=20>, cf1<maxversions=20>}"',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def run_tera_mark(file_path, op, table_name, random, value_size, num, key_size, cf='', key_seed=1, value_seed=1):
    """
    This function provide means to write data into Tera and dump a copy into a specified file at the same time.
    :param file_path: a copy of data will be dumped into file_path for future use
    :param op: ['w' | 'd'], 'w' indicates write and 'd' indicates delete
    :param table_name: table name
    :param random: ['random' | 'seq']
    :param value_size: value size in Bytes
    :param num: entry number
    :param key_size: key size in Bytes
    :param cf: cf list, e.g. 'cf0:qual,cf1:flag'. Empty cf list for kv mode. Notice: no space in between
    :param key_seed: seed for random key generator
    :param value_seed: seed for random value generator
    :return: None
    """

    # write data into Tera
    tera_bench_args = ""
    awk_args = ""

    if cf == '':  # kv mode
        tera_bench_args += """--compression_ratio=1 --key_seed={kseed} --value_seed={vseed} """\
                           """ --value_size={vsize} --num={num} --benchmarks={random} """\
                           """ --key_size={ksize} """.format(kseed=key_seed, vseed=value_seed,
                                                             vsize=value_size, num=num, random=random, ksize=key_size)
        if op == 'd':  # delete
            awk_args += """-F '\t' '{print $1}'"""
        else:  # write
            awk_args += """-F '\t' '{print $1"\t"$2}'"""
    else:  # table
        tera_bench_args += """--cf={cf} --compression_ratio=1 --key_seed={kseed} --value_seed={vseed} """\
                           """ --value_size={vsize} --num={num} --benchmarks={random} """\
                           """ --key_size={ksize} """.format(cf=cf, kseed=key_seed, vseed=value_seed,
                                                             vsize=value_size, num=num, random=random, ksize=key_size)
        if op == 'd':  # delete
            awk_args += """-F '\t' '{print $1"\t"$3"\t"$4}'"""
        else:  # write
            awk_args += """-F '\t' '{print $1"\t"$2"\t"$3"\t"$4}'"""

    tera_mark_args = """--mode={op} --tablename={table_name} --type=async """\
                     """ --verify=false""".format(op=op, table_name=table_name)

    cmd = '{tera_bench} {bench_args} | awk {awk_args} | {tera_mark} {mark_args}'.format(
        tera_bench=const.tera_bench_binary, bench_args=tera_bench_args, awk_args=awk_args,
        tera_mark=const.tera_mark_binary, mark_args=tera_mark_args)

    print cmd
    ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

    # write/append data to a file for comparison
    for path, is_append in file_path:
        if cf == '':
            awk_args = """-F '\t' '{print $1"::0:"$2}'"""
        else:
            awk_args = """-F '\t' '{print $1":"$3":"$4":"$2}'"""

        redirect_op = ''
        if is_append is True:
            redirect_op += '>>'
        else:
            redirect_op += '>'

        dump_cmd = '{tera_bench} {tera_bench_args} | awk {awk_args} {redirect_op} {out}'.format(
            tera_bench=const.tera_bench_binary, tera_bench_args=tera_bench_args,
            redirect_op=redirect_op, awk_args=awk_args, out=path)
        print dump_cmd
        ret = subprocess.Popen(dump_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())

def scan_table(table_name, file_path, allversion, snapshot=0):
    """
    This function scans the table and write the output into file_path
    :param table_name: table name
    :param file_path: write scan output into file_path
    :param allversion: [True | False]
    """

    allv = ''
    if allversion is True:
        allv += 'scanallv'
    else:
        allv += 'scan'

    snapshot_args = ''
    if snapshot != 0:
        snapshot_args += '--snapshot={snapshot}'.format(snapshot=snapshot)

    scan_cmd = '{teracli} {op} {table_name} "" "" {snapshot} > {out}'.format(
        teracli=const.teracli_binary, op=allv, table_name=table_name, snapshot=snapshot_args, out=file_path)
    print scan_cmd
    ret = subprocess.Popen(scan_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def get_tablet_list(table_name):
    # TODO: need a more elegant & general way to obtain tablet info
    show_cmd = '{teracli} show {table}'.format(teracli=const.teracli_binary, table=table_name)
    print show_cmd
    ret = subprocess.Popen(show_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    tablet_info = ret.stdout.readlines()[5:]  # tablet info starts from the 6th line
    tablet_info = filter(lambda x: x != '\n', tablet_info)
    tablet_paths = []
    for tablet in tablet_info:
        comp = filter(None, tablet.split(' '))
        tablet_paths.append(comp[2])
    return tablet_paths

def parse_showinfo(table, filed):
    show_cmd = '{teracli} show'.format(teracli=const.teracli_binary)
    print show_cmd
    ret = subprocess.Popen(show_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    table_info = ret.stdout.readlines()[2:-1]
    retinfo = {}
    for line in table_info:
        line = line.strip("\n")
        line_list = line.split(" ")
        list_ret = [line_list[i] for i in range(len(line_list)) if line_list[i] != ""]

        retinfo[list_ret[1]] = {}
        retinfo[list_ret[1]]["status"] = list_ret[2]
        retinfo[list_ret[1]]["size"] = list_ret[3]
        retinfo[list_ret[1]]["lg_size"] = list_ret[4]
        retinfo[list_ret[1]]["tablet"] = list_ret[5]
        retinfo[list_ret[1]]["busy"] = list_ret[6]

    #return retinfo

    print json.dumps(retinfo)

    for table_name in retinfo:
        if table_name == table:
            print retinfo[table_name][filed]
            return retinfo[table_name][filed]

def compact_tablets(tablet_list):
    # TODO: compact may timeout
    for tablet in tablet_list:
        compact_cmd = '{teracli} tablet compact {tablet}'.format(teracli=const.teracli_binary, tablet=tablet)
        print compact_cmd
        ret = subprocess.Popen(compact_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())

def snapshot_op(table_name):
    """
    This function creates | deletes a snapshot
    :param table_name: table name
    :return: snapshot id on success, None otherwise
    """
    # TODO: delete snapshot
    snapshot_cmd = '{teracli} snapshot {table_name} create'.format(teracli=const.teracli_binary, table_name=table_name)
    print snapshot_cmd
    ret = subprocess.Popen(snapshot_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    out = ret.stdout.readlines()
    ret = ''
    try:
        ret += out[1]
    except IndexError:
        return None

    if ret.startswith('new snapshot: '):
        snapshot_id = ret[len('new snapshot: '):-1]
        if snapshot_id.isdigit():
            return int(snapshot_id)
    return None

def compare_files(file1, file2, need_sort):
    """
    This function compares two files.
    :param file1: file path to the first file
    :param file2: file path to the second file
    :param need_sort: whether the files need to be sorted
    :return: True if the files are the same, False on the other hand
    """
    if need_sort is True:
        sort_cmd = 'sort {f1} > {f1}.sort; sort {f2} > {f2}.sort'.format(f1=file1, f2=file2)
        print sort_cmd
        ret = subprocess.Popen(sort_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())
        os.rename(file1+'.sort', file1)
        os.rename(file2+'.sort', file2)
    return filecmp.cmp(file1, file2)

def file_is_empty(file_path):
    """
    This function test whether a file is empty
    :param file_path: file path
    :return: True if the file is empty, False on the other hand
    """
    return not os.path.getsize(file_path)

def cleanup_files(file_list):
    for file_path in file_list:
        os.remove(file_path)

<commit_msg>#391 modify<commit_after>"""
Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
"""

import subprocess
import filecmp
import os
import nose.tools
import json

from conf import const

def print_debug_msg(sid=0, msg=""):
    """
    provide general print interface
    """
    print "@%d======================%s" % (sid, msg)

def exe_and_check_res(cmd):
    """
    execute cmd and check result
    """

    print cmd
    ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    nose.tools.assert_equal(ret.stderr.readlines(), [])

def clear_env():
    """
    clear env
    """

    print_debug_msg(4, "delete table_test001 and table_test002, clear env")

    cmd = "./teracli disable table_test001"
    exe_and_check_res(cmd)

    cmd = "./teracli drop table_test001"
    exe_and_check_res(cmd)

    cmd = "./teracli disable table_test002"
    exe_and_check_res(cmd)

    cmd = "./teracli drop table_test002"
    exe_and_check_res(cmd)

def cleanup():
    ret = subprocess.Popen(const.teracli_binary + ' disable test',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())
    ret = subprocess.Popen(const.teracli_binary + ' drop test',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

    files = os.listdir('.')
    for f in files:
        if f.endswith('.out'):
            os.remove(f)

def cluster_op(op):
    if op == 'kill':
        print 'kill cluster'
        ret = subprocess.Popen(const.kill_script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())
    elif op == 'launch':
        print 'launch cluster'
        ret = subprocess.Popen(const.launch_script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())
    else:
        print 'unknown argument'
        nose.tools.assert_true(False)

def create_kv_table():
    print 'print kv table'
    cleanup()
    ret = subprocess.Popen(const.teracli_binary + ' create test', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def create_singleversion_table():
    print 'print single version table'
    cleanup()
    ret = subprocess.Popen(const.teracli_binary + ' create "test{cf0, cf1}"',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def create_multiversion_table():
    print 'print multi version table'
    cleanup()
    ret = subprocess.Popen(const.teracli_binary + ' create "test{cf0<maxversions=20>, cf1<maxversions=20>}"',
                           stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def run_tera_mark(file_path, op, table_name, random, value_size, num, key_size, cf='', key_seed=1, value_seed=1):
    """
    This function provide means to write data into Tera and dump a copy into a specified file at the same time.
    :param file_path: a copy of data will be dumped into file_path for future use
    :param op: ['w' | 'd'], 'w' indicates write and 'd' indicates delete
    :param table_name: table name
    :param random: ['random' | 'seq']
    :param value_size: value size in Bytes
    :param num: entry number
    :param key_size: key size in Bytes
    :param cf: cf list, e.g. 'cf0:qual,cf1:flag'. Empty cf list for kv mode. Notice: no space in between
    :param key_seed: seed for random key generator
    :param value_seed: seed for random value generator
    :return: None
    """

    # write data into Tera
    tera_bench_args = ""
    awk_args = ""

    if cf == '':  # kv mode
        tera_bench_args += """--compression_ratio=1 --key_seed={kseed} --value_seed={vseed} """\
                           """ --value_size={vsize} --num={num} --benchmarks={random} """\
                           """ --key_size={ksize} """.format(kseed=key_seed, vseed=value_seed,
                                                             vsize=value_size, num=num, random=random, ksize=key_size)
        if op == 'd':  # delete
            awk_args += """-F '\t' '{print $1}'"""
        else:  # write
            awk_args += """-F '\t' '{print $1"\t"$2}'"""
    else:  # table
        tera_bench_args += """--cf={cf} --compression_ratio=1 --key_seed={kseed} --value_seed={vseed} """\
                           """ --value_size={vsize} --num={num} --benchmarks={random} """\
                           """ --key_size={ksize} """.format(cf=cf, kseed=key_seed, vseed=value_seed,
                                                             vsize=value_size, num=num, random=random, ksize=key_size)
        if op == 'd':  # delete
            awk_args += """-F '\t' '{print $1"\t"$3"\t"$4}'"""
        else:  # write
            awk_args += """-F '\t' '{print $1"\t"$2"\t"$3"\t"$4}'"""

    tera_mark_args = """--mode={op} --tablename={table_name} --type=async """\
                     """ --verify=false""".format(op=op, table_name=table_name)

    cmd = '{tera_bench} {bench_args} | awk {awk_args} | {tera_mark} {mark_args}'.format(
        tera_bench=const.tera_bench_binary, bench_args=tera_bench_args, awk_args=awk_args,
        tera_mark=const.tera_mark_binary, mark_args=tera_mark_args)

    print cmd
    ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

    # write/append data to a file for comparison
    for path, is_append in file_path:
        if cf == '':
            awk_args = """-F '\t' '{print $1"::0:"$2}'"""
        else:
            awk_args = """-F '\t' '{print $1":"$3":"$4":"$2}'"""

        redirect_op = ''
        if is_append is True:
            redirect_op += '>>'
        else:
            redirect_op += '>'

        dump_cmd = '{tera_bench} {tera_bench_args} | awk {awk_args} {redirect_op} {out}'.format(
            tera_bench=const.tera_bench_binary, tera_bench_args=tera_bench_args,
            redirect_op=redirect_op, awk_args=awk_args, out=path)
        print dump_cmd
        ret = subprocess.Popen(dump_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())

def scan_table(table_name, file_path, allversion, snapshot=0):
    """
    This function scans the table and write the output into file_path
    :param table_name: table name
    :param file_path: write scan output into file_path
    :param allversion: [True | False]
    """

    allv = ''
    if allversion is True:
        allv += 'scanallv'
    else:
        allv += 'scan'

    snapshot_args = ''
    if snapshot != 0:
        snapshot_args += '--snapshot={snapshot}'.format(snapshot=snapshot)

    scan_cmd = '{teracli} {op} {table_name} "" "" {snapshot} > {out}'.format(
        teracli=const.teracli_binary, op=allv, table_name=table_name, snapshot=snapshot_args, out=file_path)
    print scan_cmd
    ret = subprocess.Popen(scan_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    print ''.join(ret.stdout.readlines())

def get_tablet_list(table_name):
    # TODO: need a more elegant & general way to obtain tablet info
    show_cmd = '{teracli} show {table}'.format(teracli=const.teracli_binary, table=table_name)
    print show_cmd
    ret = subprocess.Popen(show_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    tablet_info = ret.stdout.readlines()[5:]  # tablet info starts from the 6th line
    tablet_info = filter(lambda x: x != '\n', tablet_info)
    tablet_paths = []
    for tablet in tablet_info:
        comp = filter(None, tablet.split(' '))
        tablet_paths.append(comp[2])
    return tablet_paths

def parse_showinfo(table, filed):
    '''
    if you want get the size of table 'test',
    then you can call this function, ret = parse_showinfo('test', 'size')
    '''
    show_cmd = '{teracli} show'.format(teracli=const.teracli_binary)
    print show_cmd
    ret = subprocess.Popen(show_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    table_info = ret.stdout.readlines()[2:-1]
    retinfo = {}
    for line in table_info:
        line = line.strip("\n")
        line_list = line.split(" ")
        list_ret = [line_list[i] for i in range(len(line_list)) if line_list[i] != ""]

        retinfo[list_ret[1]] = {}
        retinfo[list_ret[1]]["status"] = list_ret[2]
        retinfo[list_ret[1]]["size"] = list_ret[3]
        retinfo[list_ret[1]]["lg_size"] = list_ret[4]
        retinfo[list_ret[1]]["tablet"] = list_ret[5]
        retinfo[list_ret[1]]["busy"] = list_ret[6]

    #return retinfo

    print json.dumps(retinfo)

    for table_name in retinfo:
        if table_name == table:
            print retinfo[table_name][filed]
            return retinfo[table_name][filed]

def compact_tablets(tablet_list):
    # TODO: compact may timeout
    for tablet in tablet_list:
        compact_cmd = '{teracli} tablet compact {tablet}'.format(teracli=const.teracli_binary, tablet=tablet)
        print compact_cmd
        ret = subprocess.Popen(compact_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())

def snapshot_op(table_name):
    """
    This function creates | deletes a snapshot
    :param table_name: table name
    :return: snapshot id on success, None otherwise
    """
    # TODO: delete snapshot
    snapshot_cmd = '{teracli} snapshot {table_name} create'.format(teracli=const.teracli_binary, table_name=table_name)
    print snapshot_cmd
    ret = subprocess.Popen(snapshot_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    out = ret.stdout.readlines()
    ret = ''
    try:
        ret += out[1]
    except IndexError:
        return None

    if ret.startswith('new snapshot: '):
        snapshot_id = ret[len('new snapshot: '):-1]
        if snapshot_id.isdigit():
            return int(snapshot_id)
    return None

def compare_files(file1, file2, need_sort):
    """
    This function compares two files.
    :param file1: file path to the first file
    :param file2: file path to the second file
    :param need_sort: whether the files need to be sorted
    :return: True if the files are the same, False on the other hand
    """
    if need_sort is True:
        sort_cmd = 'sort {f1} > {f1}.sort; sort {f2} > {f2}.sort'.format(f1=file1, f2=file2)
        print sort_cmd
        ret = subprocess.Popen(sort_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        print ''.join(ret.stdout.readlines())
        os.rename(file1+'.sort', file1)
        os.rename(file2+'.sort', file2)
    return filecmp.cmp(file1, file2)

def file_is_empty(file_path):
    """
    This function test whether a file is empty
    :param file_path: file path
    :return: True if the file is empty, False on the other hand
    """
    return not os.path.getsize(file_path)

def cleanup_files(file_list):
    for file_path in file_list:
        os.remove(file_path)

<|endoftext|>


<commit_before># ===============================================================================
# Copyright 2013 Jake Ross
#
# 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.
# ===============================================================================

# ============= enthought library imports =======================

from pyface.tasks.task_window_layout import TaskWindowLayout
from traits.api import Any, List
from pyface.action.action import Action
from pyface.tasks.action.task_action import TaskAction
from pyface.confirmation_dialog import confirm
from pyface.constant import YES
# ============= standard library imports ========================
import os
import shutil
import sys
# ============= local library imports  ==========================
from pychron.envisage.resources import icon

# from pychron.processing.tasks.actions.processing_actions import myTaskAction

# ===============================================================================
# help
# ===============================================================================
from pychron.envisage.user_login import login_file

def restart():
    os.execl(sys.executable, *([sys.executable] + sys.argv))

def get_key_binding(k_id):
    from pychron.envisage.key_bindings import user_key_map

    try:
        return user_key_map[k_id][0]
    except KeyError:
        pass

class myTaskAction(TaskAction):
    task_ids = List

    def _task_changed(self):
        if self.task:
            if self.task.id in self.task_ids:
                enabled = True
                if self.enabled_name:
                    if self.object:
                        enabled = bool(self._get_attr(self.object,
                                                      self.enabled_name, False))
                if enabled:
                    self._enabled = True
            else:
                self._enabled = False

    def _enabled_update(self):
        """
             reimplement ListeningAction's _enabled_update
        """
        if self.enabled_name:
            if self.object:
                self.enabled = bool(self._get_attr(self.object,
                                                   self.enabled_name, False))
            else:
                self.enabled = False
        elif self._enabled is not None:
            self.enabled = self._enabled
        else:
            self.enabled = bool(self.object)

class PAction(Action):
    def __init__(self, *args, **kw):
        super(PAction, self).__init__(*args, **kw)
        acc = get_key_binding(self.id)
        self.accelerator = acc or self.accelerator

class PTaskAction(TaskAction):
    def __init__(self, *args, **kw):
        super(PTaskAction, self).__init__(*args, **kw)
        acc = get_key_binding(self.id)
        self.accelerator = acc or self.accelerator

class DemoAction(Action):
    name = 'Demo'
    accelerator = 'Shift+Ctrl+0'

    def perform(self, event):
        app = event.task.application
        app.info('Demo message: {}'.format('Hello version 1.6'))

class StartupTestsAction(Action):
    name = 'Run Startup Tests'
    def perform(self, event):
        app = event.task.application
        from pychron.globals import globalv

        ov = globalv.use_startup_tests
        globalv.use_startup_tests = True

        for plugin in app.plugin_manager:
            if hasattr(plugin, 'startup_test'):
                plugin.startup_test()

        globalv.use_startup_tests = ov

        st = app.startup_tester
        if st.results:
            from pychron.startup_test.results_view import ResultsView

            v = ResultsView(model=st,
                            _cancel_auto_close=True,
                            can_cancel=False)
            app.open_view(v)

class KeyBindingsAction(PAction):
    name = 'Edit Key Bindings'

    def perform(self, event):
        from pychron.envisage.key_bindings import edit_key_bindings

        edit_key_bindings()

class UserAction(PAction):
    def _get_current_user(self, event):
        app = event.task.application
        args = app.id.split('.')
        cuser = args[-1]
        base_id = '.'.join(args[:-1])
        return base_id, cuser

class SwitchUserAction(UserAction):
    name = 'Switch User'
    image = icon('user_suit')

    def perform(self, event):
        from pychron.envisage.user_login import get_user

        base_id, cuser = self._get_current_user(event)
        user = get_user(current=cuser)
        if user:
            # from pychron.paths import paths
            # set login file
            with open(login_file, 'w') as fp:
                fp.write(user)
            restart()

class CopyPreferencesAction(UserAction):
    name = 'Copy Preferences'

    def perform(self, event):
        from pychron.envisage.user_login import get_src_dest_user

        base_id, cuser = self._get_current_user(event)
        src_name, dest_names = get_src_dest_user(cuser)

        if src_name:

            for di in dest_names:
                dest_id = '{}.{}'.format(base_id, di)
                src_id = '{}.{}'.format(base_id, src_name)

                root = os.path.join(os.path.expanduser('~'), '.enthought')

                src_dir = os.path.join(root, src_id)
                dest_dir = os.path.join(root, dest_id)
                if not os.path.isdir(dest_dir):
                    os.mkdir(dest_dir)

                name = 'preferences.ini'
                dest = os.path.join(dest_dir, name)
                src = os.path.join(src_dir, name)
                shutil.copyfile(src, dest)

class RestartAction(PAction):
    name = 'Restart'
    image = icon('system-restart')

    def perform(self, event):
        restart()

class WebAction(PAction):
    def _open_url(self, url):

        import webbrowser
        import urllib2

        try:
            urllib2.urlopen(url)
        except (urllib2.HTTPError, urllib2.URLError):
            return

        webbrowser.open_new(url)

class IssueAction(WebAction):
    name = 'Add Request/Report Bug'
    image = icon('bug')

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        url = 'https://github.com/NMGRL/pychron/issues/new'
        self._open_url(url)

class NoteAction(WebAction):
    name = 'Add Laboratory Note'
    image = icon('insert-comment')

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        app = event.task.window.application
        name = app.preferences.get('pychron.general.remote')
        if not name:
            name = 'NMGRL/Laboratory'

        url = 'https://github.com/{}/issues/new'.format(name)
        self._open_url(url)

class DocumentationAction(WebAction):
    name = 'View Documentation'
    image = icon('documentation')

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        url = 'http://pychron.readthedocs.org/en/latest/index.html'
        self._open_url(url)

class ChangeLogAction(WebAction):
    name = "What's New"
    image = icon('documentation')
    description = 'View changelog'

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        from pychron.version import __version__
        url = 'https://github.com/NMGRL/pychron/blob/release/v{}/CHANGELOG.md'.format(__version__)
        if not self._open_url(url):
            url = 'https://github.com/NMGRL/pychron/blob/develop/CHANGELOG.md'
            self._open_url(url)

class AboutAction(PAction):
    name = 'About Pychron'

    def perform(self, event):
        app = event.task.window.application
        app.about()

class ResetLayoutAction(PTaskAction):
    name = 'Reset Layout'
    image = icon('view-restore')

    def perform(self, event):
        self.task.window.reset_layout()

class PositionAction(PAction):
    name = 'Window Positions'
    image = icon('window-new')

    def perform(self, event):
        from pychron.envisage.tasks.layout_manager import LayoutManager

        app = event.task.window.application
        lm = LayoutManager(app)
        lm.edit_traits()

class MinimizeAction(PTaskAction):
    name = 'Minimize'
    accelerator = 'Ctrl+m'

    def perform(self, event):
        app = self.task.window.application
        app.active_window.control.showMinimized()

class CloseAction(PTaskAction):
    name = 'Close'
    accelerator = 'Ctrl+W'

    def perform(self, event):
        ok = YES
        if len(self.task.window.application.windows) == 1:
            ok = confirm(self.task.window.control, message='Quit Pychron?')

        if ok == YES:
            self.task.window.close()

class CloseOthersAction(PTaskAction):
    name = 'Close others'
    accelerator = 'Ctrl+Shift+W'

    def perform(self, event):
        win = self.task.window
        for wi in self.task.window.application.windows:
            if wi != win:
                wi.close()

class OpenAdditionalWindow(PTaskAction):
    name = 'Open Additional Window'
    description = 'Open an additional window of the current active task'

    def perform(self, event):
        app = self.task.window.application
        win = app.create_window(TaskWindowLayout(self.task.id))
        win.open()

class RaiseAction(PTaskAction):
    window = Any
    style = 'toggle'

    def perform(self, event):
        self.window.activate()
        self.checked = True

    # @on_trait_change('window:deactivated')
    # def _on_deactivate(self):
    #     self.checked = False

class RaiseUIAction(PTaskAction):
    style = 'toggle'

    def perform(self, event):
        self.checked = True

class GenericSaveAction(PTaskAction):
    name = 'Save'
    accelerator = 'Ctrl+S'
    image = icon('document-save')

    def perform(self, event):
        task = self.task
        if hasattr(task, 'save'):
            task.save()

class GenericSaveAsAction(PTaskAction):
    name = 'Save As...'
    accelerator = 'Ctrl+Shift+S'
    image = icon('document-save-as')

    def perform(self, event):
        task = self.task
        if hasattr(task, 'save_as'):
            task.save_as()

class GenericFindAction(PTaskAction):
    accelerator = 'Ctrl+F'
    name = 'Find text...'

    def perform(self, event):
        task = self.task
        if hasattr(task, 'find'):
            task.find()

class FileOpenAction(PAction):
    task_id = ''
    test_path = ''
    image = icon('document-open')

    def perform(self, event):
        if event.task.id == self.task_id:
            task = event.task
            task.open()
        else:
            application = event.task.window.application
            win = application.create_window(TaskWindowLayout(self.task_id))
            task = win.active_task
            if task.open(path=self.test_path):
                win.open()

class NewAction(PAction):
    task_id = ''

    def perform(self, event):
        if event.task.id == self.task_id:
            task = event.task
            task.new()
        else:
            application = event.task.window.application
            win = application.create_window(TaskWindowLayout(self.task_id))
            task = win.active_task
            if task.new():
                win.open()

# class GenericReplaceAction(TaskAction):
#    pass
#        else:
#            manager = self._get_experimentor(event)
#            manager.save_as_experiment_queues()

class ToggleFullWindowAction(myTaskAction):
    name = 'Toggle Full Window'
    method = 'toggle_full_window'
    image = icon('view-fullscreen-8')
    task_ids = ['pychron.recall', 'pychron.labbook', 'pychron.processing.figures']

class EditInitializationAction(Action):
    name = 'Edit Initialization'
    image = icon('brick-edit')

    def perform(self, event):
        from pychron.envisage.initialization.initialization_edit_view import edit_initialization

        if edit_initialization():
            restart()

# ============= EOF =============================================
<commit_msg>bump demo action<commit_after># ===============================================================================
# Copyright 2013 Jake Ross
#
# 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.
# ===============================================================================

# ============= enthought library imports =======================

from pyface.tasks.task_window_layout import TaskWindowLayout
from traits.api import Any, List
from pyface.action.action import Action
from pyface.tasks.action.task_action import TaskAction
from pyface.confirmation_dialog import confirm
from pyface.constant import YES
# ============= standard library imports ========================
import os
import shutil
import sys
# ============= local library imports  ==========================
from pychron.envisage.resources import icon

# from pychron.processing.tasks.actions.processing_actions import myTaskAction

# ===============================================================================
# help
# ===============================================================================
from pychron.envisage.user_login import login_file

def restart():
    os.execl(sys.executable, *([sys.executable] + sys.argv))

def get_key_binding(k_id):
    from pychron.envisage.key_bindings import user_key_map

    try:
        return user_key_map[k_id][0]
    except KeyError:
        pass

class myTaskAction(TaskAction):
    task_ids = List

    def _task_changed(self):
        if self.task:
            if self.task.id in self.task_ids:
                enabled = True
                if self.enabled_name:
                    if self.object:
                        enabled = bool(self._get_attr(self.object,
                                                      self.enabled_name, False))
                if enabled:
                    self._enabled = True
            else:
                self._enabled = False

    def _enabled_update(self):
        """
             reimplement ListeningAction's _enabled_update
        """
        if self.enabled_name:
            if self.object:
                self.enabled = bool(self._get_attr(self.object,
                                                   self.enabled_name, False))
            else:
                self.enabled = False
        elif self._enabled is not None:
            self.enabled = self._enabled
        else:
            self.enabled = bool(self.object)

class PAction(Action):
    def __init__(self, *args, **kw):
        super(PAction, self).__init__(*args, **kw)
        acc = get_key_binding(self.id)
        self.accelerator = acc or self.accelerator

class PTaskAction(TaskAction):
    def __init__(self, *args, **kw):
        super(PTaskAction, self).__init__(*args, **kw)
        acc = get_key_binding(self.id)
        self.accelerator = acc or self.accelerator

class DemoAction(Action):
    name = 'Demo'
    accelerator = 'Shift+Ctrl+0'

    def perform(self, event):
        app = event.task.application
        app.info('Demo message: {}'.format('Hello version 1.7'))

class StartupTestsAction(Action):
    name = 'Run Startup Tests'
    def perform(self, event):
        app = event.task.application
        from pychron.globals import globalv

        ov = globalv.use_startup_tests
        globalv.use_startup_tests = True

        for plugin in app.plugin_manager:
            if hasattr(plugin, 'startup_test'):
                plugin.startup_test()

        globalv.use_startup_tests = ov

        st = app.startup_tester
        if st.results:
            from pychron.startup_test.results_view import ResultsView

            v = ResultsView(model=st,
                            _cancel_auto_close=True,
                            can_cancel=False)
            app.open_view(v)

class KeyBindingsAction(PAction):
    name = 'Edit Key Bindings'

    def perform(self, event):
        from pychron.envisage.key_bindings import edit_key_bindings

        edit_key_bindings()

class UserAction(PAction):
    def _get_current_user(self, event):
        app = event.task.application
        args = app.id.split('.')
        cuser = args[-1]
        base_id = '.'.join(args[:-1])
        return base_id, cuser

class SwitchUserAction(UserAction):
    name = 'Switch User'
    image = icon('user_suit')

    def perform(self, event):
        from pychron.envisage.user_login import get_user

        base_id, cuser = self._get_current_user(event)
        user = get_user(current=cuser)
        if user:
            # from pychron.paths import paths
            # set login file
            with open(login_file, 'w') as fp:
                fp.write(user)
            restart()

class CopyPreferencesAction(UserAction):
    name = 'Copy Preferences'

    def perform(self, event):
        from pychron.envisage.user_login import get_src_dest_user

        base_id, cuser = self._get_current_user(event)
        src_name, dest_names = get_src_dest_user(cuser)

        if src_name:

            for di in dest_names:
                dest_id = '{}.{}'.format(base_id, di)
                src_id = '{}.{}'.format(base_id, src_name)

                root = os.path.join(os.path.expanduser('~'), '.enthought')

                src_dir = os.path.join(root, src_id)
                dest_dir = os.path.join(root, dest_id)
                if not os.path.isdir(dest_dir):
                    os.mkdir(dest_dir)

                name = 'preferences.ini'
                dest = os.path.join(dest_dir, name)
                src = os.path.join(src_dir, name)
                shutil.copyfile(src, dest)

class RestartAction(PAction):
    name = 'Restart'
    image = icon('system-restart')

    def perform(self, event):
        restart()

class WebAction(PAction):
    def _open_url(self, url):

        import webbrowser
        import urllib2

        try:
            urllib2.urlopen(url)
        except (urllib2.HTTPError, urllib2.URLError):
            return

        webbrowser.open_new(url)

class IssueAction(WebAction):
    name = 'Add Request/Report Bug'
    image = icon('bug')

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        url = 'https://github.com/NMGRL/pychron/issues/new'
        self._open_url(url)

class NoteAction(WebAction):
    name = 'Add Laboratory Note'
    image = icon('insert-comment')

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        app = event.task.window.application
        name = app.preferences.get('pychron.general.remote')
        if not name:
            name = 'NMGRL/Laboratory'

        url = 'https://github.com/{}/issues/new'.format(name)
        self._open_url(url)

class DocumentationAction(WebAction):
    name = 'View Documentation'
    image = icon('documentation')

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        url = 'http://pychron.readthedocs.org/en/latest/index.html'
        self._open_url(url)

class ChangeLogAction(WebAction):
    name = "What's New"
    image = icon('documentation')
    description = 'View changelog'

    def perform(self, event):
        """
            goto issues page add an request or report bug
        """
        from pychron.version import __version__
        url = 'https://github.com/NMGRL/pychron/blob/release/v{}/CHANGELOG.md'.format(__version__)
        if not self._open_url(url):
            url = 'https://github.com/NMGRL/pychron/blob/develop/CHANGELOG.md'
            self._open_url(url)

class AboutAction(PAction):
    name = 'About Pychron'

    def perform(self, event):
        app = event.task.window.application
        app.about()

class ResetLayoutAction(PTaskAction):
    name = 'Reset Layout'
    image = icon('view-restore')

    def perform(self, event):
        self.task.window.reset_layout()

class PositionAction(PAction):
    name = 'Window Positions'
    image = icon('window-new')

    def perform(self, event):
        from pychron.envisage.tasks.layout_manager import LayoutManager

        app = event.task.window.application
        lm = LayoutManager(app)
        lm.edit_traits()

class MinimizeAction(PTaskAction):
    name = 'Minimize'
    accelerator = 'Ctrl+m'

    def perform(self, event):
        app = self.task.window.application
        app.active_window.control.showMinimized()

class CloseAction(PTaskAction):
    name = 'Close'
    accelerator = 'Ctrl+W'

    def perform(self, event):
        ok = YES
        if len(self.task.window.application.windows) == 1:
            ok = confirm(self.task.window.control, message='Quit Pychron?')

        if ok == YES:
            self.task.window.close()

class CloseOthersAction(PTaskAction):
    name = 'Close others'
    accelerator = 'Ctrl+Shift+W'

    def perform(self, event):
        win = self.task.window
        for wi in self.task.window.application.windows:
            if wi != win:
                wi.close()

class OpenAdditionalWindow(PTaskAction):
    name = 'Open Additional Window'
    description = 'Open an additional window of the current active task'

    def perform(self, event):
        app = self.task.window.application
        win = app.create_window(TaskWindowLayout(self.task.id))
        win.open()

class RaiseAction(PTaskAction):
    window = Any
    style = 'toggle'

    def perform(self, event):
        self.window.activate()
        self.checked = True

    # @on_trait_change('window:deactivated')
    # def _on_deactivate(self):
    #     self.checked = False

class RaiseUIAction(PTaskAction):
    style = 'toggle'

    def perform(self, event):
        self.checked = True

class GenericSaveAction(PTaskAction):
    name = 'Save'
    accelerator = 'Ctrl+S'
    image = icon('document-save')

    def perform(self, event):
        task = self.task
        if hasattr(task, 'save'):
            task.save()

class GenericSaveAsAction(PTaskAction):
    name = 'Save As...'
    accelerator = 'Ctrl+Shift+S'
    image = icon('document-save-as')

    def perform(self, event):
        task = self.task
        if hasattr(task, 'save_as'):
            task.save_as()

class GenericFindAction(PTaskAction):
    accelerator = 'Ctrl+F'
    name = 'Find text...'

    def perform(self, event):
        task = self.task
        if hasattr(task, 'find'):
            task.find()

class FileOpenAction(PAction):
    task_id = ''
    test_path = ''
    image = icon('document-open')

    def perform(self, event):
        if event.task.id == self.task_id:
            task = event.task
            task.open()
        else:
            application = event.task.window.application
            win = application.create_window(TaskWindowLayout(self.task_id))
            task = win.active_task
            if task.open(path=self.test_path):
                win.open()

class NewAction(PAction):
    task_id = ''

    def perform(self, event):
        if event.task.id == self.task_id:
            task = event.task
            task.new()
        else:
            application = event.task.window.application
            win = application.create_window(TaskWindowLayout(self.task_id))
            task = win.active_task
            if task.new():
                win.open()

# class GenericReplaceAction(TaskAction):
#    pass
#        else:
#            manager = self._get_experimentor(event)
#            manager.save_as_experiment_queues()

class ToggleFullWindowAction(myTaskAction):
    name = 'Toggle Full Window'
    method = 'toggle_full_window'
    image = icon('view-fullscreen-8')
    task_ids = ['pychron.recall', 'pychron.labbook', 'pychron.processing.figures']

class EditInitializationAction(Action):
    name = 'Edit Initialization'
    image = icon('brick-edit')

    def perform(self, event):
        from pychron.envisage.initialization.initialization_edit_view import edit_initialization

        if edit_initialization():
            restart()

# ============= EOF =============================================
<|endoftext|>