<commit_before>import time
import Queue
import socket
import logging

import signals
from stoppable import StoppableLoopThread
from packeter import packeter
from utils import big_endian_to_int as idec
from utils import recursive_int_to_big_endian
import rlp

logger = logging.getLogger(__name__)

class Peer(StoppableLoopThread):

    def __init__(self, connection, ip, port):
        super(Peer, self).__init__()
        self._connection = connection

        assert ip.count('.') == 3
        self.ip = ip
        # None if peer was created in response to external connect
        self.port = port
        self.node_id = ''
        self.response_queue = Queue.Queue()
        self.hello_received = False
        self.hello_sent = False
        self.last_valid_packet_received = time.time()
        self.last_asked_for_peers = 0
        self.last_pinged = 0

        self.recv_buffer = ''

        # connect signals

    def __repr__(self):
        return "<Peer(%s:%r)>" % (self.ip, self.port)

    def __str__(self):
        return "[{0}: {1}]".format(self.ip, self.port)

    def connection(self):
        if self.stopped():
            raise IOError("Connection was stopped")
        else:
            return self._connection

    def stop(self):
        super(Peer, self).stop()

        # shut down
        try:
            self._connection.shutdown(socket.SHUT_RDWR)
        except socket.error as e:
            logger.debug(
                "shutting down failed {0} \"{1}\"".format(repr(self), str(e)))
        self._connection.close()

    def send_packet(self, response):
        logger.debug('sending packet to {0} >>> {1}'.format(
            self, response.encode('hex')))
        self.response_queue.put(response)

    def _process_send(self):
        '''
        :return: size of processed data
        '''
        # send packet
        try:
            packet = self.response_queue.get(block=False)
        except Queue.Empty:
            packet = ''

        while packet:
            try:
                n = self.connection().send(packet)
                packet = packet[n:]
            except socket.error as e:
                logger.debug(
                    '{0}: send packet failed, {1}'
                    .format(self, str(e)))
                self.stop()
                break

        if packet:
            return len(packet)
        else:
            return 0

    def _process_recv(self):
        '''
        :return: size of processed data
        '''
        while True:
            try:
                self.recv_buffer += self.connection().recv(2048)
            except socket.error:
                break
        length = len(self.recv_buffer)
        if length:
            self._process_recv_buffer()
        return length

    def _process_recv_buffer(self):
        try:
            cmd, data, self.recv_buffer = packeter.load_cmd(self.recv_buffer)
        except Exception as e:
            self.recv_buffer = ''
            logger.warn(e)
            return self.send_Disconnect(reason='Bad protocol')

        # good peer
        self.last_valid_packet_received = time.time()

        logger.debug('receive from {0} <<< cmd: {1}: data: {2}'.format(
            self, cmd,
            rlp.encode(recursive_int_to_big_endian(data)).encode('hex')
        ))

        func_name = "_recv_{0}".format(cmd)
        if not hasattr(self, func_name):
            logger.warn('unknown cmd \'{0}\''.format(func_name))
            return

        getattr(self, func_name)(data)

    def send_Hello(self):
        self.send_packet(packeter.dump_Hello())
        self.hello_sent = True

    def _recv_Hello(self, data):
        # check compatibility
        peer_protocol_version = idec(data[0])

        logger.debug('received Hello protocol_version:{0:#04x}'.format(
                     peer_protocol_version))

        if peer_protocol_version != packeter.PROTOCOL_VERSION:
            return self.send_Disconnect(
                reason='Incompatible network protocols'
                'expected:{0:#04x} received:{1:#04x}'.format(
                    packeter.PROTOCOL_VERSION, peer_protocol_version))

        if idec(data[1]) != packeter.NETWORK_ID:
            return self.send_Disconnect(reason='Wrong genesis block')

        # TODO add to known peers list
        self.hello_received = True
        if len(data) == 6:
            self.node_id = data[5]

        # reply with hello if not send
        if not self.hello_sent:
            self.send_Hello()

        signals.peer_handshake_success.send(sender=self)

    def send_Ping(self):
        self.send_packet(packeter.dump_Ping())
        self.last_pinged = time.time()

    def _recv_Ping(self, data):
        self.send_Pong()

    def send_Pong(self):
        self.send_packet(packeter.dump_Pong())

    def _recv_Pong(self, data):
        self.send_GetTransactions()  # FIXME

    def send_Disconnect(self, reason=None):
        logger.info('disconnecting {0}, reason: {1}'.format(
            str(self), reason or ''))
        self.send_packet(packeter.dump_Disconnect())
        # end connection
        time.sleep(2)
        signals.peer_disconnect_requested.send(self)

    def _recv_Disconnect(self, data):
        if len(data):
            reason = packeter.disconnect_reasons_map_by_id[idec(data[0])]
            logger.info('{0} sent disconnect, {1} '.format(repr(self), reason))
        signals.peer_disconnect_requested.send(sender=self)

    def send_GetPeers(self):
        self.send_packet(packeter.dump_GetPeers())

    def _recv_GetPeers(self, data):
        signals.request_data_async(
            'known_peer_addresses', data, self.send_Peers)

    def send_Peers(self, peers):
        packet = packeter.dump_Peers(peers)
        if packet:
            self.send_packet(packet)

    def _recv_Peers(self, data):
        for ip, port, pid in data:
            assert isinstance(ip, list)
            ip = '.'.join(str(ord(b or '\x00')) for b in ip)
            port = idec(port)
            logger.debug('received peer address: {0}:{1}'.format(ip, port))
            signals.peer_address_received.send(
                sender=self, peer=[ip, port, pid])

    def send_GetTransactions(self):
        logger.info('asking for transactions')
        self.send_packet(packeter.dump_GetTransactions())

    def _recv_GetTransactions(self, data):
        logger.info('asking for transactions')
        signals.request_data_async('local_transactions', data,
                                   self.send_Transactions)

    def send_Transactions(self, transactions):
        self.send_packet(packeter.dump_Transactions(transactions))

    def _recv_Transactions(self, data):
        logger.info('received transactions #%d', len(data))
        signals.remote_transactions_received.send(
            sender=self, transactions=data)

    def send_Blocks(self, blocks):
        self.send_packet(packeter.dump_Blocks(blocks))

    def _recv_Blocks(self, data):
        signals.remote_blocks_received.send(sender=self, block_lst=data)

    def send_GetChain(self, parents=[], count=1):
        self.send_packet(packeter.dump_GetChain(parents, count))

    def _recv_GetChain(self, data):
        """
        [0x14, Parent1, Parent2, ..., ParentN, Count]
        Request the peer to send Count (to be interpreted as an integer) blocks
        in the current canonical block chain that are children of Parent1
        (to be interpreted as a SHA3 block hash). If Parent1 is not present in
        the block chain, it should instead act as if the request were for Parent2 &c.
        through to ParentN. If the designated parent is the present block chain head,
        an empty reply should be sent. If none of the parents are in the current
        canonical block chain, then NotInChain should be sent along with ParentN
        (i.e. the last Parent in the parents list). If no parents are passed, then
        reply need not be made.
        """
        signals.local_chain_requested.send(
            sender=self, blocks=data[:-1], count=idec(data[-1]))

    def send_NotInChain(self, block_hash):
        self.send_packet(packeter.dump_NotInChain(block_hash))

    def _recv_NotInChain(self, data):
        pass

    def loop_body(self):
        try:
            send_size = self._process_send()
            recv_size = self._process_recv()
        except IOError:
            self.stop()
            return
        # pause
        if not (send_size or recv_size):
            time.sleep(0.1)
<commit_msg>fix: dont request tx on pong<commit_after>import time
import Queue
import socket
import logging

import signals
from stoppable import StoppableLoopThread
from packeter import packeter
from utils import big_endian_to_int as idec
from utils import recursive_int_to_big_endian
import rlp

logger = logging.getLogger(__name__)

class Peer(StoppableLoopThread):

    def __init__(self, connection, ip, port):
        super(Peer, self).__init__()
        self._connection = connection

        assert ip.count('.') == 3
        self.ip = ip
        # None if peer was created in response to external connect
        self.port = port
        self.node_id = ''
        self.response_queue = Queue.Queue()
        self.hello_received = False
        self.hello_sent = False
        self.last_valid_packet_received = time.time()
        self.last_asked_for_peers = 0
        self.last_pinged = 0

        self.recv_buffer = ''

        # connect signals

    def __repr__(self):
        return "<Peer(%s:%r)>" % (self.ip, self.port)

    def __str__(self):
        return "[{0}: {1}]".format(self.ip, self.port)

    def connection(self):
        if self.stopped():
            raise IOError("Connection was stopped")
        else:
            return self._connection

    def stop(self):
        super(Peer, self).stop()

        # shut down
        try:
            self._connection.shutdown(socket.SHUT_RDWR)
        except socket.error as e:
            logger.debug(
                "shutting down failed {0} \"{1}\"".format(repr(self), str(e)))
        self._connection.close()

    def send_packet(self, response):
        logger.debug('sending packet to {0} >>> {1}'.format(
            self, response.encode('hex')))
        self.response_queue.put(response)

    def _process_send(self):
        '''
        :return: size of processed data
        '''
        # send packet
        try:
            packet = self.response_queue.get(block=False)
        except Queue.Empty:
            packet = ''

        while packet:
            try:
                n = self.connection().send(packet)
                packet = packet[n:]
            except socket.error as e:
                logger.debug(
                    '{0}: send packet failed, {1}'
                    .format(self, str(e)))
                self.stop()
                break

        if packet:
            return len(packet)
        else:
            return 0

    def _process_recv(self):
        '''
        :return: size of processed data
        '''
        while True:
            try:
                self.recv_buffer += self.connection().recv(2048)
            except socket.error:
                break
        length = len(self.recv_buffer)
        if length:
            self._process_recv_buffer()
        return length

    def _process_recv_buffer(self):
        try:
            cmd, data, self.recv_buffer = packeter.load_cmd(self.recv_buffer)
        except Exception as e:
            self.recv_buffer = ''
            logger.warn(e)
            return self.send_Disconnect(reason='Bad protocol')

        # good peer
        self.last_valid_packet_received = time.time()

        logger.debug('receive from {0} <<< cmd: {1}: data: {2}'.format(
            self, cmd,
            rlp.encode(recursive_int_to_big_endian(data)).encode('hex')
        ))

        func_name = "_recv_{0}".format(cmd)
        if not hasattr(self, func_name):
            logger.warn('unknown cmd \'{0}\''.format(func_name))
            return

        getattr(self, func_name)(data)

    def send_Hello(self):
        self.send_packet(packeter.dump_Hello())
        self.hello_sent = True

    def _recv_Hello(self, data):
        # check compatibility
        peer_protocol_version = idec(data[0])

        logger.debug('received Hello protocol_version:{0:#04x}'.format(
                     peer_protocol_version))

        if peer_protocol_version != packeter.PROTOCOL_VERSION:
            return self.send_Disconnect(
                reason='Incompatible network protocols'
                'expected:{0:#04x} received:{1:#04x}'.format(
                    packeter.PROTOCOL_VERSION, peer_protocol_version))

        if idec(data[1]) != packeter.NETWORK_ID:
            return self.send_Disconnect(reason='Wrong genesis block')

        # TODO add to known peers list
        self.hello_received = True
        if len(data) == 6:
            self.node_id = data[5]

        # reply with hello if not send
        if not self.hello_sent:
            self.send_Hello()

        signals.peer_handshake_success.send(sender=self)

    def send_Ping(self):
        self.send_packet(packeter.dump_Ping())
        self.last_pinged = time.time()

    def _recv_Ping(self, data):
        self.send_Pong()

    def send_Pong(self):
        self.send_packet(packeter.dump_Pong())

    def _recv_Pong(self, data):
        pass

    def send_Disconnect(self, reason=None):
        logger.info('disconnecting {0}, reason: {1}'.format(
            str(self), reason or ''))
        self.send_packet(packeter.dump_Disconnect())
        # end connection
        time.sleep(2)
        signals.peer_disconnect_requested.send(self)

    def _recv_Disconnect(self, data):
        if len(data):
            reason = packeter.disconnect_reasons_map_by_id[idec(data[0])]
            logger.info('{0} sent disconnect, {1} '.format(repr(self), reason))
        signals.peer_disconnect_requested.send(sender=self)

    def send_GetPeers(self):
        self.send_packet(packeter.dump_GetPeers())

    def _recv_GetPeers(self, data):
        signals.request_data_async(
            'known_peer_addresses', data, self.send_Peers)

    def send_Peers(self, peers):
        packet = packeter.dump_Peers(peers)
        if packet:
            self.send_packet(packet)

    def _recv_Peers(self, data):
        for ip, port, pid in data:
            assert isinstance(ip, list)
            ip = '.'.join(str(ord(b or '\x00')) for b in ip)
            port = idec(port)
            logger.debug('received peer address: {0}:{1}'.format(ip, port))
            signals.peer_address_received.send(
                sender=self, peer=[ip, port, pid])

    def send_GetTransactions(self):
        logger.info('asking for transactions')
        self.send_packet(packeter.dump_GetTransactions())

    def _recv_GetTransactions(self, data):
        logger.info('asking for transactions')
        signals.request_data_async('local_transactions', data,
                                   self.send_Transactions)

    def send_Transactions(self, transactions):
        self.send_packet(packeter.dump_Transactions(transactions))

    def _recv_Transactions(self, data):
        logger.info('received transactions #%d', len(data))
        signals.remote_transactions_received.send(
            sender=self, transactions=data)

    def send_Blocks(self, blocks):
        self.send_packet(packeter.dump_Blocks(blocks))

    def _recv_Blocks(self, data):
        signals.remote_blocks_received.send(sender=self, block_lst=data)

    def send_GetChain(self, parents=[], count=1):
        self.send_packet(packeter.dump_GetChain(parents, count))

    def _recv_GetChain(self, data):
        """
        [0x14, Parent1, Parent2, ..., ParentN, Count]
        Request the peer to send Count (to be interpreted as an integer) blocks
        in the current canonical block chain that are children of Parent1
        (to be interpreted as a SHA3 block hash). If Parent1 is not present in
        the block chain, it should instead act as if the request were for Parent2 &c.
        through to ParentN. If the designated parent is the present block chain head,
        an empty reply should be sent. If none of the parents are in the current
        canonical block chain, then NotInChain should be sent along with ParentN
        (i.e. the last Parent in the parents list). If no parents are passed, then
        reply need not be made.
        """
        signals.local_chain_requested.send(
            sender=self, blocks=data[:-1], count=idec(data[-1]))

    def send_NotInChain(self, block_hash):
        self.send_packet(packeter.dump_NotInChain(block_hash))

    def _recv_NotInChain(self, data):
        pass

    def loop_body(self):
        try:
            send_size = self._process_send()
            recv_size = self._process_recv()
        except IOError:
            self.stop()
            return
        # pause
        if not (send_size or recv_size):
            time.sleep(0.1)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Fri Dec 28 13:14:26 2012

@author: Preston
"""

from Queue import Queue

class Rule(object):
    """Creates a new rule object which, when passed into the RuleGenerator,
    will generate code based off given commands and parametres"""
    def __init__(self, name, triggers, script):
        """name: a simple name to easily identify a rule

        trigger: card or phrase that invokes the rule

        commands is a multi-lined script like the following:

        Logic:
            if True:
                Set dog to 'bark!'
                if dog == None
                    Remove dog
            elif False:
                Replace cat with dog
            else:
                Print 'There is no logic'

        Commands:
            Set word to 'World!'
            Set something to Any-Player say Anything
            New Card to Current-Player where rank = None, suit = 'Joker'
            Replace this with that
            3rd-Player and Last-Player say 'Hello' + word * 2 in 5 seconds
            Next-Player or Previous-Player play King of Hearts //Can we do or?
            Random-Player play Hearts         //Just match suit
            Any-Player play 5                 //Just match rank
            Call awesome_rule                 /Referred to by name attribute
            Set Order to 7

            The Say/Play commands are the deepest ones, offering the following
            features:
                *Multiple player listings (Just use 'and' or 'or')
                *Relative player choice (First, Last, Next, Random)
                *Specific player choice (3rd player (Think like 3 next players))
                *Action multipliers (Have to say/phrase something more than once)
                *Timers (How long until punished for not doing the action)
            Please note the player(s) are first, not the command, unlike the
            other commands. This is to allow smooth semantics.

            Things in quotes are strings, lowerscore-only words are
            User-Variables, and Capitalised words are Commands/Dynamic-Variables
            (Variables dependent on exterior knowlege, like the current player)

            The extra words (to, with, in, etc.) is the delimiter between parametres
        """
        self.name = name
        if triggers:
            self.triggers = tuple(triggers)
        else:
            self.triggers = ()
        self.script = script#Used to be commands/actions
        #So that other if's can be nested as well!
        self.play_queue = Queue()
        self.say_queue = Queue()

if __name__ == '__main__':
    raise NotImplementedError, 'I have yet to rewrite the code generation in RuleGenerator for the sexy scripting language'
<commit_msg>Update the Rule doc strings to prepare for the change to a less secure way to handle rules<commit_after># -*- coding: utf-8 -*-
"""
Created on Fri Dec 28 13:14:26 2012

@author: Preston
"""

from Queue import Queue

class Rule(object):
    """Creates a new rule object which, has a name (for identification),
    triggers (to indicate when the script will execute), and a script,
    which is some executable python code, whether it is a function, lambda,
    compiled code object, or even an entire object (with enough hacking).
    The only requriement for the script is that there is only one parametre
    that will represent the entire Server object"""
    def __init__(self, name, triggers, script):
        """
        name -- a simple name to easily identify a rule

        trigger -- card or phrase that invokes the rule

        commands -- executable python code. Either a lambda, function, compiled
        code object, or class. The only requriement is that it takes one
        parametre, which will represnt the Server

        """
        assert type(name) == str
        self.name = name
        if triggers:
            self.triggers = tuple(triggers)
        else:
            self.triggers = ()
        self.script = script
        self.play_queue = Queue()
        self.say_queue = Queue()

if __name__ == '__main__':

<|endoftext|>


<commit_before>from PyQt4 import QtCore, QtGui, Qt

from lib.misc import Application
from lib.services.service import UserService
from lib.models.model import User
from ui.views.profiles import Ui_Profiles

class ProfilesForm(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Profiles()
        self.ui.setupUi(self)

        QtCore.QObject.connect(self.ui.lvUsers, QtCore.SIGNAL("currentItemChanged(QListWidgetItem*,QListWidgetItem*)"), self.populateItem)
        QtCore.QObject.connect(self.ui.pbSave, QtCore.SIGNAL("clicked()"), self.saveUser)
        QtCore.QObject.connect(self.ui.pbAdd, QtCore.SIGNAL("clicked()"), self.addUser)
        QtCore.QObject.connect(self.ui.pbDelete, QtCore.SIGNAL("clicked()"), self.deleteUser)
        QtCore.QObject.connect(self.ui.pbCancel, QtCore.SIGNAL("clicked()"), self.cancel)
        QtCore.QObject.connect(self.ui.leUsername, QtCore.SIGNAL("textChanged(QString)"), self.changed)
        QtCore.QObject.connect(self.ui.leAccessKey, QtCore.SIGNAL("textChanged(QString)"), self.changed)
        QtCore.QObject.connect(self.ui.leAccessSecret, QtCore.SIGNAL("textChanged(QString)"), self.changed)
        QtCore.QObject.connect(self.ui.cbSyncData, QtCore.SIGNAL("stateChanged(int)"), self.changed)

        self.userService = UserService()
        self.updateUsers();

        self.ui.splitter.setStretchFactor(0,0)
        self.ui.splitter.setStretchFactor(1,1)
        self.ui.pbSwitch.hide()

    def _currentUser(self):
        if self.ui.lvUsers.currentItem() is None:
            return None

        return self.userService.findOne(self.ui.lvUsers.currentItem().data(QtCore.Qt.UserRole).userId)

    def changed(self):
        self.ui.pbCancel.setEnabled(True)
        self.ui.pbSave.setEnabled(True)
        self.ui.lvUsers.setEnabled(False)
        self.ui.pbAdd.setEnabled(False)
        self.ui.pbDelete.setEnabled(False)
        self.ui.pbSwitch.setEnabled(False)
        self.changed = True

    def resetForm(self):
        self.ui.pbCancel.setEnabled(False)
        self.ui.pbSave.setEnabled(False)
        self.ui.lvUsers.setEnabled(True)
        self.ui.pbAdd.setEnabled(True)
        self.ui.pbDelete.setEnabled(True)
        self.ui.pbSwitch.setEnabled(True)
        self.changed = False

    def cancel(self):
        currentRow = self.ui.lvUsers.currentRow()
        self.ui.lvUsers.setCurrentRow(-1)
        self.ui.lvUsers.setCurrentRow(currentRow)
        self.resetForm()

    def populateItem(self, current, previous):
        if current is None:
            return

        user = self.userService.findOne(current.data(QtCore.Qt.UserRole).userId)
        self.ui.leUsername.setText(user.username)
        self.ui.leAccessKey.setText(user.accessKey)
        self.ui.leAccessSecret.setText(user.accessSecret)
        self.ui.cbSyncData.setChecked(user.syncData)

        if self.ui.lvUsers.currentItem().data(QtCore.Qt.UserRole).userId==Application.user.userId:
            self.ui.pbDelete.setEnabled(False)
            self.ui.pbSwitch.setEnabled(False)
        else:
            self.ui.pbDelete.setEnabled(True)
            self.ui.pbSwitch.setEnabled(True)

        self.resetForm()

    def saveUser(self):
        user = None

        if self.ui.lvUsers.currentItem() is None:
            user = User()
        else:
            user = self._currentUser()

        currentRow = self.ui.lvUsers.currentRow()

        user.username = self.ui.leUsername.text()
        user.accessKey = self.ui.leAccessKey.text()
        user.accessSecret = self.ui.leAccessSecret.text()
        user.syncData = self.ui.cbSyncData.isChecked()

        self.userService.save(user)
        self.updateUsers()
        self.ui.lvUsers.setCurrentRow(currentRow)

        self.resetForm()

    def deleteUser(self):
        user = self._currentUser()

        if user is None or self.changed or user.userId==Application.user.userId:
            return

        currentRow = self.ui.lvUsers.currentRow()
        self.userService.delete(user.userId)
        self.updateUsers()

        if currentRow>=self.ui.lvUsers.count():
            self.ui.lvUsers.setCurrentRow(self.ui.lvUsers.count()-1)
        else:
            self.ui.lvUsers.setCurrentRow(currentRow)

        self.resetForm()

    def addUser(self):
        counter = 1
        username = "New Profile"

        while self.userService.findOneByUsername(username) is not None:
            username = "New Profile %d" % counter
            counter += 1

        user = User()
        user.username = username
        user = self.userService.save(user)
        self.updateUsers(user.userId)

        self.resetForm()

    def updateUsers(self, selectedId=None):
        users = self.userService.findAll("username", 100000)

        self.ui.lvUsers.clear()
        for user in users:
            item = QtGui.QListWidgetItem(user.username)
            item.setData(QtCore.Qt.UserRole, user)
            self.ui.lvUsers.addItem(item)

            if selectedId is not None and user.userId==selectedId:
                self.ui.lvUsers.setCurrentItem(item)

        if self.ui.lvUsers.currentItem() is None and self.ui.lvUsers.count()>0:
            self.ui.lvUsers.setCurrentItem(self.ui.lvUsers.item(0))

    def keyPressEvent(self, event):
        if(self._currentUser() is None):
            return

        if event.key()==QtCore.Qt.Key_Delete:
            self.deleteUser()
            return

        if event.key()==QtCore.Qt.Key_Escape:
            self.cancel()
            return

        if event.modifiers() & QtCore.Qt.ControlModifier:
            if event.key()==QtCore.Qt.Key_S:
                self.saveUser()
                return

        return QtGui.QDialog.keyPressEvent(self, event)<commit_msg>Update Application.user on save<commit_after>from PyQt4 import QtCore, QtGui, Qt

from lib.misc import Application
from lib.services.service import UserService
from lib.models.model import User
from ui.views.profiles import Ui_Profiles

class ProfilesForm(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Profiles()
        self.ui.setupUi(self)

        QtCore.QObject.connect(self.ui.lvUsers, QtCore.SIGNAL("currentItemChanged(QListWidgetItem*,QListWidgetItem*)"), self.populateItem)
        QtCore.QObject.connect(self.ui.pbSave, QtCore.SIGNAL("clicked()"), self.saveUser)
        QtCore.QObject.connect(self.ui.pbAdd, QtCore.SIGNAL("clicked()"), self.addUser)
        QtCore.QObject.connect(self.ui.pbDelete, QtCore.SIGNAL("clicked()"), self.deleteUser)
        QtCore.QObject.connect(self.ui.pbCancel, QtCore.SIGNAL("clicked()"), self.cancel)
        QtCore.QObject.connect(self.ui.leUsername, QtCore.SIGNAL("textChanged(QString)"), self.changed)
        QtCore.QObject.connect(self.ui.leAccessKey, QtCore.SIGNAL("textChanged(QString)"), self.changed)
        QtCore.QObject.connect(self.ui.leAccessSecret, QtCore.SIGNAL("textChanged(QString)"), self.changed)
        QtCore.QObject.connect(self.ui.cbSyncData, QtCore.SIGNAL("stateChanged(int)"), self.changed)

        self.userService = UserService()
        self.updateUsers();

        self.ui.splitter.setStretchFactor(0,0)
        self.ui.splitter.setStretchFactor(1,1)
        self.ui.pbSwitch.hide()

    def _currentUser(self):
        if self.ui.lvUsers.currentItem() is None:
            return None

        return self.userService.findOne(self.ui.lvUsers.currentItem().data(QtCore.Qt.UserRole).userId)

    def changed(self):
        self.ui.pbCancel.setEnabled(True)
        self.ui.pbSave.setEnabled(True)
        self.ui.lvUsers.setEnabled(False)
        self.ui.pbAdd.setEnabled(False)
        self.ui.pbDelete.setEnabled(False)
        self.ui.pbSwitch.setEnabled(False)
        self.changed = True

    def resetForm(self):
        self.ui.pbCancel.setEnabled(False)
        self.ui.pbSave.setEnabled(False)
        self.ui.lvUsers.setEnabled(True)
        self.ui.pbAdd.setEnabled(True)
        self.ui.pbDelete.setEnabled(True)
        self.ui.pbSwitch.setEnabled(True)
        self.changed = False

    def cancel(self):
        currentRow = self.ui.lvUsers.currentRow()
        self.ui.lvUsers.setCurrentRow(-1)
        self.ui.lvUsers.setCurrentRow(currentRow)
        self.resetForm()

    def populateItem(self, current, previous):
        if current is None:
            return

        user = self.userService.findOne(current.data(QtCore.Qt.UserRole).userId)
        self.ui.leUsername.setText(user.username)
        self.ui.leAccessKey.setText(user.accessKey)
        self.ui.leAccessSecret.setText(user.accessSecret)
        self.ui.cbSyncData.setChecked(user.syncData)

        if self.ui.lvUsers.currentItem().data(QtCore.Qt.UserRole).userId==Application.user.userId:
            self.ui.pbDelete.setEnabled(False)
            self.ui.pbSwitch.setEnabled(False)
        else:
            self.ui.pbDelete.setEnabled(True)
            self.ui.pbSwitch.setEnabled(True)

        self.resetForm()

    def saveUser(self):
        user = None

        if self.ui.lvUsers.currentItem() is None:
            user = User()
        else:
            user = self._currentUser()

        currentRow = self.ui.lvUsers.currentRow()

        user.username = self.ui.leUsername.text()
        user.accessKey = self.ui.leAccessKey.text()
        user.accessSecret = self.ui.leAccessSecret.text()
        user.syncData = self.ui.cbSyncData.isChecked()

        self.userService.save(user)
        self.updateUsers()
        self.ui.lvUsers.setCurrentRow(currentRow)

        self.resetForm()

        Application.user = user

    def deleteUser(self):
        user = self._currentUser()

        if user is None or self.changed or user.userId==Application.user.userId:
            return

        currentRow = self.ui.lvUsers.currentRow()
        self.userService.delete(user.userId)
        self.updateUsers()

        if currentRow>=self.ui.lvUsers.count():
            self.ui.lvUsers.setCurrentRow(self.ui.lvUsers.count()-1)
        else:
            self.ui.lvUsers.setCurrentRow(currentRow)

        self.resetForm()

    def addUser(self):
        counter = 1
        username = "New Profile"

        while self.userService.findOneByUsername(username) is not None:
            username = "New Profile %d" % counter
            counter += 1

        user = User()
        user.username = username
        user = self.userService.save(user)
        self.updateUsers(user.userId)

        self.resetForm()

    def updateUsers(self, selectedId=None):
        users = self.userService.findAll("username", 100000)

        self.ui.lvUsers.clear()
        for user in users:
            item = QtGui.QListWidgetItem(user.username)
            item.setData(QtCore.Qt.UserRole, user)
            self.ui.lvUsers.addItem(item)

            if selectedId is not None and user.userId==selectedId:
                self.ui.lvUsers.setCurrentItem(item)

        if self.ui.lvUsers.currentItem() is None and self.ui.lvUsers.count()>0:
            self.ui.lvUsers.setCurrentItem(self.ui.lvUsers.item(0))

    def keyPressEvent(self, event):
        if(self._currentUser() is None):
            return

        if event.key()==QtCore.Qt.Key_Delete:
            self.deleteUser()
            return

        if event.key()==QtCore.Qt.Key_Escape:
            self.cancel()
            return

        if event.modifiers() & QtCore.Qt.ControlModifier:
            if event.key()==QtCore.Qt.Key_S:
                self.saveUser()
                return

        return QtGui.QDialog.keyPressEvent(self, event)<|endoftext|>


<commit_before>"""Requests service."""
import os
import json
from datetime import datetime
from collections import namedtuple
import cherrypy
import html
from apache_utils import name_from_dn
from sqlalchemy_utils import create_db, db_session
from tables import Requests, Users, ParametricJobs

COLUMNS = ['id', 'request_date', 'sim_lead', 'status', 'description']
SelectedMacro = namedtuple('SelectedMacro', ('path', 'name', 'njobs', 'nevents', 'seed', 'status', 'output'))

class RequestsDB(object):
    """
    RequestsDB Service.

    Service for checking the requests in the LZProd DB and for returning
    a given row.
    """

    exposed = True

    def __init__(self, dburl):
        """Initialisation."""
        self.dburl = dburl
        create_db(dburl)

    def GET(self, reqid=None):  # pylint: disable=C0103
        """REST Get method."""
        print "IN GET: reqid=(%s)" % reqid
        requester = cherrypy.request.verified_user

        with db_session(self.dburl) as session:
            if reqid is None:
                if not requester.admin:
                    query = session.query(Requests.id,
                                          Requests.request_date,
                                          Requests.sim_lead,
                                          Requests.status,
                                          Requests.description)\
                                   .filter(Requests.requester_id == requester.id)
                    return json.dumps({'data': [dict(zip(COLUMNS, request))
                                                for request in query.all()]})
                query = session.query(Requests.id,
                                      Requests.request_date,
                                      Requests.sim_lead,
                                      Requests.status,
                                      Requests.description,
                                      Users.dn)\
                               .join(Users, Requests.requester_id == Users.id)
                data = []
                for request in query.all():
                    tmp = dict(zip(COLUMNS, request))
                    tmp['requester'] = name_from_dn(request.dn)
                    data.append(tmp)

                return json.dumps({'data': data})

            table = html.HTML().table(border='1')
            request = session.query(Requests).filter(Requests.id == reqid).first()
            if request is not None:
                for colname, value in request.iteritems():
                    row = table.tr()
                    row.td(colname)
                    row.td(str(value))
        return str(table)

    def POST(self, **kwargs):  # pylint: disable=C0103
        """REST Post method."""
        print "IN POST", kwargs
        kwargs['request_date'] = datetime.now().strftime('%d/%m/%Y')
        kwargs['status'] = 'Requested'
        selected_macros = kwargs.pop('selected_macros', [])
        if not isinstance(selected_macros, list):
            selected_macros = [selected_macros]

        with db_session(self.dburl) as session:
            request = Requests(requester_id=cherrypy.request.verified_user.id, request_date=kwargs['request_date'], source=kwargs['source'], detector=kwargs['detector'], sim_lead=kwargs['sim_lead'], status=kwargs['status'], description=kwargs['description'])
            session.add(request)
            session.flush()
            session.refresh(request)

            macros = []
            for macro in selected_macros:
                path, njobs, nevents, seed = macro.split()
                macros.append(ParametricJobs(request_id=request.id, status="Requested", macro=path, tag=kwargs['tag'], app=kwargs.get('app'), fastnest_version=kwargs.get('fastnest_version'), reduction_version=kwargs.get('reduction_version'), der_version=kwargs.get('der_version'), lzap_version=kwargs.get('lzap_version'),
                                             outputdir_lfns=[], njobs=njobs, nevents=nevents, seed=seed, app_version=kwargs.get('app_version'),
                                             dirac_jobs={}, reschedule=False))

            session.add_all(macros)
        return self.GET()

    def PUT(self, reqid, **kwargs):  # pylint: disable=C0103
        """REST Put method."""
        print "IN PUT: reqid=(%s)" % reqid, kwargs
        requester = cherrypy.request.verified_user

        with db_session(self.dburl) as session:
            query = session.query(Requests).filter(Requests.id == reqid)
            if not requester.admin:
                query = query.filter(Requests.requester_id == requester.id)
            query.update(kwargs)

    def DELETE(self, reqid):  # pylint: disable=C0103
        """REST Delete method."""
        print "IN DELETE: reqid=(%s)" % reqid

        if cherrypy.request.verified_user.admin:
            with db_session(self.dburl) as session:
                session.query(Requests)\
                       .filter(Requests.id == reqid)\
                       .delete(synchronize_session=False)
        return self.GET()
<commit_msg>Remove ParametricJobs on Request removal.<commit_after>"""Requests service."""
import os
import json
from datetime import datetime
from collections import namedtuple
import cherrypy
import html
from apache_utils import name_from_dn
from sqlalchemy_utils import create_db, db_session
from tables import Requests, Users, ParametricJobs

COLUMNS = ['id', 'request_date', 'sim_lead', 'status', 'description']
SelectedMacro = namedtuple('SelectedMacro', ('path', 'name', 'njobs', 'nevents', 'seed', 'status', 'output'))

class RequestsDB(object):
    """
    RequestsDB Service.

    Service for checking the requests in the LZProd DB and for returning
    a given row.
    """

    exposed = True

    def __init__(self, dburl):
        """Initialisation."""
        self.dburl = dburl
        create_db(dburl)

    def GET(self, reqid=None):  # pylint: disable=C0103
        """REST Get method."""
        print "IN GET: reqid=(%s)" % reqid
        requester = cherrypy.request.verified_user

        with db_session(self.dburl) as session:
            if reqid is None:
                if not requester.admin:
                    query = session.query(Requests.id,
                                          Requests.request_date,
                                          Requests.sim_lead,
                                          Requests.status,
                                          Requests.description)\
                                   .filter(Requests.requester_id == requester.id)
                    return json.dumps({'data': [dict(zip(COLUMNS, request))
                                                for request in query.all()]})
                query = session.query(Requests.id,
                                      Requests.request_date,
                                      Requests.sim_lead,
                                      Requests.status,
                                      Requests.description,
                                      Users.dn)\
                               .join(Users, Requests.requester_id == Users.id)
                data = []
                for request in query.all():
                    tmp = dict(zip(COLUMNS, request))
                    tmp['requester'] = name_from_dn(request.dn)
                    data.append(tmp)

                return json.dumps({'data': data})

            table = html.HTML().table(border='1')
            request = session.query(Requests).filter(Requests.id == reqid).first()
            if request is not None:
                for colname, value in request.iteritems():
                    row = table.tr()
                    row.td(colname)
                    row.td(str(value))
        return str(table)

    def POST(self, **kwargs):  # pylint: disable=C0103
        """REST Post method."""
        print "IN POST", kwargs
        kwargs['request_date'] = datetime.now().strftime('%d/%m/%Y')
        kwargs['status'] = 'Requested'
        selected_macros = kwargs.pop('selected_macros', [])
        if not isinstance(selected_macros, list):
            selected_macros = [selected_macros]

        with db_session(self.dburl) as session:
            request = Requests(requester_id=cherrypy.request.verified_user.id, request_date=kwargs['request_date'], source=kwargs['source'], detector=kwargs['detector'], sim_lead=kwargs['sim_lead'], status=kwargs['status'], description=kwargs['description'])
            session.add(request)
            session.flush()
            session.refresh(request)

            macros = []
            for macro in selected_macros:
                path, njobs, nevents, seed = macro.split()
                macros.append(ParametricJobs(request_id=request.id, status="Requested", macro=path, tag=kwargs['tag'], app=kwargs.get('app'), fastnest_version=kwargs.get('fastnest_version'), reduction_version=kwargs.get('reduction_version'), der_version=kwargs.get('der_version'), lzap_version=kwargs.get('lzap_version'),
                                             outputdir_lfns=[], njobs=njobs, nevents=nevents, seed=seed, app_version=kwargs.get('app_version'),
                                             dirac_jobs={}, reschedule=False))

            session.add_all(macros)
        return self.GET()

    def PUT(self, reqid, **kwargs):  # pylint: disable=C0103
        """REST Put method."""
        print "IN PUT: reqid=(%s)" % reqid, kwargs
        requester = cherrypy.request.verified_user

        with db_session(self.dburl) as session:
            query = session.query(Requests).filter(Requests.id == reqid)
            if not requester.admin:
                query = query.filter(Requests.requester_id == requester.id)
            query.update(kwargs)

    def DELETE(self, reqid):  # pylint: disable=C0103
        """REST Delete method."""
        print "IN DELETE: reqid=(%s)" % reqid

        if cherrypy.request.verified_user.admin:
            with db_session(self.dburl) as session:
                session.query(Requests)\
                       .filter(Requests.id == reqid)\
                       .delete(synchronize_session=False)
                session.query(ParametricJobs)\
                       .filter(ParametricJobs.request_id == reqid)\
                       .delete(synchronize_session=False)
        return self.GET()
<|endoftext|>


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

__version__ = "0.2.2-beta"

__title__ = "pygcgen"
__summary__ = "Automatic changelog generation"
__uri__ = "https://github.com/topic2k/pygcgen"

__author__ = "topic2k"
__email__ = "topic2k+pypi@gmail.com"

__license__ = "MIT"
__copyright__ = "2016 %s" % __author__
<commit_msg>change version string<commit_after># -*- coding: utf-8 -*-

__version__ = "0.2.2b1"

__title__ = "pygcgen"
__summary__ = "Automatic changelog generation"
__uri__ = "https://github.com/topic2k/pygcgen"

__author__ = "topic2k"
__email__ = "topic2k+pypi@gmail.com"

__license__ = "MIT"
__copyright__ = "2016 %s" % __author__
<|endoftext|>


<commit_before>
from .black_sep import *
from .command_text_box import *
from .drop_down_box import *
from .bar import *
from .menu_box import *

__all__ = [ 'black_sep', 'command_text_box', 'drop_down_box', 'bar', 'menu_box' ]

# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab smarttab
<commit_msg>* Removed the custom bar widget.<commit_after>
from .black_sep import *
from .command_text_box import *
from .drop_down_box import *
from .menu_box import *

__all__ = [ 'black_sep', 'command_text_box', 'drop_down_box', 'menu_box' ]

# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab smarttab
<|endoftext|>


<commit_before>from __future__ import division
import numpy as np

def main(dSigOrig, dSigRecon, dAna, iSNRSuccess):

    ## Get the original unnoisy signals, the number of signal and their length
    mSig_orig = dSigOrig['mSigNN']
    (iSigs_orig, iSiz_orig) = mSig_orig.shape

    # Get the reconstructed signals and their length
    mSig_recon = dSigRecon['mSig']
    (iSigs_recon, iSiz_recon) = mSig_orig.shape

    # Check if the original and the reconstructed signals have the same length
    strErr = 'The original and reconstructed signals must have the same length'
    if iSiz_orig != iSiz_recon:
        raise ValueError(strErr)

    # Check if there is the same number of original and reconstructed signals
    strErr = 'There are more original signals than reconstructed signals!'
    if iSigs_orig > iSigs_recon:
        raise ValueError(strErr)
    strErr = 'There are more reconstructed signals than original signals!'
    if iSigs_recon > iSigs_orig:
        raise ValueError(strErr)

    # -------------------------------------------------------------------
    # Compute the SNR

    # Compute the noise
    mNoise = np.abs(mSig_orig - mSig_recon)
    (_, iSizNoise) = mNoise.shape  # Size of the noise

    # Compute the power of noise
    vNoiseP = (np.sum(mNoise * mNoise, axis=1) / iSizNoise)

    # Compute the power of orignal signals
    vSigP = (np.sum(mSig_orig * mSig_orig, axis=1) / iSiz_orig)

    # Compute the SNR for every reconstructed signal and the average SNR
    vSNR = 10 * np.log10(vSigP / vNoiseP)
    iSNR = vSNR.mean()

    # -------------------------------------------------------------------
    # Compute the success ratio
    iSR = (vSNR >= iSNRSuccess).mean()

    # -------------------------------------------------------------------
    # Add the vector with computed SNR to the dictionary with system
    # analysis results
    dAna['vSNR'] = vSNR

    # Add the average SNR to the dictionary with system analysis results
    dAna['iSNR'] = iSNR

    # Add the success ratio to the dictionary with system analysis results
    dAna['iSR'] = iSR

    # -------------------------------------------------------------------
    return dAna
<commit_msg>Docstrings added, configuration by the dictionary, progress and results printing added to the Reconstruction SNR evaluation<commit_after>"""
This module contains SNR evaluation function of the reconstructed signals. |br|

*Author*:
    Jacek Pierzchlewski, Aalborg University, Denmark. <jap@es.aau.dk>

*Version*:
    0.1  | 20-MAY-2014 : * Initial version. |br|
    0.2  | 21-MAY-2014 : * Success Ratio computation is added. |br|
    0.3  | 21-MAY-2014 : * Docstrings added. |br|
    0.4  | 21-MAY-2014 : * Configuration with a dictionary |br|
    0.5  | 21-MAY-2014 : * Progress and results printing |br|

*License*:
    BSD 2-Clause
"""
from __future__ import division
import numpy as np
import rxcs

def main(dSigOrig, dSigRecon, dAna, dAnaConf):
    """
    This the main function of the generator and the only one which should be
    accessed by a user. |br|

    The function computes a noise of reconstrucion for every signal;
    this noise is equal to the difference between the reconstructed and
    the original signals.
    Afterwards the function computes the signal-to-noise ratio of
    the reconstruction for every signal.
    The ratio is computed as: SNR = 10log10(iPs/iPn),
    where:

            iPs - power of the original signal

            iPn - power of noise

    The function computes also the average signal-to-noise ratio of the
    reconstruction. |br|

    Additionally. the function computes the success ratio, which is equal to
    the ratio of reconstructed signal with reconstruction SNR higher than
    success threshold. |br|

    Args:
        dSigOrig (dict): dict. with the original signals
        dSigRecon (dict): dict. with the reconstructed signals
        dAna (dict): dict. with results of system analysis
        dAnaConf (dict): dict. with configuration for system analysis

    Returns:
        dAna (dict): dict. with results of system analysis
    """

    # -------------------------------------------------------------------
    # Get the signals
    (mSig_orig, mSig_recon, nSigs_orig, iSiz_orig) = \
        _getSignals(dSigOrig, dSigRecon)

    # Get the configuration
    # bMute        -  'mute the console output' flag
    # iSNRSuccess  -  success threshold
    (bMute,
     iSNRSuccess) = _getConf(dAnaConf)

    # -------------------------------------------------------------------
    # Print out the header of the SNR analysis
    if bMute == 0:
        rxcs.console.progress('System analysis',
                              'SNR of the reconstructed signal')
        tStart = rxcs.console.module_progress('SNR analysis starts!!!')

    # -------------------------------------------------------------------
    # Compute the SNR

    # Compute the noise
    mNoise = np.abs(mSig_orig - mSig_recon)
    (_, iSizNoise) = mNoise.shape  # Size of the noise

    # Compute the power of noise
    vNoiseP = (np.sum(mNoise * mNoise, axis=1) / iSizNoise)

    # Compute the power of orignal signals
    vSigP = (np.sum(mSig_orig * mSig_orig, axis=1) / iSiz_orig)

    # Compute the SNR for every reconstructed signal and the average SNR
    vSNR = 10 * np.log10(vSigP / vNoiseP)
    iSNR = vSNR.mean()

    # -------------------------------------------------------------------
    # Compute the success ratio
    iSR = (vSNR >= iSNRSuccess).mean()

    # -------------------------------------------------------------------
    # Add the vector with computed SNR to the dictionary with system
    # analysis results
    dAna['vSNR'] = vSNR

    # Add the average SNR to the dictionary with system analysis results
    dAna['iSNR'] = iSNR

    # Add the success ratio to the dictionary with system analysis results
    dAna['iSR'] = iSR

    # -------------------------------------------------------------------
    # SNR analysis is done
    if bMute == 0:
        rxcs.console.module_progress_done(tStart)

    # -------------------------------------------------------------------
    # Print results
    _printResults(iSNR, iSR, iSNRSuccess, bMute)

    # -------------------------------------------------------------------
    return dAna

# =================================================================
# Get the signals
# =================================================================
def _getSignals(dSigOrig, dSigRecon):
    """
    This function gets the reconstructed and the original signals from
    the data dicionaries.

    The function checks if:

        - the signals are present in the dictionaries

        - the signals have the same length

        - there is the same number of signals

    Args:
        dSigOrig (dict): dict. with the original signals
        dSigRecon (dict): dict. with the reconstructed signals

    Returns:
        mSig_orig (matrix): the original non noisy signal
        mSig_recon (matrix): the reconstructed signal
        nSigs (float): the number of signals
        iSigSiz (float): the length of signals
    """

    # -------------------------------------------------------------------
    # Get the original non noisy signals, the number of orignal signals
    # and their length
    strErr = 'The original signals (mSigNN) are missing in the "dSigOrig"'
    if not 'mSigNN' in dSigOrig:
        raise NameError(strErr)

    mSig_orig = dSigOrig['mSigNN']
    (nSigs_orig, iSiz_orig) = mSig_orig.shape

    # -------------------------------------------------------------------
    # Get the reconstructed signals, the number of reconstructed signals,
    # and their length
    strErr = 'The reconstructed signals (mSig) are missing in the "dSigRecon"'
    if not 'mSig' in dSigRecon:
        raise NameError(strErr)

    mSig_recon = dSigRecon['mSig']
    (nSigs_recon, iSiz_recon) = mSig_orig.shape

    # -------------------------------------------------------------------
    # Check if the original and the reconstructed signals have the same
    # length
    strErr = 'The original and reconstructed signals must have the same length'
    if iSiz_orig != iSiz_recon:
        raise ValueError(strErr)

    # -------------------------------------------------------------------
    # Check if there is the same number of original and reconstructed
    # signals
    strErr = 'There are more original signals than reconstructed signals!'
    if nSigs_orig > nSigs_recon:
        raise ValueError(strErr)
    strErr = 'There are more reconstructed signals than original signals!'
    if nSigs_recon > nSigs_orig:
        raise ValueError(strErr)

    # -------------------------------------------------------------------
    nSigs = nSigs_orig
    iSigSiz = iSiz_orig
    return (mSig_orig, mSig_recon, nSigs, iSigSiz)

# =================================================================
# Get the configuration
# =================================================================
def _getConf(dAnaConf):
    """
    This function gets the configuration of the module from the
    system analysis configuration dictionary.

    The function checks if the correct configuration fields are given in
    the configuration dictionary. If not, the default values are assigned to
    the configuration values.

    Args:
        dAnaConf (dict): dict. with the system analysis configuration

    Returns:
        bMute (float): 'mute the console output' flag
        iSNRSuccess (float): success threshold
    """

    # -------------------------------------------------------------------
    # Get the mute flag
    if not 'bMute' in dAnaConf:
        bMute = 0
    else:
        bMute = dAnaConf['bMute']

    # -------------------------------------------------------------------
    # Get the success threshold
    if not 'bMute' in dAnaConf:
        iSNRSuccess = 20
    else:
        iSNRSuccess = dAnaConf['iSNRSuccess']

    return (bMute, iSNRSuccess)

# =================================================================
# Print results of the analysis
# =================================================================
def _printResults(iSNR, iSR, iSNRSuccess, bMute):
    """
    This function print the results of the SNR analysis to the console,
    if the 'mute' flag is not set.

    Args:
        iSNR (float): the measured average SNR of the reconstrucion
        iSR (float): success ratio
        iSNRSuccess (float): success threshold
        bMute (float): 'mute the console output' flag

    Returns:
        nothing

    """

    if bMute == 0:
        rxcs.console.bullet_param('The average SNR of the reconstruction',
                                  iSNR, '-', 'dB')
        rxcs.console.bullet_param('The Success Ratio', iSR, ' ', '')
        rxcs.console.param('(success threshold)', iSNRSuccess, '-', 'dB')
    return
<|endoftext|>


<commit_before>"""
Implementation of the squared-exponential kernels.
"""

# future imports
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

# global imports
import numpy as np

# local imports
from ._base import RealKernel
from ._distances import sqdist, sqdist_per_dim
from ._local import local_se

from ..utils.random import rstate
from ..utils.models import Printable

# exported symbols
__all__ = ['SEARD', 'SEIso']

class SEARD(RealKernel, Printable):
    def __init__(self, sf, ell):
        self._logsf = np.log(sf)
        self._logell = np.log(np.ravel(ell))
        self.ndim = len(self._logell)
        self.nhyper = self.ndim + 1

    def _params(self):
        return [
            ('sf',  1),
            ('ell', self.ndim),]

    def get_hyper(self):
        return np.r_[self._logsf, self._logell]

    def set_hyper(self, hyper):
        self._logsf  = hyper[0]
        self._logell = hyper[1:]

    def get(self, X1, X2=None):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        return sf2 * np.exp(-0.5*sqdist(ell, X1, X2))

    def dget(self, X1):
        sf2 = np.exp(self._logsf*2)
        return sf2 * np.ones(len(X1))

    def grad(self, X1, X2=None):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        for D in sqdist_per_dim(ell, X1, X2):
            D *= sf2 * np.exp(-0.5*D)
            yield D
        yield 2*self.get(X1, X2)

    def dgrad(self, X):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        for i in xrange(self.ndim):
            yield np.zeros(len(X))
        yield 2 * sf2 * np.ones(len(X))

    def sample_spectrum(self, N, rng=None):
        rng = rstate(rng)
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        W = rng.randn(N, self.ndim) / ell
        return W, sf2

    def get_local(self, x, X1, X2=None):
        ell = np.exp(self._logell*-1)
        sf2 = np.exp(self._logsf*2)
        return local_se(ell, sf2, 0.0, x, X1, X2)

# NOTE: the definitions of the ARD and Iso kernels are basically the same, and
# will remain so until I implement the gradients. Trying to generalize this code
# seems to make the kernel a lot messier to read, so I'll leave it this way
# until I come up with a nicer way to do things.

class SEIso(RealKernel, Printable):
    def __init__(self, sf, ell, ndim=1):
        self._logsf = np.log(sf)
        self._logell = np.log(float(ell))
        self.ndim = ndim
        self.nhyper = 2

    def _params(self):
        return [
            ('sf',  1),
            ('ell', 1),]

    def get_hyper(self):
        return np.r_[self._logsf, self._logell]

    def set_hyper(self, hyper):
        self._logsf  = hyper[0]
        self._logell = hyper[1]

    def get(self, X1, X2=None):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        return sf2 * np.exp(-0.5*sqdist(ell, X1, X2))

    def dget(self, X1):
        sf2 = np.exp(self._logsf*2)
        return sf2 * np.ones(len(X1))

    def grad(self, X1, X2=None):
        ell = np.exp(self._logell)
        sf2 = np.exp(self._logsf*2)
        D = sqdist(ell, X1, X2)
        K = sf2 * np.exp(-0.5*D)
        yield 2*K
        yield D*K

    def dgrad(self, X):
        yield 2*self.dget(X)
        yield np.zeros(len(x1))

    def sample_spectrum(self, N, rng=None):
        rng = rstate(rng)
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        W = rng.randn(N, self.ndim) / ell
        return W, sf2

    def get_local(self, x, X1, X2=None):
        ell = np.tile(np.exp(self._logell*-1), self._ndim)
        sf2 = np.exp(self._logsf*2)
        return local_se(ell, sf2, 0.0, x, X1, X2)

<commit_msg>Update the use of ell.<commit_after>"""
Implementation of the squared-exponential kernels.
"""

# future imports
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

# global imports
import numpy as np

# local imports
from ._base import RealKernel
from ._distances import sqdist, sqdist_per_dim
from ._local import local_se

from ..utils.random import rstate
from ..utils.models import Printable

# exported symbols
__all__ = ['SEARD', 'SEIso']

class SEARD(RealKernel, Printable):
    def __init__(self, sf, ell):
        self._logsf = np.log(sf)
        self._logell = np.log(np.ravel(ell))
        self.ndim = len(self._logell)
        self.nhyper = self.ndim + 1

    def _params(self):
        return [
            ('sf',  1),
            ('ell', self.ndim),]

    def get_hyper(self):
        return np.r_[self._logsf, self._logell]

    def set_hyper(self, hyper):
        self._logsf  = hyper[0]
        self._logell = hyper[1:]

    def get(self, X1, X2=None):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        return sf2 * np.exp(-0.5*sqdist(ell, X1, X2))

    def dget(self, X1):
        sf2 = np.exp(self._logsf*2)
        return sf2 * np.ones(len(X1))

    def grad(self, X1, X2=None):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        for D in sqdist_per_dim(ell, X1, X2):
            D *= sf2 * np.exp(-0.5*D)
            yield D
        yield 2*self.get(X1, X2)

    def dgrad(self, X):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        for i in xrange(self.ndim):
            yield np.zeros(len(X))
        yield 2 * sf2 * np.ones(len(X))

    def sample_spectrum(self, N, rng=None):
        rng = rstate(rng)
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        W = rng.randn(N, self.ndim) / ell
        return W, sf2

    def get_local(self, sn2, x, X1, X2=None):
        ell = np.exp(self._logell*-2)
        sf2 = np.exp(self._logsf*2)
        return local_se(ell, sf2, sn2, x, X1, X2)

# NOTE: the definitions of the ARD and Iso kernels are basically the same, and
# will remain so until I implement the gradients. Trying to generalize this code
# seems to make the kernel a lot messier to read, so I'll leave it this way
# until I come up with a nicer way to do things.

class SEIso(RealKernel, Printable):
    def __init__(self, sf, ell, ndim=1):
        self._logsf = np.log(sf)
        self._logell = np.log(float(ell))
        self.ndim = ndim
        self.nhyper = 2

    def _params(self):
        return [
            ('sf',  1),
            ('ell', 1),]

    def get_hyper(self):
        return np.r_[self._logsf, self._logell]

    def set_hyper(self, hyper):
        self._logsf  = hyper[0]
        self._logell = hyper[1]

    def get(self, X1, X2=None):
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        return sf2 * np.exp(-0.5*sqdist(ell, X1, X2))

    def dget(self, X1):
        sf2 = np.exp(self._logsf*2)
        return sf2 * np.ones(len(X1))

    def grad(self, X1, X2=None):
        ell = np.exp(self._logell)
        sf2 = np.exp(self._logsf*2)
        D = sqdist(ell, X1, X2)
        K = sf2 * np.exp(-0.5*D)
        yield 2*K
        yield D*K

    def dgrad(self, X):
        yield 2*self.dget(X)
        yield np.zeros(len(x1))

    def sample_spectrum(self, N, rng=None):
        rng = rstate(rng)
        sf2 = np.exp(self._logsf*2)
        ell = np.exp(self._logell)
        W = rng.randn(N, self.ndim) / ell
        return W, sf2

    def get_local(self, sn2, x, X1, X2=None):
        ell = np.tile(np.exp(self._logell*-2), self.ndim)
        sf2 = np.exp(self._logsf*2)
        return local_se(ell, sf2, sn2, x, X1, X2)

<|endoftext|>


<commit_before>'''
Roulette
========

Dependencies
------------

1. the garden package ``kivy.garden.tickline``. Use ``garden install tickline``
    to install it like any other garden package.

'''
from kivy.garden.roulettescroll import RouletteScrollEffect
from kivy.garden.tickline import Tick, Tickline, TickLabeller
from kivy.garden.timeline import Timeline, TimeTick, TimeLabeller, \
    round_time
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.core.text import Label as CoreLabel
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from kivy.metrics import sp, dp
from kivy.properties import ListProperty, ObjectProperty, AliasProperty, \
    NumericProperty, BooleanProperty, StringProperty, OptionProperty

class SlotLabeller(TickLabeller):
    def __init__(self, tickline):
        self.instructions = {}
        self.re_init()
        self.tickline = tickline

    def re_init(self):
        self.to_pop = set(self.instructions)
        self.to_push = []

    def register(self, tick, tick_index, tick_info):
        tickline = self.tickline
        if tick_index not in self.instructions:
            self.to_push.append(tick_index)
            texture = tick.get_label_texture(tick_index)
        else:
            self.to_pop.remove(tick_index)
            texture = self.instructions[tick_index].texture
        if texture:
            if tickline.is_vertical():
                tick_pos = tick_info[1] + tick_info[3] / 2
                pos = (tickline.center_x - texture.width / 2,
                       tick_pos - texture.height / 2)
            else:
                tick_pos = tick_info[0] + tick_info[2] / 2
                pos = (tick_pos - texture.width / 2,
                       tickline.center_y - texture.height / 2)
            # only need to update the position if label is saved
            self.instructions.setdefault(tick_index,
                Rectangle(texture=texture, size=texture.size,
                          group=self.group_id)).pos = pos
    def make_labels(self):
        canvas = self.tickline.canvas
        for index in self.to_push:
            rect = self.instructions[index]
            canvas.add(rect)
        for index in self.to_pop:
            rect = self.instructions.pop(index)
            canvas.remove(rect)

#===============================================================================
# Slots
#===============================================================================
class Slot(Tick):
    tick_size = ListProperty([0, 0])
    font_size = NumericProperty('20sp')
    int_valued = BooleanProperty(True)
    format_str = StringProperty('{}')
    def value_str(self, value):
        return self.format_str.format(value)
    def slot_value(self, index, *args, **kw):
        '''returns the selection value that corresponds to ``index``.
        Should be overriden if necessary.'''
        if self.int_valued:
            return int(round(index))
        return index
    def index_of(self, val, *args, **kw):
        '''returns the index that corresponds to a selection value ``val``.
        Should be override if necessary.'''
        return val
    def get_label_texture(self, index, **kw):
        label = CoreLabel(text=self.value_str(self.slot_value(index)),
                          font_size=self.font_size, **kw)
        label.refresh()
        return label.texture

class CyclicSlot(Slot):
    cycle = NumericProperty(10)
    zero_indexed = BooleanProperty(False)
    def get_first_value(self):
        return 0 if self.zero_indexed else 1
    def set_first_value(self, val):
        self.zero_indexed = not val
    first_value = AliasProperty(get_first_value, set_first_value, cache=True,
                                bind=['zero_indexed'])
    def slot_value(self, index):
        cycle = self.cycle
        val = index % cycle + 1 - self.zero_indexed
        val = Slot.slot_value(self, val)
        if val >= cycle + 1 - self.zero_indexed:
            val -= cycle
        return val
    def index_of(self, val, current_index, *args, **kw):
        '''returns the closest index to ``current_index`` that would correspond
        to ``val``. All indices should be localized.'''
        if self.int_valued:
            val = int(round(val))
        zero_indexed = self.zero_indexed
        cycle = self.cycle
        if not (1 - zero_indexed) <= val <= cycle - zero_indexed:
            raise ValueError('value must be between {} and {}; {} is given'.
                             format(1 - zero_indexed, cycle - zero_indexed, val))
        base_index = val - 1 + self.zero_indexed
        n = round((current_index - base_index) / cycle)
        index = n * cycle + base_index
        return index

#===============================================================================
# Roulettes
#===============================================================================

Builder.load_string('''
<Roulette>:
    canvas.after:
        Color:
            rgb: 1, 1, 1, 0
        Line:
            points: self.x, self.y, self.x, self.top
        Line:
            points: self.right, self.y, self.right, self.top
        Color:
            rgba: 1, 1, 1, .3
        Rectangle:
            pos: self.pos
            size: self.width, self.height / 2
    size_hint: None, 1
''')

class Roulette(Tickline):
    __events__ = ('on_centered',)
    tick_cls = ObjectProperty(Slot)
    '''The class of the tick in this roulette. Should be overriden as needed
    by child class.'''
    labeller_cls = ObjectProperty(SlotLabeller)
    zoomable = BooleanProperty(False)
    draw_line = BooleanProperty(False)
    background_color = ListProperty([0.06, .07, .22])
    font_size = NumericProperty('20sp')
    width = NumericProperty('60dp')
    selected_value = ObjectProperty(None)
    format_str = StringProperty('{}')
    int_valued = BooleanProperty(True)
    scroll_effect_cls = ObjectProperty(RouletteScrollEffect)
    drag_threshold = NumericProperty(0)
    center_duration = NumericProperty(.3)
    '''duration for the animation of :meth:`center_on`.'''
    density = NumericProperty(4.2)
    '''determines how many slots are shown at a time.'''
    def get_rolling_value(self):
        return self.tick.slot_value(self.tick.localize(self.index_mid))
    def set_rolling_value(self, val):
        self.index_mid = self.tick.globalize(val)
    rolling_value = AliasProperty(get_rolling_value,
                                    set_rolling_value,
                                    bind=['index_mid'])
    '''the val indicated by whatever slot is in the middle of the roulette.
    If the roulette is still, then :attr:`rolling_value` is equal to
    :attr:`selected_value`. Otherwise, they shouldn't be equal.

    .. note::
        This property is not stable under resizing, since often that will
        change the slot in the middle.'''
    def get_ticks(self):
        if self.tick:
            return [self.tick]
        else:
            return []
    def set_ticks(self, val):
        self.tick = val[0]
    ticks = AliasProperty(get_ticks, set_ticks, bind=['tick'])
    # needs a non-None value to so that kv bindings work
    tick = ObjectProperty(None)

    def __init__(self, **kw):
        self.tick = Slot()
        super(Roulette, self).__init__(**kw)
        self.scale = dp(10)
        self._trigger_set_selection = \
                Clock.create_trigger(self.set_selected_value)
        self.tick = self.tick_cls()
        self._trigger_calibrate()
    def on_tick_cls(self, *args):
        self.tick = self.tick_cls()
    def on_tick(self, *args):
        tick = self.tick
        if tick:
            tick.font_size = self.font_size
            tick.int_valued = self.int_valued
            tick.format_str = self.format_str

    def get_anchor(self):
        '''returns a legal stopping value for the :class:`RouletteScrollEffect`.
        Should be overriden if necessary.'''
        return 0
    def _update_effect_constants(self, *args):
        if not super(Roulette, self)._update_effect_constants(*args):
            return
        effect = self.scroll_effect
        scale = self.scale
        effect.pull_back_velocity = sp(50) / scale
    def calibrate_scroll_effect(self, *args, **kw):
        if not super(Roulette, self).calibrate_scroll_effect(*args, **kw):
            return
        anchor = self.get_anchor()
        effect = self.scroll_effect
        effect.interval = 1. / self.tick.scale_factor
        effect.anchor = anchor
        effect.on_coasted_to_stop = self._trigger_set_selection
    def set_selected_value(self, *args):
        '''set :attr:`selected_value` to the currently slot.'''
        self.selected_value = self.round_(self.rolling_value)
    def round_(self, val):
        '''round an arbitrary rolling value to a legal selection value.
        Should be overriden if necessary.'''
        if self.int_valued:
            return int(round(val))
        return round(val)
    def recenter(self, *args):
        if self.selected_value is not None:
            self.center_on(self.selected_value)
        self._trigger_calibrate()
    def on_size(self, *args):
        self.scale = self.line_length / self.density
        self.recenter()
    def index_of(self, val):
        '''returns the index that should be equivalent to a selection value
        ``val``. Should be overriden if necessary.'''
        return val
    def center_on(self, val, animate=True):
        Animation.stop_all(self)
        center_index = self.index_of(val)
        print hasattr(Tickline, 'max_pos')
        half_length = self.line_length / 2. / self.scale
        index_0 = center_index - half_length
        index_1 = center_index + half_length
        if animate:
            anim = Animation(index_0=index_0, index_1=index_1,
                             duration=self.center_duration)
            anim.on_complete = lambda *args: self._centered()
            anim.start(self)
        else:
            self.index_0 = index_0
            self.index_1 = index_1
            self._centered()
    def on_centered(self, *args):
        '''event that fires when the operation :meth:`center_on` completes.
        (and by extension, when :meth:`center` or :meth:`select_and_center`
        completes). By default it doesn't do anything.'''
        pass

    def _centered(self, *args):
        print 'animation complete: calling "_centered"'
        self._trigger_calibrate()
        self.dispatch('on_centered')
    def center(self, animate=True):
        self.center_on(self.selected_value, animate)
    def select_and_center(self, val, *args, **kw):
        '''set :attr:`selected_value` to ``val`` and center on it. If
        :attr:`selected_value` is already ``val``, return False; else return
        True.'''
        if self.selected_value == val:
            return False
        self.selected_value = val
        self.center(*args, **kw)
        return True
    def is_rolling(self):
        return self.scroll_effect.velocity != 0
    def on_int_valued(self, *args):
        if self.tick:
            self.tick.int_valued = self.int_valued
    def on_format_str(self, *args):
        if self.tick:
            self.tick.format_str = self.format_str

class CyclicRoulette(Roulette):
    tick_cls = ObjectProperty(CyclicSlot)
    cycle = NumericProperty(10)
    zero_indexed = BooleanProperty(False)
    format_str = StringProperty('{}')
    int_valued = BooleanProperty(True)

    def __init__(self, **kw):
        super(CyclicRoulette, self).__init__(**kw)
        self.selected_value = self.tick.first_value
        self.center()

    def on_tick(self, *args):
        tick = self.tick
        if tick:
            tick.cycle = self.cycle
            tick.zero_indexed = self.zero_indexed
            tick.format_str = self.format_str
            tick.int_valued = self.int_valued
    def on_cycle(self, *args):
        if self.tick:
            self.tick.cycle = self.cycle
    def on_zero_indexed(self, *args):
        if self.tick:
            self.tick.zero_indexed = self.zero_indexed
    def index_of(self, val):
        tick = self.tick
        if not tick:
            return val
        return tick.index_of(val, tick.localize(self.index_mid))

Builder.load_string('''
<TimeFormatCyclicRoulette>:
    zero_indexed: True
    format_str: '{:02d}'
''')
class TimeFormatCyclicRoulette(CyclicRoulette):
    pass

if __name__ == '__main__':
    from kivy.base import runTouchApp
    from kivy.uix.boxlayout import BoxLayout
    b = BoxLayout(
#                   size=[500, 300], size_hint=[None, None],
#                   pos_hint={'x': .1, 'y': .1}
                  )
    b.add_widget(CyclicRoulette(cycle=24, zero_indexed=True, format_str='{:02d}'))
    b.add_widget(CyclicRoulette(cycle=60, zero_indexed=True, format_str='{:02d}'))
    b.add_widget(CyclicRoulette(cycle=60, zero_indexed=True, format_str='{:02d}'))
#     year = Roulette()
#     year.select_and_center(2013)
#     b.add_widget(year)
    b.add_widget(TimeFormatCyclicRoulette(cycle=24))
#     b.add_widget(HourRoulette())
#     b.add_widget(MinuteRoulette())
#     b.add_widget(SecondRoulette())
# #     for i in xrange(5):
#         b.add_widget(SecondRoulette())
    runTouchApp(b)

<commit_msg>rearranged code and wrote docs on ``Roulette``.<commit_after>'''
Roulette
========

Dependencies
------------

*. the garden package ``kivy.garden.tickline``. Use ``garden install tickline``
    to install it like any other garden package.

*. the garden package ``kivy.garden.roulettescroll``.

'''
from kivy.garden.roulettescroll import RouletteScrollEffect
from kivy.garden.tickline import Tick, Tickline, TickLabeller
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.core.text import Label as CoreLabel
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from kivy.metrics import sp, dp
from kivy.properties import ListProperty, ObjectProperty, AliasProperty, \
    NumericProperty, BooleanProperty, StringProperty, OptionProperty

class SlotLabeller(TickLabeller):
    def __init__(self, tickline):
        self.instructions = {}
        self.re_init()
        self.tickline = tickline

    def re_init(self):
        self.to_pop = set(self.instructions)
        self.to_push = []

    def register(self, tick, tick_index, tick_info):
        tickline = self.tickline
        if tick_index not in self.instructions:
            self.to_push.append(tick_index)
            texture = tick.get_label_texture(tick_index)
        else:
            self.to_pop.remove(tick_index)
            texture = self.instructions[tick_index].texture
        if texture:
            if tickline.is_vertical():
                tick_pos = tick_info[1] + tick_info[3] / 2
                pos = (tickline.center_x - texture.width / 2,
                       tick_pos - texture.height / 2)
            else:
                tick_pos = tick_info[0] + tick_info[2] / 2
                pos = (tick_pos - texture.width / 2,
                       tickline.center_y - texture.height / 2)
            # only need to update the position if label is saved
            self.instructions.setdefault(tick_index,
                Rectangle(texture=texture, size=texture.size,
                          group=self.group_id)).pos = pos

    def make_labels(self):
        canvas = self.tickline.canvas
        for index in self.to_push:
            rect = self.instructions[index]
            canvas.add(rect)
        for index in self.to_pop:
            rect = self.instructions.pop(index)
            canvas.remove(rect)

#===============================================================================
# Slots
#===============================================================================

class Slot(Tick):
    tick_size = ListProperty([0, 0])
    font_size = NumericProperty('20sp')
    int_valued = BooleanProperty(True)
    format_str = StringProperty('{}')
    def value_str(self, value):
        return self.format_str.format(value)
    def slot_value(self, index, *args, **kw):
        '''returns the selection value that corresponds to ``index``.
        Should be overriden if necessary.'''
        if self.int_valued:
            return int(round(index))
        return index
    def index_of(self, val, *args, **kw):
        '''returns the index that corresponds to a selection value ``val``.
        Should be override if necessary.'''
        return val
    def get_label_texture(self, index, **kw):
        label = CoreLabel(text=self.value_str(self.slot_value(index)),
                          font_size=self.font_size, **kw)
        label.refresh()
        return label.texture

class CyclicSlot(Slot):
    cycle = NumericProperty(10)
    zero_indexed = BooleanProperty(False)

    def get_first_value(self):
        return 0 if self.zero_indexed else 1
    def set_first_value(self, val):
        self.zero_indexed = not val
    first_value = AliasProperty(get_first_value, set_first_value, cache=True,
                                bind=['zero_indexed'])

    def slot_value(self, index):
        cycle = self.cycle
        val = index % cycle + 1 - self.zero_indexed
        val = Slot.slot_value(self, val)
        if val >= cycle + 1 - self.zero_indexed:
            val -= cycle
        return val

    def index_of(self, val, current_index, *args, **kw):
        '''returns the closest index to ``current_index`` that would correspond
        to ``val``. All indices should be localized.'''
        if self.int_valued:
            val = int(round(val))
        zero_indexed = self.zero_indexed
        cycle = self.cycle
        if not (1 - zero_indexed) <= val <= cycle - zero_indexed:
            raise ValueError('value must be between {} and {}; {} is given'.
                             format(1 - zero_indexed, cycle - zero_indexed, val))
        base_index = val - 1 + self.zero_indexed
        n = round((current_index - base_index) / cycle)
        index = n * cycle + base_index
        return index

#===============================================================================
# Roulettes
#===============================================================================

Builder.load_string('''
<Roulette>:
    canvas.after:
        Color:
            rgb: 1, 1, 1, 0
        Line:
            points: self.x, self.y, self.x, self.top
        Line:
            points: self.right, self.y, self.right, self.top
        Color:
            rgba: 1, 1, 1, .3
        Rectangle:
            pos: self.pos
            size: self.width, self.height / 2
    size_hint: None, 1
''')

class Roulette(Tickline):
    __events__ = ('on_centered',)

    #===========================================================================
    # overrides
    #===========================================================================

    labeller_cls = ObjectProperty(SlotLabeller)
    zoomable = BooleanProperty(False)
    draw_line = BooleanProperty(False)
    background_color = ListProperty([0.06, .07, .22])
    font_size = NumericProperty('20sp')
    width = NumericProperty('60dp')

    # doesn't make sense to have more than 1 tick
    tick = ObjectProperty(None)

    def get_ticks(self):
        if self.tick:
            return [self.tick]
        else:
            return []
    def set_ticks(self, val):
        self.tick = val[0]
    ticks = AliasProperty(get_ticks, set_ticks, bind=['tick'])

    #===========================================================================
    # public attributes
    #===========================================================================

    selected_value = ObjectProperty(None)
    '''the currently selected value.'''

    format_str = StringProperty('{}')
    '''formatting spec string for the values displayed.'''

    tick_cls = ObjectProperty(Slot)
    '''The class of the tick in this roulette. Defaults to
    :class:`Slot`. Should be overriden as needed by child class.'''

    int_valued = BooleanProperty(True)
    '''indicates whether the values should be displayed as integers.'''

    scroll_effect_cls = ObjectProperty(RouletteScrollEffect)

    # has to be negative so that ``ScrollEffect.trigger_velocity_update``
    # is always called
    drag_threshold = NumericProperty(-1)
    '''this is passed to the ``drag_threshold`` of :attr:`scroll_effect_cls`.

    It is by default set to -1 to turn off the drag threshold.
    '''

    center_duration = NumericProperty(.3)
    '''duration for the animation of :meth:`center_on`.'''

    density = NumericProperty(4.2)
    '''determines how many slots are shown at a time.'''

    def get_rolling_value(self):
        return self.tick.slot_value(self.tick.localize(self.index_mid))
    def set_rolling_value(self, val):
        self.index_mid = self.tick.globalize(val)
    rolling_value = AliasProperty(get_rolling_value,
                                    set_rolling_value,
                                    bind=['index_mid'])
    '''the val indicated by whatever slot is in the middle of the roulette.
    If the roulette is still, then :attr:`rolling_value` is equal to
    :attr:`selected_value`. Otherwise, they shouldn't be equal.

    .. note::
        This property is not stable under resizing, since often that will
        change the slot in the middle.'''

    def __init__(self, **kw):
        self.tick = Slot()
        super(Roulette, self).__init__(**kw)
        self.scale = dp(10)
        self._trigger_set_selection = \
                Clock.create_trigger(self.set_selected_value)
        self.tick = self.tick_cls()
        self._trigger_calibrate()

    def on_tick_cls(self, *args):
        self.tick = self.tick_cls()
    def on_tick(self, *args):
        tick = self.tick
        if tick:
            tick.font_size = self.font_size
            tick.int_valued = self.int_valued
            tick.format_str = self.format_str
    def on_size(self, *args):
        self.scale = self.line_length / self.density
        self.recenter()
    def on_int_valued(self, *args):
        if self.tick:
            self.tick.int_valued = self.int_valued
    def on_format_str(self, *args):
        if self.tick:
            self.tick.format_str = self.format_str

    def get_anchor(self):
        '''returns a legal stopping value for the :class:`RouletteScrollEffect`.
        Should be overriden if necessary.'''
        return 0
    def _update_effect_constants(self, *args):
        if not super(Roulette, self)._update_effect_constants(*args):
            return
        effect = self.scroll_effect
        scale = self.scale
        effect.pull_back_velocity = sp(50) / scale
    def calibrate_scroll_effect(self, *args, **kw):
        if not super(Roulette, self).calibrate_scroll_effect(*args, **kw):
            return
        anchor = self.get_anchor()
        effect = self.scroll_effect
        effect.interval = 1. / self.tick.scale_factor
        effect.anchor = anchor
        effect.on_coasted_to_stop = self._trigger_set_selection
    def set_selected_value(self, *args):
        '''set :attr:`selected_value` to the currently slot.'''
        self.selected_value = self.round_(self.rolling_value)
    def round_(self, val):
        '''round an arbitrary rolling value to a legal selection value.
        Should be overriden if necessary.'''
        if self.int_valued:
            return int(round(val))
        return round(val)
    def recenter(self, *args):
        if self.selected_value is not None:
            self.center_on(self.selected_value)
        self._trigger_calibrate()
    def index_of(self, val):
        '''returns the index that should be equivalent to a selection value
        ``val``. Should be overriden if necessary.'''
        return val
    def center_on(self, val, animate=True):
        Animation.stop_all(self)
        center_index = self.index_of(val)
        print hasattr(Tickline, 'max_pos')
        half_length = self.line_length / 2. / self.scale
        index_0 = center_index - half_length
        index_1 = center_index + half_length
        if animate:
            anim = Animation(index_0=index_0, index_1=index_1,
                             duration=self.center_duration)
            anim.on_complete = lambda *args: self._centered()
            anim.start(self)
        else:
            self.index_0 = index_0
            self.index_1 = index_1
            self._centered()
    def on_centered(self, *args):
        '''event that fires when the operation :meth:`center_on` completes.
        (and by extension, when :meth:`center` or :meth:`select_and_center`
        completes). By default it doesn't do anything.'''
        pass

    def _centered(self, *args):
        print 'animation complete: calling "_centered"'
        self._trigger_calibrate()
        self.dispatch('on_centered')
    def center(self, animate=True):
        self.center_on(self.selected_value, animate)
    def select_and_center(self, val, *args, **kw):
        '''set :attr:`selected_value` to ``val`` and center on it. If
        :attr:`selected_value` is already ``val``, return False; else return
        True.'''
        if self.selected_value == val:
            return False
        self.selected_value = val
        self.center(*args, **kw)
        return True
    def is_rolling(self):
        return self.scroll_effect.velocity != 0

class CyclicRoulette(Roulette):
    tick_cls = ObjectProperty(CyclicSlot)
    cycle = NumericProperty(10)
    zero_indexed = BooleanProperty(False)
    format_str = StringProperty('{}')
    int_valued = BooleanProperty(True)

    def __init__(self, **kw):
        super(CyclicRoulette, self).__init__(**kw)
        self.selected_value = self.tick.first_value
        self.center()

    def on_tick(self, *args):
        tick = self.tick
        if tick:
            tick.cycle = self.cycle
            tick.zero_indexed = self.zero_indexed
            tick.format_str = self.format_str
            tick.int_valued = self.int_valued
    def on_cycle(self, *args):
        if self.tick:
            self.tick.cycle = self.cycle
    def on_zero_indexed(self, *args):
        if self.tick:
            self.tick.zero_indexed = self.zero_indexed
    def index_of(self, val):
        tick = self.tick
        if not tick:
            return val
        return tick.index_of(val, tick.localize(self.index_mid))

class TimeFormatCyclicRoulette(CyclicRoulette):
    '''formatted roulette for displaying time.'''
    zero_indexed = BooleanProperty(True)
    format_str = StringProperty('{:02d}')

if __name__ == '__main__':
    from kivy.base import runTouchApp
    from kivy.uix.boxlayout import BoxLayout
    b = BoxLayout(
#                   size=[500, 300], size_hint=[None, None],
#                   pos_hint={'x': .1, 'y': .1}
                  )
    b.add_widget(CyclicRoulette(cycle=24, zero_indexed=True, format_str='{:02d}'))
    b.add_widget(CyclicRoulette(cycle=60, zero_indexed=True, format_str='{:02d}'))
    b.add_widget(CyclicRoulette(cycle=60, zero_indexed=True, format_str='{:02d}'))
#     year = Roulette()
#     year.select_and_center(2013)
#     b.add_widget(year)
    b.add_widget(TimeFormatCyclicRoulette(cycle=24))
#     b.add_widget(HourRoulette())
#     b.add_widget(MinuteRoulette())
#     b.add_widget(SecondRoulette())
# #     for i in xrange(5):
#         b.add_widget(SecondRoulette())
    runTouchApp(b)

<|endoftext|>


<commit_before>XPM_MOD_VERSION = '1.2.0'
XPM_MOD_URL = 'https://github.com/juho-p/wot-debugserver'
XPM_MOD_UPDATE_URL = ''
XPM_GAME_VERSIONS = ['0.9.5']

run = True

import datetime
import tcprepl

def log(text):
    ds = datetime.time.strftime(datetime.datetime.now().time(), '%H:%M')
    print 'replserver %s: %s' % (ds, text)

def run_server():
    log('run server...')
    try:
        while True:
            tcprepl.run_repl()
            log('REPL stopped, restarting...')
    except:
        log('* Crashed *')
        import traceback
        traceback.print_exc()
    log('Server stopped!')

if run:
    log('starting..')

    try:
        import threading
        thread = threading.Thread(target=run_server, args=())
        thread.setDaemon(True)
        thread.start()

        log('thread started..')
    except:
        import traceback
        traceback.print_exc()
<commit_msg>update version<commit_after>XPM_MOD_VERSION = '1.2.1'
XPM_MOD_URL = 'https://github.com/juho-p/wot-debugserver'
XPM_MOD_UPDATE_URL = ''
XPM_GAME_VERSIONS = ['0.9.5']

run = True

import datetime
import tcprepl

def log(text):
    ds = datetime.time.strftime(datetime.datetime.now().time(), '%H:%M')
    print 'replserver %s: %s' % (ds, text)

def run_server():
    log('run server...')
    try:
        while True:
            tcprepl.run_repl()
            log('REPL stopped, restarting...')
    except:
        log('* Crashed *')
        import traceback
        traceback.print_exc()
    log('Server stopped!')

if run:
    log('starting..')

    try:
        import threading
        thread = threading.Thread(target=run_server, args=())
        thread.setDaemon(True)
        thread.start()

        log('thread started..')
    except:
        import traceback
        traceback.print_exc()
<|endoftext|>