<commit_before># -*- coding: utf-8 -*-
# libavg - Media Playback Engine.
# Copyright (C) 2003-2011 Ulrich von Zadow
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Current versions can be found at www.libavg.de
#
# Original author of this file is Henrik Thoms

from libavg import avg, statemachine, utils
import gesture
from helper import *

g_Player = avg.Player.get()

class Button(avg.DivNode):
    STATE_DISABLED = 1
    STATE_UP       = 2
    STATE_DOWN     = 3

    def __init__(self, upNode=None, downNode=None, disabledNode=None,
            activeAreaNode=None, pressHandler=None, clickHandler=None,
            stateChangeHandler=None, parent=None, **kwargs):
        super(Button, self).__init__(**kwargs)
        if parent:
            parent.appendChild(self)

        self.__upNode = upNode
        self.__downNode = downNode
        self.__disabledNode = disabledNode
        self.__activeAreaNode = activeAreaNode

        self.__pressCallback = utils.methodref(pressHandler)
        self.__clickCallback = utils.methodref(clickHandler)
        self.__stateChangeCallback = utils.methodref(stateChangeHandler)

        self.__capturedCursorIds = set()
        self.__overCursorIds = set()

        self.__isCheckable = False
        self.__isToggled = False

        self.__isOver = False
        self.__state = Button.STATE_UP

        if self.__upNode and self.__downNode:
            self.__setupNodes()

    def delete(self):
        self.__pressCallback = None
        self.__clickCallback = None
        self.__stateChangeCallback = None
        self.__deactivateEventHandlers()

    def setEventHandler(self, type, source, func):
        raise RuntimeError("Setting event handlers for buttons is not supported")

    def getUpNode(self):
        return self.__upNode

    def getDownNode(self):
        return self.__downNode

    def getDisabledNode(self):
        return self.__disabledNode

    def setNodes(self, upNode, downNode, disabledNode = None, activeAreaNode = None):
        if self.__activeAreaNode and self.isEnabled():
            self.__deactivateEventHandlers()
        self.__upNode = upNode
        self.__downNode = downNode
        self.__disabledNode = disabledNode
        self.__activeAreaNode = activeAreaNode
        self.__setupNodes()

    def setPressHandler(self, handler):
        self.__pressCallback = utils.methodref(handler)

    def setClickHandler(self, handler):
        self.__clickCallback = utils.methodref(handler)

    def setCheckable(self, val):
        self.__isCheckable = val

    def isCheckable(self):
        return self.__isCheckable

    def setChecked(self, val):
        assert(self.__isCheckable)
        assert(self.isEnabled())
        self.__isToggled = val
        state = Button.STATE_DOWN if self.__isToggled else Button.STATE_UP
        self.__changeState(state)

    def isChecked(self):
        assert(self.__isCheckable)
        # XXX: Shouldn't this check self.__isToggled?
        return self.__state == Button.STATE_DOWN

    def setEnabled(self, isEnabled):
        if (isEnabled == self.isEnabled()):
            # No state change
            return

        state = Button.STATE_DISABLED if not(isEnabled) else Button.STATE_UP
        self.__changeState(state)

        if self.__state == Button.STATE_DISABLED:
            self.__deactivateEventHandlers()
            self.__overCursorIds = set()
        else:
            self.__activateEventHandlers()

    def isEnabled(self):
        return self.__state != Button.STATE_DISABLED

    def __setupNodes(self):
        while self.getNumChildren() > 0:
            self.removeChild(self.getChild(0))

        self.appendChild(self.__upNode)
        self.appendChild(self.__downNode)

        if self.__disabledNode:
            self.appendChild(self.__disabledNode)

        if self.__activeAreaNode == None:
            self.__activeAreaNode = avg.RectNode(opacity=0, size=self.__upNode.size)
        self.appendChild(self.__activeAreaNode)

        self.size = self.__activeAreaNode.size
        self.__updateNodesVisibility()
        if self.isEnabled():
            self.__activateEventHandlers()

    def __updateNodesVisibility(self):
        for element in (self.__upNode, self.__downNode, self.__disabledNode):
            if element:
                element.active = False

        if self.__state == Button.STATE_UP:
            activeNode = self.__upNode
        elif self.__state == Button.STATE_DOWN:
            activeNode = self.__downNode
        elif self.__state == Button.STATE_DISABLED:
            activeNode = self.__disabledNode
        else:
            # This state doesn't exist.
            assert(False)

        activeNode.active = True

    def __changeState(self, state):
        self.__state = state
        self.__updateNodesVisibility()
        utils.callWeakRef(self.__stateChangeCallback, state)

    def __captureCursor(self, id):
        self.__capturedCursorIds.add(id)
        self.__activeAreaNode.setEventCapture(id)

    def __releaseCapturedCursor(self, id):
        self.__capturedCursorIds.remove(id)
        self.releaseEventCapture(id)

    def __isCursorCaptured(self, id):
        return id in self.__capturedCursorIds

    def __getNumberOfCapturedCursors(self):
        return len(self.__capturedCursorIds)

    def __hasCapturedCursor(self):
        return len(self.__capturedCursorIds) != 0

    def __pressHandler(self, event):
        if not self.__isCursorCaptured(event.cursorid):
            self.__captureCursor(event.cursorid)

        if event.cursorid not in self.__overCursorIds:
            self.__overCursorIds.add(event.cursorid)

        if self.__getNumberOfCapturedCursors() <= 1:
            self.__changeState(Button.STATE_DOWN)
            utils.callWeakRef(self.__pressCallback, event)

    def __releaseHandler(self, event):
        numberOfCapturedCursors = self.__getNumberOfCapturedCursors()
        numberOfOverCursors = len(self.__overCursorIds)

        if self.__isCursorCaptured(event.cursorid):
            self.__releaseCapturedCursor(event.cursorid)

        if event.cursorid in self.__overCursorIds:
            self.__overCursorIds.remove(event.cursorid)

        if numberOfCapturedCursors == 1 and numberOfOverCursors == 1:
            newState = Button.STATE_UP
            if self.isCheckable():
                self.__isToggled = not self.__isToggled
                if self.__isToggled:
                    newState = Button.STATE_DOWN

            self.__changeState(newState)

            utils.callWeakRef(self.__clickCallback, event)

    def __overHandler(self, event):
        if event.cursorid not in self.__overCursorIds:
            self.__overCursorIds.add(event.cursorid)

        if self.__hasCapturedCursor() and len(self.__overCursorIds):
            self.__changeState(Button.STATE_DOWN)

        self.__isOver = not(self.__isOver)
        return True

    def __outHandler(self, event):
        if event.cursorid in self.__overCursorIds:
            self.__overCursorIds.remove(event.cursorid)

        if self.__hasCapturedCursor() and not len(self.__overCursorIds):
            newState = Button.STATE_UP
            if self.isCheckable():
                if self.__isToggled:
                    newState = Button.STATE_DOWN
            self.__changeState(newState)

        self.__isOver = not(self.__isOver)
        return True

    def __activateEventHandlers(self):
        def setOneHandler(type, handler):
            self.__activeAreaNode.connectEventHandler(type, avg.MOUSE | avg.TOUCH,
                    self, handler)

        setOneHandler(avg.CURSORDOWN, self.__pressHandler)
        setOneHandler(avg.CURSORUP, self.__releaseHandler)
        setOneHandler(avg.CURSOROVER, self.__overHandler)
        setOneHandler(avg.CURSOROUT, self.__outHandler)

    def __deactivateEventHandlers(self):
        for id in self.__capturedCursorIds:
            self.releaseEventCapture(id)
        self.__capturedCursorIds = set()
        self.__activeAreaNode.disconnectEventHandler(self)

class TouchButton(avg.DivNode):

    def __init__(self, upNode, downNode, disabledNode=None, activeAreaNode=None,
            fatFingerEnlarge=False, clickHandler=None, **kwargs):
        super(TouchButton, self).__init__(**kwargs)

        self.__upNode = upNode
        self.__downNode = downNode
        self.__disabledNode = disabledNode
        self.__activeAreaNode = activeAreaNode

        self.__clickHandler = utils.methodref(clickHandler)

        self.__stateMachine = statemachine.StateMachine("TouchButton", "UP")
        self.__stateMachine.addState("UP", ("DOWN", "DISABLED"),
                enterFunc=self.enterUp, leaveFunc=self.leaveUp)
        self.__stateMachine.addState("DOWN", ("UP", "DISABLED"),
                enterFunc=self.enterDown, leaveFunc=self.leaveDown)
        self.__stateMachine.addState("DISABLED", ("UP", "DOWN"),
                enterFunc=self.enterDisabled, leaveFunc=self.leaveDisabled)

        self.appendChild(self.__upNode)
        self.__upNode.active = True
        self.appendChild(self.__downNode)
        self.__downNode.active = False

        if self.__disabledNode:
            self.appendChild(self.__disabledNode)
            self.__disabledNode.active = False

        if fatFingerEnlarge:
            if self.__activeAreaNode != None:
                raise(RuntimeError(
                    "TouchButton: Can't specify both fatFingerEnlarge and activeAreaNode"))
            size = upNode.size
            minSize = 20*g_Player.getPixelsPerMM()
            size = avg.Point2D(max(minSize, size.x), max(minSize, size.y))
            self.__activeAreaNode = avg.RectNode(size=size, opacity=0, parent=self)
        else:
            if self.__activeAreaNode == None:
                self.__activeAreaNode = self.__upNode
            else:
                self.appendChild(self.__activeAreaNode)

        self.__tapRecognizer = gesture.TapRecognizer(self.__activeAreaNode,
                possibleHandler=self.__onDown,
                detectedHandler=self.__onTap,
                failHandler=self.__onTapFail)

    @classmethod
    def fromSrc(cls, upSrc, downSrc, disabledSrc=None, **kwargs):
        upNode = avg.ImageNode(href=upSrc)
        downNode = avg.ImageNode(href=downSrc)
        if disabledSrc != None:
            disabledNode = avg.ImageNode(href=disabledSrc)
        else:
            disabledNode = None
        return TouchButton(upNode=upNode, downNode=downNode, disabledNode=disabledNode,
                **kwargs)

    def getEnabled(self):
        return self.__stateMachine.state != "DISABLED"

    def setEnabled(self, enabled):
        if enabled:
            if self.__stateMachine.state == "DISABLED":
                self.__stateMachine.changeState("UP")
        else:
            if self.__stateMachine.state != "DISABLED":
                self.__stateMachine.changeState("DISABLED")

    enabled = property(getEnabled, setEnabled)

    def __onDown(self, event):
        self.__stateMachine.changeState("DOWN")

    def __onTap(self, event):
        self.__stateMachine.changeState("UP")
        utils.callWeakRef(self.__clickHandler)

    def __onTapFail(self, event):
        self.__stateMachine.changeState("UP")

    def enterUp(self):
        self.__upNode.active = True

    def leaveUp(self):
        self.__upNode.active = False

    def enterDown(self):
        self.__downNode.active = True

    def leaveDown(self):
        self.__downNode.active = False

    def enterDisabled(self):
        if self.__disabledNode:
            self.__disabledNode.active = True
        self.__tapRecognizer.enable(False)

    def leaveDisabled(self):
        if self.__disabledNode:
            self.__disabledNode.active = False
        self.__tapRecognizer.enable(True)

<commit_msg>libavg_togglebutotn: changed statechange methods from public to private in ToggleButton <commit_after># -*- coding: utf-8 -*-
# libavg - Media Playback Engine.
# Copyright (C) 2003-2011 Ulrich von Zadow
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Current versions can be found at www.libavg.de
#
# Original author of this file is Henrik Thoms

from libavg import avg, statemachine, utils
import gesture
from helper import *

g_Player = avg.Player.get()

class Button(avg.DivNode):
    STATE_DISABLED = 1
    STATE_UP       = 2
    STATE_DOWN     = 3

    def __init__(self, upNode=None, downNode=None, disabledNode=None,
            activeAreaNode=None, pressHandler=None, clickHandler=None,
            stateChangeHandler=None, parent=None, **kwargs):
        super(Button, self).__init__(**kwargs)
        if parent:
            parent.appendChild(self)

        self.__upNode = upNode
        self.__downNode = downNode
        self.__disabledNode = disabledNode
        self.__activeAreaNode = activeAreaNode

        self.__pressCallback = utils.methodref(pressHandler)
        self.__clickCallback = utils.methodref(clickHandler)
        self.__stateChangeCallback = utils.methodref(stateChangeHandler)

        self.__capturedCursorIds = set()
        self.__overCursorIds = set()

        self.__isCheckable = False
        self.__isToggled = False

        self.__isOver = False
        self.__state = Button.STATE_UP

        if self.__upNode and self.__downNode:
            self.__setupNodes()

    def delete(self):
        self.__pressCallback = None
        self.__clickCallback = None
        self.__stateChangeCallback = None
        self.__deactivateEventHandlers()

    def setEventHandler(self, type, source, func):
        raise RuntimeError("Setting event handlers for buttons is not supported")

    def getUpNode(self):
        return self.__upNode

    def getDownNode(self):
        return self.__downNode

    def getDisabledNode(self):
        return self.__disabledNode

    def setNodes(self, upNode, downNode, disabledNode = None, activeAreaNode = None):
        if self.__activeAreaNode and self.isEnabled():
            self.__deactivateEventHandlers()
        self.__upNode = upNode
        self.__downNode = downNode
        self.__disabledNode = disabledNode
        self.__activeAreaNode = activeAreaNode
        self.__setupNodes()

    def setPressHandler(self, handler):
        self.__pressCallback = utils.methodref(handler)

    def setClickHandler(self, handler):
        self.__clickCallback = utils.methodref(handler)

    def setCheckable(self, val):
        self.__isCheckable = val

    def isCheckable(self):
        return self.__isCheckable

    def setChecked(self, val):
        assert(self.__isCheckable)
        assert(self.isEnabled())
        self.__isToggled = val
        state = Button.STATE_DOWN if self.__isToggled else Button.STATE_UP
        self.__changeState(state)

    def isChecked(self):
        assert(self.__isCheckable)
        # XXX: Shouldn't this check self.__isToggled?
        return self.__state == Button.STATE_DOWN

    def setEnabled(self, isEnabled):
        if (isEnabled == self.isEnabled()):
            # No state change
            return

        state = Button.STATE_DISABLED if not(isEnabled) else Button.STATE_UP
        self.__changeState(state)

        if self.__state == Button.STATE_DISABLED:
            self.__deactivateEventHandlers()
            self.__overCursorIds = set()
        else:
            self.__activateEventHandlers()

    def isEnabled(self):
        return self.__state != Button.STATE_DISABLED

    def __setupNodes(self):
        while self.getNumChildren() > 0:
            self.removeChild(self.getChild(0))

        self.appendChild(self.__upNode)
        self.appendChild(self.__downNode)

        if self.__disabledNode:
            self.appendChild(self.__disabledNode)

        if self.__activeAreaNode == None:
            self.__activeAreaNode = avg.RectNode(opacity=0, size=self.__upNode.size)
        self.appendChild(self.__activeAreaNode)

        self.size = self.__activeAreaNode.size
        self.__updateNodesVisibility()
        if self.isEnabled():
            self.__activateEventHandlers()

    def __updateNodesVisibility(self):
        for element in (self.__upNode, self.__downNode, self.__disabledNode):
            if element:
                element.active = False

        if self.__state == Button.STATE_UP:
            activeNode = self.__upNode
        elif self.__state == Button.STATE_DOWN:
            activeNode = self.__downNode
        elif self.__state == Button.STATE_DISABLED:
            activeNode = self.__disabledNode
        else:
            # This state doesn't exist.
            assert(False)

        activeNode.active = True

    def __changeState(self, state):
        self.__state = state
        self.__updateNodesVisibility()
        utils.callWeakRef(self.__stateChangeCallback, state)

    def __captureCursor(self, id):
        self.__capturedCursorIds.add(id)
        self.__activeAreaNode.setEventCapture(id)

    def __releaseCapturedCursor(self, id):
        self.__capturedCursorIds.remove(id)
        self.releaseEventCapture(id)

    def __isCursorCaptured(self, id):
        return id in self.__capturedCursorIds

    def __getNumberOfCapturedCursors(self):
        return len(self.__capturedCursorIds)

    def __hasCapturedCursor(self):
        return len(self.__capturedCursorIds) != 0

    def __pressHandler(self, event):
        if not self.__isCursorCaptured(event.cursorid):
            self.__captureCursor(event.cursorid)

        if event.cursorid not in self.__overCursorIds:
            self.__overCursorIds.add(event.cursorid)

        if self.__getNumberOfCapturedCursors() <= 1:
            self.__changeState(Button.STATE_DOWN)
            utils.callWeakRef(self.__pressCallback, event)

    def __releaseHandler(self, event):
        numberOfCapturedCursors = self.__getNumberOfCapturedCursors()
        numberOfOverCursors = len(self.__overCursorIds)

        if self.__isCursorCaptured(event.cursorid):
            self.__releaseCapturedCursor(event.cursorid)

        if event.cursorid in self.__overCursorIds:
            self.__overCursorIds.remove(event.cursorid)

        if numberOfCapturedCursors == 1 and numberOfOverCursors == 1:
            newState = Button.STATE_UP
            if self.isCheckable():
                self.__isToggled = not self.__isToggled
                if self.__isToggled:
                    newState = Button.STATE_DOWN

            self.__changeState(newState)

            utils.callWeakRef(self.__clickCallback, event)

    def __overHandler(self, event):
        if event.cursorid not in self.__overCursorIds:
            self.__overCursorIds.add(event.cursorid)

        if self.__hasCapturedCursor() and len(self.__overCursorIds):
            self.__changeState(Button.STATE_DOWN)

        self.__isOver = not(self.__isOver)
        return True

    def __outHandler(self, event):
        if event.cursorid in self.__overCursorIds:
            self.__overCursorIds.remove(event.cursorid)

        if self.__hasCapturedCursor() and not len(self.__overCursorIds):
            newState = Button.STATE_UP
            if self.isCheckable():
                if self.__isToggled:
                    newState = Button.STATE_DOWN
            self.__changeState(newState)

        self.__isOver = not(self.__isOver)
        return True

    def __activateEventHandlers(self):
        def setOneHandler(type, handler):
            self.__activeAreaNode.connectEventHandler(type, avg.MOUSE | avg.TOUCH,
                    self, handler)

        setOneHandler(avg.CURSORDOWN, self.__pressHandler)
        setOneHandler(avg.CURSORUP, self.__releaseHandler)
        setOneHandler(avg.CURSOROVER, self.__overHandler)
        setOneHandler(avg.CURSOROUT, self.__outHandler)

    def __deactivateEventHandlers(self):
        for id in self.__capturedCursorIds:
            self.releaseEventCapture(id)
        self.__capturedCursorIds = set()
        self.__activeAreaNode.disconnectEventHandler(self)

class TouchButton(avg.DivNode):

    def __init__(self, upNode, downNode, disabledNode=None, activeAreaNode=None,
            fatFingerEnlarge=False, clickHandler=None, **kwargs):
        super(TouchButton, self).__init__(**kwargs)

        self.__upNode = upNode
        self.__downNode = downNode
        self.__disabledNode = disabledNode
        self.__activeAreaNode = activeAreaNode

        self.__clickHandler = utils.methodref(clickHandler)

        self.__stateMachine = statemachine.StateMachine("TouchButton", "UP")
        self.__stateMachine.addState("UP", ("DOWN", "DISABLED"),
                enterFunc=self.__enterUp, leaveFunc=self.__leaveUp)
        self.__stateMachine.addState("DOWN", ("UP", "DISABLED"),
                enterFunc=self.__enterDown, leaveFunc=self.__leaveDown)
        self.__stateMachine.addState("DISABLED", ("UP", "DOWN"),
                enterFunc=self.__enterDisabled, leaveFunc=self.__leaveDisabled)

        self.appendChild(self.__upNode)
        self.__upNode.active = True
        self.appendChild(self.__downNode)
        self.__downNode.active = False

        if self.__disabledNode:
            self.appendChild(self.__disabledNode)
            self.__disabledNode.active = False

        if fatFingerEnlarge:
            if self.__activeAreaNode != None:
                raise(RuntimeError(
                    "TouchButton: Can't specify both fatFingerEnlarge and activeAreaNode"))
            size = upNode.size
            minSize = 20*g_Player.getPixelsPerMM()
            size = avg.Point2D(max(minSize, size.x), max(minSize, size.y))
            self.__activeAreaNode = avg.RectNode(size=size, opacity=0, parent=self)
        else:
            if self.__activeAreaNode == None:
                self.__activeAreaNode = self.__upNode
            else:
                self.appendChild(self.__activeAreaNode)

        self.__tapRecognizer = gesture.TapRecognizer(self.__activeAreaNode,
                possibleHandler=self.__onDown,
                detectedHandler=self.__onTap,
                failHandler=self.__onTapFail)

    @classmethod
    def fromSrc(cls, upSrc, downSrc, disabledSrc=None, **kwargs):
        upNode = avg.ImageNode(href=upSrc)
        downNode = avg.ImageNode(href=downSrc)
        if disabledSrc != None:
            disabledNode = avg.ImageNode(href=disabledSrc)
        else:
            disabledNode = None
        return TouchButton(upNode=upNode, downNode=downNode, disabledNode=disabledNode,
                **kwargs)

    def getEnabled(self):
        return self.__stateMachine.state != "DISABLED"

    def setEnabled(self, enabled):
        if enabled:
            if self.__stateMachine.state == "DISABLED":
                self.__stateMachine.changeState("UP")
        else:
            if self.__stateMachine.state != "DISABLED":
                self.__stateMachine.changeState("DISABLED")

    enabled = property(getEnabled, setEnabled)

    def __onDown(self, event):
        self.__stateMachine.changeState("DOWN")

    def __onTap(self, event):
        self.__stateMachine.changeState("UP")
        utils.callWeakRef(self.__clickHandler)

    def __onTapFail(self, event):
        self.__stateMachine.changeState("UP")

    def __enterUp(self):
        self.__upNode.active = True

    def __leaveUp(self):
        self.__upNode.active = False

    def __enterDown(self):
        self.__downNode.active = True

    def __leaveDown(self):
        self.__downNode.active = False

    def __enterDisabled(self):
        if self.__disabledNode:
            self.__disabledNode.active = True
        self.__tapRecognizer.enable(False)

    def __leaveDisabled(self):
        if self.__disabledNode:
            self.__disabledNode.active = False
        self.__tapRecognizer.enable(True)
<|endoftext|>


<commit_before>"""
Add the Git segment to the Powerline-shell prompt
"""
import os
import re
import subprocess

def get_git_status():
    """
    Get the status of the Git repository
    """
    has_pending_commits = True
    has_untracked_files = False
    origin_position = ""
    output = subprocess.Popen(['git', 'status', '--ignore-submodules'],
            env={"LANG": "C", "HOME": os.getenv("HOME")}, stdout=subprocess.PIPE).communicate()[0]
    try:
        lines = output.split('\n')
    except TypeError:  # Python 3
        lines = output.decode().split('\n')
    for line in lines:
        origin_status = re.findall(
            r"Your branch is (ahead|behind).*?(\d+) comm", line)
        diverged_status = re.findall(r"and have (\d+) and (\d+) different commits each", line)
        if origin_status:
            origin_position = " %d" % int(origin_status[0][1])
            if origin_status[0][0] == 'behind':
                origin_position += u'\u21E3'
            if origin_status[0][0] == 'ahead':
                origin_position += u'\u21E1'
        if diverged_status:
            origin_position = " %d%c %d%c" % (int(diverged_status[0][0]), u'\u21E1', int(diverged_status[0][1]), u'\u21E3')

        if line.find('nothing to commit') >= 0:
            has_pending_commits = False
        if line.find('Untracked files') >= 0:
            has_untracked_files = True
    return has_pending_commits, has_untracked_files, origin_position

def add_git_segment():
    """
    Add the Git segment to the Powerline-shell prompt

    This version of the function fails quickly
    """
    oldcwd = os.getcwd()
    # Fail quickly if .git is not present in cwd and parents
    found = False
    pathhead, pathtail = oldcwd, '.'
    while pathtail != '':
        if os.access(".git", os.R_OK):
            found = True
            break
        pathhead, pathtail = os.path.split(pathhead)

    if 'Not a git repo' in str(err):
        return

    if out:
        branch = out[len('refs/heads/'):].rstrip()
    else:
        branch = '(Detached)'

    has_pending_commits, has_untracked_files, origin_position = get_git_status()
    try:
        branch += origin_position
    except TypeError:
        branch = branch.decode()
        branch += origin_position
    if has_untracked_files:
        branch += ' +'

    bg = Color.REPO_CLEAN_BG
    fg = Color.REPO_CLEAN_FG
    if has_pending_commits:
        bg = Color.REPO_DIRTY_BG
        fg = Color.REPO_DIRTY_FG

    powerline.append(' %s ' % branch, fg, bg)

try:
    add_git_segment()
except OSError:
    pass
except subprocess.CalledProcessError:
    pass
<commit_msg>Add symbols for branch, has_untracked_files, has_pending_commits and clean<commit_after>"""
Add the Git segment to the Powerline-shell prompt
"""
import os
import re
import subprocess

def get_git_status():
    """
    Get the status of the Git repository
    """
    has_pending_commits = True
    has_untracked_files = False
    origin_position = ""
    output = subprocess.Popen(['git', 'status', '--ignore-submodules'],
            env={"LANG": "C", "HOME": os.getenv("HOME")}, stdout=subprocess.PIPE).communicate()[0]
    try:
        lines = output.split('\n')
    except TypeError:  # Python 3
        lines = output.decode().split('\n')
    for line in lines:
        origin_status = re.findall(
            r"Your branch is (ahead|behind).*?(\d+) comm", line)
        diverged_status = re.findall(r"and have (\d+) and (\d+) different commits each", line)
        if origin_status:
            origin_position = " %d" % int(origin_status[0][1])
            if origin_status[0][0] == 'behind':
                origin_position += u'\u21E3'
            if origin_status[0][0] == 'ahead':
                origin_position += u'\u21E1'
        if diverged_status:
            origin_position = " %d%c %d%c" % (int(diverged_status[0][0]), u'\u21E1', int(diverged_status[0][1]), u'\u21E3')

        if line.find('nothing to commit') >= 0:
            has_pending_commits = False
        if line.find('Untracked files') >= 0:
            has_untracked_files = True
    return has_pending_commits, has_untracked_files, origin_position

def add_git_segment():
    """
    Add the Git segment to the Powerline-shell prompt

    This version of the function fails quickly
    """
    oldcwd = os.getcwd()
    # Fail quickly if .git is not present in cwd and parents
    found = False
    pathhead, pathtail = oldcwd, '.'
    while pathtail != '':
        if os.access(".git", os.R_OK):
            found = True
            break
        pathhead, pathtail = os.path.split(pathhead)

    if 'Not a git repo' in str(err):
        return

    branch = u'\ue0a0 '
    if out:
        branch += out[len('refs/heads/'):].rstrip()
    else:
        branch += '(Detached)'

    has_pending_commits, has_untracked_files, origin_position = get_git_status()
    try:
        branch += origin_position
    except TypeError:
        branch = branch.decode()
        branch += origin_position
    if has_untracked_files:
        branch += u' \u271A'

    bg = Color.REPO_CLEAN_BG
    fg = Color.REPO_CLEAN_FG
    if has_pending_commits:
        bg = Color.REPO_DIRTY_BG
        fg = Color.REPO_DIRTY_FG
        branch += u' \u2718'
    else:
        branch += u' \u2714'

    powerline.append(' %s ' % branch, fg, bg)

try:
    add_git_segment()
except OSError:
    pass
except subprocess.CalledProcessError:
    pass
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# libavg - Media Playback Engine.
# Copyright (C) 2003-2011 Ulrich von Zadow
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Current versions can be found at www.libavg.de
#

from libavg import avg

def optionalCallback(handler, defaultHandler):
    if handler:
        return handler
    else:
        return defaultHandler

class ScrollPane(avg.DivNode):

    def __init__(self, contentDiv, *args, **kwargs):

        avg.DivNode.__init__(self, crop=True, *args, **kwargs)
        self.appendChild(contentDiv)
        self.__contentDiv = contentDiv

    def setContentPos(self, pos):

        def constrain(pos, limit):
            if limit < 0:
                # Content larger than container
                if pos < limit:
                    pos = limit
                elif pos > 0:
                    pos = 0
            else:
                # Content smaller than container
                if pos < 0:
                    pos = 0
                elif pos > limit:
                    pos = limit
            return pos

        maxPos = self.getMaxContentPos()
        pos = avg.Point2D(pos)
        pos.x = constrain(pos.x, maxPos.x)
        pos.y = constrain(pos.y, maxPos.y)
        self.__contentDiv.pos = pos

    def getContentPos(self):
        return self.__contentDiv.pos
    contentpos = property(getContentPos, setContentPos)

    def getMaxContentPos(self):
        maxPos = self.size - self.__contentDiv.size
        return maxPos
<commit_msg>Removed obsolete optionalCallback().<commit_after># -*- coding: utf-8 -*-
# libavg - Media Playback Engine.
# Copyright (C) 2003-2011 Ulrich von Zadow
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Current versions can be found at www.libavg.de
#

from libavg import avg

class ScrollPane(avg.DivNode):

    def __init__(self, contentDiv, *args, **kwargs):

        avg.DivNode.__init__(self, crop=True, *args, **kwargs)
        self.appendChild(contentDiv)
        self.__contentDiv = contentDiv

    def setContentPos(self, pos):

        def constrain(pos, limit):
            if limit < 0:
                # Content larger than container
                if pos < limit:
                    pos = limit
                elif pos > 0:
                    pos = 0
            else:
                # Content smaller than container
                if pos < 0:
                    pos = 0
                elif pos > limit:
                    pos = limit
            return pos

        maxPos = self.getMaxContentPos()
        pos = avg.Point2D(pos)
        pos.x = constrain(pos.x, maxPos.x)
        pos.y = constrain(pos.y, maxPos.y)
        self.__contentDiv.pos = pos

    def getContentPos(self):
        return self.__contentDiv.pos
    contentpos = property(getContentPos, setContentPos)

    def getMaxContentPos(self):
        maxPos = self.size - self.__contentDiv.size
        return maxPos
<|endoftext|>


<commit_before>import contextlib

from selenium.webdriver.support.ui import WebDriverWait
import selenium.webdriver.support.expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

class Util(object):

    def __init__(self, driver, default_timeout=2):
        self.driver = driver
        self.timeouts = [default_timeout]
        self.driver.set_script_timeout(default_timeout)
        self.osx = driver.desired_capabilities[
            "platform"].startswith("Mac OS X")

        self.windows = driver.desired_capabilities["platform"] == "XP"

        self.firefox = driver.name == "firefox"
        self.ie = driver.name == "internet explorer"
        # Only IE 9 or earlier has a problem with setting cookies...
        self._can_set_cookies = not (
            self.ie and int(driver.desired_capabilities["version"]) <= 9)

        self.ctrl_equivalent_x = self.command_x if self.osx else self.ctrl_x
        """
        When controlling a browser running in a platform other than OS X,
        equivalent to `:func:Util.ctrl_x`. Otherwise, equivalent to
        `:func:Util.command_x:`.
        """

    @property
    def can_set_cookies(self):
        """
        ``True`` if the driver we are using is able to set cookies. Bugs in
        selenium sometimes prevent this from being true.
        """
        return self._can_set_cookies

    @property
    def timeout(self):
        return self.timeouts[0]

    @contextlib.contextmanager
    def local_timeout(self, value):
        self.push_timeout(value)
        try:
            yield
        finally:
            self.pop_timeout()

    def push_timeout(self, new):
        self.timeouts[0:0] = [new]
        self.driver.set_script_timeout(new)

    def pop_timeout(self):
        if len(self.timeouts) == 1:
            raise Exception("can't pop when there is only one element on "
                            "the stack")
        # The new timeout is currently in 2nd position.
        self.driver.set_script_timeout(self.timeouts[1])
        return self.timeouts.pop(0)

    def find_element(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.presence_of_element_located(locator))

    def find_elements(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.presence_of_all_elements_located(locator))

    def find_clickable_element(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.element_to_be_clickable(locator))

    def find_descendants_by_text_re(self, parent, re):
        """
        :param parent: The parent element into which to search.
        :type parent: :class:`selenium.webdriver.remote.webelement.WebElement`
        :param re: A regular expression in JavaScript syntax.
        :type re: :class:`str`
        :returns: The descendants whose text (as returned by
                  ``jQuery().text()``) match the regular expression.

        """

        def cond(*_):
            return self.driver.execute_script("""
            var parent = arguments[0];
            var re = new RegExp(arguments[1]);
            return jQuery(parent).find("*").filter(function () {
            return re.test(jQuery(this).text().trim());
            }).toArray();
            return ret;
            """, parent, re)

        return self.wait(cond)

    #
    # The key sending methods are here as a sort of insurance policy
    # against possible issues with the various drivers that Selenium
    # uses.  We used to emit sequences like Ctrl-X or Shift-Q as
    # key_down, send_keys, key_up sequences. However, these sequence
    # are **really** expensive when using a remote setup. So the
    # following methods use a single send_keys instead. If this turns
    # out to be a problem eventually, we can still revert to the
    # key_down, send_keys, key_up sequence if we ever need to do this.
    #
    def ctrl_x(self, x, to=None):
        """
        Sends a character to the currently active element with Ctrl
        pressed. This method takes care of pressing and releasing
        Ctrl.
        """
        if to is None:
            ActionChains(self.driver) \
                .send_keys([Keys.CONTROL, x, Keys.CONTROL]) \
                .perform()
        else:
            self.send_keys(to, [Keys.CONTROL, x, Keys.CONTROL])

    #
    # The key sending methods are here as a sort of insurance policy
    # against possible issues with the various drivers that Selenium
    # uses.  We used to emit sequences like Ctrl-X or Shift-Q as
    # key_down, send_keys, key_up sequences. However, these sequence
    # are **really** expensive when using a remote setup. So the
    # following methods use a single send_keys instead. If this turns
    # out to be a problem eventually, we can still revert to the
    # key_down, send_keys, key_up sequence if we ever need to do this.
    #
    def command_x(self, x, to=None):
        """
        Sends a character to the currently active element with Command
        pressed. This method takes care of pressing and releasing
        Command.
        """
        if to is None:
            ActionChains(self.driver) \
                .send_keys([Keys.COMMAND, x, Keys.COMMAND]) \
                .perform()
        else:
            self.send_keys(to, [Keys.COMMAND, x, Keys.COMMAND])

    def send_keys(self, element, x):
        """
        Sends keys to the element. This method takes care of handling
        modifiers keys. To press and release a modifier key you must
        include it twice: once to press, once to release.
        """
        ActionChains(self.driver) \
            .send_keys_to_element(element, x) \
            .perform()

    def get_text_excluding_children(self, element):
        return self.driver.execute_script("""
        return jQuery(arguments[0]).contents().filter(function() {
            return this.nodeType == Node.TEXT_NODE;
        }).text();
        """, element)

    def element_screen_position(self, element):
        return self.driver.execute_script("""
        var $ = jQuery;
        var offset = $(arguments[0]).offset();
        var $document = $(document);
        offset.top -= $document.scrollTop();
        offset.left -= $document.scrollLeft();
        return offset;
        """,
                                          element)

    def element_screen_center(self, element):
        """
        :returns: The center point of the element.
        :rtype: class:`dict` with the field "left" set to the X
                coordinate and the field "top" set to the Y
                coordinate.

        """
        pos = self.element_screen_position(element)
        size = element.size
        pos["top"] += int(size["height"] / 2)
        pos["left"] += int(size["width"] / 2)
        return pos

    def visible_to_user(self, element, *ignorable):
        """
        Determines whether an element is visible to the user. A list of
        ignorable elements can be passed to this function. These would
        typically be things like invisible layers sitting atop other
        elements. This function ignores these elements by setting
        their CSS ``display`` parameter to ``none`` before checking,
        and restoring them to their initial value after checking. The
        list of ignorable elements should not contain elements that
        would disturb the position of the element to check if their
        ``display`` parameter is set to ``none``. Otherwise, the
        algorithm is likely to fail.

        :param element: The element to check.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :param ignorable: The elements that can be ignored.
        :type ignorable: :class:`list` of :strings that are jQuery selectors.

        """
        if not element.is_displayed():
            return False
        pos = self.element_screen_position(element)
        size = element.size
        window_size = self.get_window_inner_size()

        # Outside the viewport
        if (pos["top"] + size["height"] < 0 or  # above
                pos["left"] + size["width"] < 0 or  # to the left
                pos["top"] > window_size["height"] or  # below
                pos["left"] > window_size["width"]):  # to the right
            return False

        return self.driver.execute_script("""
        var el = arguments[0];
        var ignorable = arguments[1];
        var $ = jQuery;

        var old_displays = [];
        var $ignorable = $(ignorable);
        ignorable.forEach(function (x) {
            old_displays.push($(x).css("display"));
        });
        $ignorable.css("display", "none");
        try {
            var rect = el.getBoundingClientRect();
            var ret = false;

            var efp = document.elementFromPoint.bind(document);
            var at_corner;
            ret = (at_corner = efp(rect.left, rect.top) === el) ||
                   el.contains(at_corner) ||
                  (at_corner = efp(rect.left, rect.bottom) === el) ||
                   el.contains(at_corner) ||
                  (at_corner = efp(rect.right, rect.top) === el) ||
                   el.contains(at_corner) ||
                  (at_corner = efp(rect.right, rect.bottom) === el) ||
                   el.contains(at_corner);
        }
        finally {
            var ix = 0;
            ignorable.forEach(function (x) {
                $(x).css("display", old_displays[ix]);
                ix++;
            });
        }
        return ret;
        """, element, ignorable)

    def get_window_inner_size(self):
        return self.driver.execute_script("""
        return {height: window.innerHeight, width: window.innerWidth};
        """)

    def completely_visible_to_user(self, element):
        if not element.is_displayed():
            return False
        pos = self.element_screen_position(element)
        size = element.size
        window_size = self.driver.get_window_size()
        return (pos["top"] >= 0 and
                pos["left"] >= 0 and
                pos["top"] + size["height"] <= window_size["height"] and
                pos["left"] + size["width"] <= window_size["width"])

    def get_selection_text(self):
        """
        Gets the text of the current selection.

        .. note:: This function requires that ``rangy`` be installed.

        :returns: The text.
        :rtype: class:`basestring`
        """
        return self.driver.execute_script("""
        return rangy.getSelection(window).toString()
        """)

    def is_something_selected(self):
        """
        :returns: Whether something is selected.
        :rtype: class:`bool`
        """
        return self.driver.execute_script("""
        var sel = window.getSelection();
        return sel.rangeCount && !sel.getRangeAt(0).collapsed;
        """)

    def scroll_top(self, element):
        """
        Gets the top of the scrolling area of the element.

        :param element: An element on the page.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :returns: The top of the scrolling area.
        """
        return self.driver.execute_script("""
        return arguments[0].scrollTop;
        """, element)

    def window_scroll_top(self):
        """
        Gets the top of the scrolling area for ``window``.

        :returns: The top of the scrolling area.
        """
        return self.driver.execute_script("""
        return window.scrollY;
        """)

    def window_scroll_left(self):
        """
        Gets the left of the scrolling area for ``window``.

        :returns: The left of the scrolling area.
        """
        return self.driver.execute_script("""
        return window.scrollX;
        """)

    def wait(self, condition):
        """
        Waits for a condition to be true.

        :param condition: Should be a callable that operates in the
                          same way ``WebDriverWait.until`` expects.
        :returns: Whatever ``WebDriverWait.until`` returns.
        """
        return WebDriverWait(self.driver, self.timeout).until(condition)

    def wait_until_not(self, condition):
        """
        Waits for a condition to be false.

        :param condition: Should be a callable that operates in the
                          same way ``WebDriverWait.until_not`` expects.
        :returns: Whatever ``WebDriverWait.until_not`` returns.
        """
        return WebDriverWait(self.driver, self.timeout).until_not(condition)

    def get_html(self, element):
        """
        :param element: The element.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :returns: The HTML of an element.
        :rtype: :class:`str`
        """
        return self.driver.execute_script("""
        return arguments[0].outerHTML;
        """, element)

    def number_of_siblings(self, element):
        """
        :param element: The element.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :returns: The number of siblings.
        :rtype: :class:`int`
        """
        return self.driver.execute_script("""
        return arguments[0].parentNode.childNodes.length;
        """, element)

    def assert_same(self, first, second):
        """
        Compares two items for identity. The items can be either single
        values or lists of values. When comparing lists, identity
        obtains when the two lists have the same number of elements
        and that the element at position in one list is identical to
        the element at the same position in the other list.

        This method is meant to be used for comparing lists of DOM
        nodes. It would also work with lists of booleans, integers,
        and similar primitive types, but is pointless in such
        cases. Also note that this method cannot meaningfully compare
        lists of lists or lists of dictionaries since the objects that
        would be part of the list would be created anew by Selenium's
        marshalling procedure. Hence, in these cases, the assertion
        would always fail.

        :param first: The first item to compare.
        :type first:
                     :class:`selenium.webdriver.remote.webelement.WebElement`
                     or array of
                     :class:`selenium.webdriver.remote.webelement.WebElement`.
        :param second: The second item to compare.
        :type second:
           :class:`selenium.webdriver.remote.webelement.WebElement` or
           :array of
           :class:`selenium.webdriver.remote.webelement.WebElement`.
        :raises: :class:`AssertionError` when unequal.
        """
        if not isinstance(first, list):
            first = [first]
        if not isinstance(second, list):
            second = [second]
        if not self.driver.execute_script("""
        var first = arguments[0];
        var second = arguments[1];
        if (first.length != second.length)
            return false;
        for(var i = 0; i < first.length; ++i)
            if (first[i] !== second[i])
                return false;
        return true;
        """, first, second):
            raise AssertionError("unequal")

def locations_within(a, b, tolerance):
    """
    Verifies whether two positions are the same. A tolerance value
    determines how close the two positions must be to be considered
    "same".

    The two locations must be dictionaries that have the same keys. If
    a key is pesent in one but not in the other, this is an error. The
    values must be integers or anything that can be converted to an
    integer through ``int``. (If somehow you need floating point
    precision, this is not the function for you.)

    Do not rely on this function to determine whether two object have
    the same keys. If the function finds the locations to be within
    tolerances, then the two objects have the same keys. Otherwise,
    you cannot infer anything regarding the keys because the function
    will return as soon as it knows that the two locations are **not**
    within tolerance.

    :param a: First position.
    :type a: :class:`dict`
    :param b: Second position.
    :type b: :class:`dict`
    :param tolerance: The tolerance within which the two positions
                      must be.
    :return: An empty string if the comparison is successful. Otherwise,
             the string contains a description of the differences.
    :rtype: :class:`str`
    :raises ValueError: When a key is present in one object but not
                        the other.
    """
    ret = ''
    # Clone b so that we can destroy it.
    b = dict(b)

    for (key, value) in a.items():
        if key not in b:
            raise ValueError("b does not have the key: " + key)
        if abs(int(value) - int(b[key])) > tolerance:
            ret += 'key {0} differs: {1} {2}'.format(key, int(value),
                                                     int(b[key]))
        del b[key]

    if b:
        raise ValueError("keys in b not seen in a: " + ", ".join(b.keys()))

    return ret
<commit_msg>Adjusted the windows variable.<commit_after>import contextlib

from selenium.webdriver.support.ui import WebDriverWait
import selenium.webdriver.support.expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

class Util(object):

    def __init__(self, driver, default_timeout=2):
        self.driver = driver
        self.timeouts = [default_timeout]
        self.driver.set_script_timeout(default_timeout)
        self.osx = driver.desired_capabilities[
            "platform"].startswith("Mac OS X")

        # Saucelabs sets this inconsistently. When requiring FF on
        # Windows 8.1, we get "XP". When requiring IE on Windows 8.1,
        # we get "WINDOWS". Yuck!
        self.windows = driver.desired_capabilities["platform"] in \
            ("XP", "WINDOWS")

        self.firefox = driver.name == "firefox"
        self.ie = driver.name == "internet explorer"
        # Only IE 9 or earlier has a problem with setting cookies...
        self._can_set_cookies = not (
            self.ie and int(driver.desired_capabilities["version"]) <= 9)

        self.ctrl_equivalent_x = self.command_x if self.osx else self.ctrl_x
        """
        When controlling a browser running in a platform other than OS X,
        equivalent to `:func:Util.ctrl_x`. Otherwise, equivalent to
        `:func:Util.command_x:`.
        """

    @property
    def can_set_cookies(self):
        """
        ``True`` if the driver we are using is able to set cookies. Bugs in
        selenium sometimes prevent this from being true.
        """
        return self._can_set_cookies

    @property
    def timeout(self):
        return self.timeouts[0]

    @contextlib.contextmanager
    def local_timeout(self, value):
        self.push_timeout(value)
        try:
            yield
        finally:
            self.pop_timeout()

    def push_timeout(self, new):
        self.timeouts[0:0] = [new]
        self.driver.set_script_timeout(new)

    def pop_timeout(self):
        if len(self.timeouts) == 1:
            raise Exception("can't pop when there is only one element on "
                            "the stack")
        # The new timeout is currently in 2nd position.
        self.driver.set_script_timeout(self.timeouts[1])
        return self.timeouts.pop(0)

    def find_element(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.presence_of_element_located(locator))

    def find_elements(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.presence_of_all_elements_located(locator))

    def find_clickable_element(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.element_to_be_clickable(locator))

    def find_descendants_by_text_re(self, parent, re):
        """
        :param parent: The parent element into which to search.
        :type parent: :class:`selenium.webdriver.remote.webelement.WebElement`
        :param re: A regular expression in JavaScript syntax.
        :type re: :class:`str`
        :returns: The descendants whose text (as returned by
                  ``jQuery().text()``) match the regular expression.

        """

        def cond(*_):
            return self.driver.execute_script("""
            var parent = arguments[0];
            var re = new RegExp(arguments[1]);
            return jQuery(parent).find("*").filter(function () {
            return re.test(jQuery(this).text().trim());
            }).toArray();
            return ret;
            """, parent, re)

        return self.wait(cond)

    #
    # The key sending methods are here as a sort of insurance policy
    # against possible issues with the various drivers that Selenium
    # uses.  We used to emit sequences like Ctrl-X or Shift-Q as
    # key_down, send_keys, key_up sequences. However, these sequence
    # are **really** expensive when using a remote setup. So the
    # following methods use a single send_keys instead. If this turns
    # out to be a problem eventually, we can still revert to the
    # key_down, send_keys, key_up sequence if we ever need to do this.
    #
    def ctrl_x(self, x, to=None):
        """
        Sends a character to the currently active element with Ctrl
        pressed. This method takes care of pressing and releasing
        Ctrl.
        """
        if to is None:
            ActionChains(self.driver) \
                .send_keys([Keys.CONTROL, x, Keys.CONTROL]) \
                .perform()
        else:
            self.send_keys(to, [Keys.CONTROL, x, Keys.CONTROL])

    #
    # The key sending methods are here as a sort of insurance policy
    # against possible issues with the various drivers that Selenium
    # uses.  We used to emit sequences like Ctrl-X or Shift-Q as
    # key_down, send_keys, key_up sequences. However, these sequence
    # are **really** expensive when using a remote setup. So the
    # following methods use a single send_keys instead. If this turns
    # out to be a problem eventually, we can still revert to the
    # key_down, send_keys, key_up sequence if we ever need to do this.
    #
    def command_x(self, x, to=None):
        """
        Sends a character to the currently active element with Command
        pressed. This method takes care of pressing and releasing
        Command.
        """
        if to is None:
            ActionChains(self.driver) \
                .send_keys([Keys.COMMAND, x, Keys.COMMAND]) \
                .perform()
        else:
            self.send_keys(to, [Keys.COMMAND, x, Keys.COMMAND])

    def send_keys(self, element, x):
        """
        Sends keys to the element. This method takes care of handling
        modifiers keys. To press and release a modifier key you must
        include it twice: once to press, once to release.
        """
        ActionChains(self.driver) \
            .send_keys_to_element(element, x) \
            .perform()

    def get_text_excluding_children(self, element):
        return self.driver.execute_script("""
        return jQuery(arguments[0]).contents().filter(function() {
            return this.nodeType == Node.TEXT_NODE;
        }).text();
        """, element)

    def element_screen_position(self, element):
        return self.driver.execute_script("""
        var $ = jQuery;
        var offset = $(arguments[0]).offset();
        var $document = $(document);
        offset.top -= $document.scrollTop();
        offset.left -= $document.scrollLeft();
        return offset;
        """,
                                          element)

    def element_screen_center(self, element):
        """
        :returns: The center point of the element.
        :rtype: class:`dict` with the field "left" set to the X
                coordinate and the field "top" set to the Y
                coordinate.

        """
        pos = self.element_screen_position(element)
        size = element.size
        pos["top"] += int(size["height"] / 2)
        pos["left"] += int(size["width"] / 2)
        return pos

    def visible_to_user(self, element, *ignorable):
        """
        Determines whether an element is visible to the user. A list of
        ignorable elements can be passed to this function. These would
        typically be things like invisible layers sitting atop other
        elements. This function ignores these elements by setting
        their CSS ``display`` parameter to ``none`` before checking,
        and restoring them to their initial value after checking. The
        list of ignorable elements should not contain elements that
        would disturb the position of the element to check if their
        ``display`` parameter is set to ``none``. Otherwise, the
        algorithm is likely to fail.

        :param element: The element to check.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :param ignorable: The elements that can be ignored.
        :type ignorable: :class:`list` of :strings that are jQuery selectors.

        """
        if not element.is_displayed():
            return False
        pos = self.element_screen_position(element)
        size = element.size
        window_size = self.get_window_inner_size()

        # Outside the viewport
        if (pos["top"] + size["height"] < 0 or  # above
                pos["left"] + size["width"] < 0 or  # to the left
                pos["top"] > window_size["height"] or  # below
                pos["left"] > window_size["width"]):  # to the right
            return False

        return self.driver.execute_script("""
        var el = arguments[0];
        var ignorable = arguments[1];
        var $ = jQuery;

        var old_displays = [];
        var $ignorable = $(ignorable);
        ignorable.forEach(function (x) {
            old_displays.push($(x).css("display"));
        });
        $ignorable.css("display", "none");
        try {
            var rect = el.getBoundingClientRect();
            var ret = false;

            var efp = document.elementFromPoint.bind(document);
            var at_corner;
            ret = (at_corner = efp(rect.left, rect.top) === el) ||
                   el.contains(at_corner) ||
                  (at_corner = efp(rect.left, rect.bottom) === el) ||
                   el.contains(at_corner) ||
                  (at_corner = efp(rect.right, rect.top) === el) ||
                   el.contains(at_corner) ||
                  (at_corner = efp(rect.right, rect.bottom) === el) ||
                   el.contains(at_corner);
        }
        finally {
            var ix = 0;
            ignorable.forEach(function (x) {
                $(x).css("display", old_displays[ix]);
                ix++;
            });
        }
        return ret;
        """, element, ignorable)

    def get_window_inner_size(self):
        return self.driver.execute_script("""
        return {height: window.innerHeight, width: window.innerWidth};
        """)

    def completely_visible_to_user(self, element):
        if not element.is_displayed():
            return False
        pos = self.element_screen_position(element)
        size = element.size
        window_size = self.driver.get_window_size()
        return (pos["top"] >= 0 and
                pos["left"] >= 0 and
                pos["top"] + size["height"] <= window_size["height"] and
                pos["left"] + size["width"] <= window_size["width"])

    def get_selection_text(self):
        """
        Gets the text of the current selection.

        .. note:: This function requires that ``rangy`` be installed.

        :returns: The text.
        :rtype: class:`basestring`
        """
        return self.driver.execute_script("""
        return rangy.getSelection(window).toString()
        """)

    def is_something_selected(self):
        """
        :returns: Whether something is selected.
        :rtype: class:`bool`
        """
        return self.driver.execute_script("""
        var sel = window.getSelection();
        return sel.rangeCount && !sel.getRangeAt(0).collapsed;
        """)

    def scroll_top(self, element):
        """
        Gets the top of the scrolling area of the element.

        :param element: An element on the page.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :returns: The top of the scrolling area.
        """
        return self.driver.execute_script("""
        return arguments[0].scrollTop;
        """, element)

    def window_scroll_top(self):
        """
        Gets the top of the scrolling area for ``window``.

        :returns: The top of the scrolling area.
        """
        return self.driver.execute_script("""
        return window.scrollY;
        """)

    def window_scroll_left(self):
        """
        Gets the left of the scrolling area for ``window``.

        :returns: The left of the scrolling area.
        """
        return self.driver.execute_script("""
        return window.scrollX;
        """)

    def wait(self, condition):
        """
        Waits for a condition to be true.

        :param condition: Should be a callable that operates in the
                          same way ``WebDriverWait.until`` expects.
        :returns: Whatever ``WebDriverWait.until`` returns.
        """
        return WebDriverWait(self.driver, self.timeout).until(condition)

    def wait_until_not(self, condition):
        """
        Waits for a condition to be false.

        :param condition: Should be a callable that operates in the
                          same way ``WebDriverWait.until_not`` expects.
        :returns: Whatever ``WebDriverWait.until_not`` returns.
        """
        return WebDriverWait(self.driver, self.timeout).until_not(condition)

    def get_html(self, element):
        """
        :param element: The element.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :returns: The HTML of an element.
        :rtype: :class:`str`
        """
        return self.driver.execute_script("""
        return arguments[0].outerHTML;
        """, element)

    def number_of_siblings(self, element):
        """
        :param element: The element.
        :type element: :class:`selenium.webdriver.remote.webelement.WebElement`
        :returns: The number of siblings.
        :rtype: :class:`int`
        """
        return self.driver.execute_script("""
        return arguments[0].parentNode.childNodes.length;
        """, element)

    def assert_same(self, first, second):
        """
        Compares two items for identity. The items can be either single
        values or lists of values. When comparing lists, identity
        obtains when the two lists have the same number of elements
        and that the element at position in one list is identical to
        the element at the same position in the other list.

        This method is meant to be used for comparing lists of DOM
        nodes. It would also work with lists of booleans, integers,
        and similar primitive types, but is pointless in such
        cases. Also note that this method cannot meaningfully compare
        lists of lists or lists of dictionaries since the objects that
        would be part of the list would be created anew by Selenium's
        marshalling procedure. Hence, in these cases, the assertion
        would always fail.

        :param first: The first item to compare.
        :type first:
                     :class:`selenium.webdriver.remote.webelement.WebElement`
                     or array of
                     :class:`selenium.webdriver.remote.webelement.WebElement`.
        :param second: The second item to compare.
        :type second:
           :class:`selenium.webdriver.remote.webelement.WebElement` or
           :array of
           :class:`selenium.webdriver.remote.webelement.WebElement`.
        :raises: :class:`AssertionError` when unequal.
        """
        if not isinstance(first, list):
            first = [first]
        if not isinstance(second, list):
            second = [second]
        if not self.driver.execute_script("""
        var first = arguments[0];
        var second = arguments[1];
        if (first.length != second.length)
            return false;
        for(var i = 0; i < first.length; ++i)
            if (first[i] !== second[i])
                return false;
        return true;
        """, first, second):
            raise AssertionError("unequal")

def locations_within(a, b, tolerance):
    """
    Verifies whether two positions are the same. A tolerance value
    determines how close the two positions must be to be considered
    "same".

    The two locations must be dictionaries that have the same keys. If
    a key is pesent in one but not in the other, this is an error. The
    values must be integers or anything that can be converted to an
    integer through ``int``. (If somehow you need floating point
    precision, this is not the function for you.)

    Do not rely on this function to determine whether two object have
    the same keys. If the function finds the locations to be within
    tolerances, then the two objects have the same keys. Otherwise,
    you cannot infer anything regarding the keys because the function
    will return as soon as it knows that the two locations are **not**
    within tolerance.

    :param a: First position.
    :type a: :class:`dict`
    :param b: Second position.
    :type b: :class:`dict`
    :param tolerance: The tolerance within which the two positions
                      must be.
    :return: An empty string if the comparison is successful. Otherwise,
             the string contains a description of the differences.
    :rtype: :class:`str`
    :raises ValueError: When a key is present in one object but not
                        the other.
    """
    ret = ''
    # Clone b so that we can destroy it.
    b = dict(b)

    for (key, value) in a.items():
        if key not in b:
            raise ValueError("b does not have the key: " + key)
        if abs(int(value) - int(b[key])) > tolerance:
            ret += 'key {0} differs: {1} {2}'.format(key, int(value),
                                                     int(b[key]))
        del b[key]

    if b:
        raise ValueError("keys in b not seen in a: " + ", ".join(b.keys()))

    return ret
<|endoftext|>


<commit_before>import sublime
import sublime_plugin
import os
import subprocess
import re

def syntax_settings(lang, key, default=None):
    settings = sublime.load_settings("SendTextPlus.sublime-settings")
    ret = None
    plat = sublime.platform()
    if lang:
        lang_settings = settings.get(lang)
        os_settings = lang_settings.get(plat)
        if os_settings:
            ret = os_settings.get(key)
        if ret is None:
            ret = lang_settings.get(key)
    if ret is None:
        ret = settings.get("default").get(plat).get(key)
    if ret is None:
        ret = default
    return ret

def clean(cmd):
    cmd = cmd.expandtabs(4)
    cmd = cmd.rstrip('\n')
    if len(re.findall("\n", cmd)) == 0:
        cmd = cmd.lstrip()
    return cmd

def escape_dq(cmd):
    cmd = cmd.replace('\\', '\\\\')
    cmd = cmd.replace('"', '\\"')
    return cmd

def sendtext(prog, cmd):
    if cmd.strip() == "":
        return
    plat = sublime.platform()
    settings = sublime.load_settings("SendTextPlus.sublime-settings")

    if re.match('Terminal', prog):
        cmd = clean(cmd)
        cmd = escape_dq(cmd)
        args = ['osascript']
        args.extend(['-e', 'tell app "Terminal" to do script "' + cmd + '" in front window\n'])
        subprocess.Popen(args)

    elif re.match('iTerm', prog):
        cmd = clean(cmd)
        cmd = escape_dq(cmd)
        # when cmd ends in a space, iterm does not execute. Thus append a line break.
        if (cmd[-1:] == ' '):
            cmd += '\n'
        try:
            # iterm <2.9
            args = ['osascript', '-e', 'tell app "iTerm" to tell the first terminal '
                    'to tell current session to write text "' + cmd + '"']
            subprocess.check_call(args)
        except:
            # iterm >=2.9
            args = ['osascript', '-e', 'tell app "iTerm" to tell the first terminal window '
                    'to tell current session to write text "' + cmd + '"']
            subprocess.check_call(args)

    elif prog == "tmux":
        cmd = clean(cmd) + "\n"
        progpath = settings.get("tmux", "tmux")
        n = 200
        chunks = [cmd[i:i+n] for i in range(0, len(cmd), n)]
        for chunk in chunks:
            subprocess.call([progpath, 'set-buffer', chunk])
            subprocess.call([progpath, 'paste-buffer', '-d'])

    elif prog == "screen":
        cmd = clean(cmd) + "\n"
        progpath = settings.get("screen", "screen")
        n = 200
        chunks = [cmd[i:i+n] for i in range(0, len(cmd), n)]
        for chunk in chunks:
            if plat == "linux":
                chunk = chunk.replace("\\", r"\\")
                chunk = chunk.replace("$", r"\$")
            subprocess.call([progpath, '-X', 'stuff', chunk])

    elif prog == "SublimeREPL":
        cmd = clean(cmd)
        view = sublime.active_window().active_view()
        external_id = view.scope_name(0).split(" ")[0].split(".", 1)[1]
        sublime.active_window().run_command("repl_send", {"external_id": external_id, "text": cmd})
        return

    if plat == 'windows':
        raise Exception("not yet supported")

class SendTextPlusCommand(sublime_plugin.TextCommand):
    def get_syntax(self):
        view = self.view
        pt = view.sel()[0].begin() if len(view.sel()) > 0 else 0
        if view.score_selector(pt, "source.r"):
            return "r"
        elif view.score_selector(pt, "source.python"):
            return "python"
        elif view.score_selector(pt, "source.julia"):
            return "julia"

    def r_expand_block(self, sel):
        # expand selection to {...} when being triggered
        view = self.view
        thiscmd = view.substr(view.line(sel))
        if re.match(r".*\{\s*$", thiscmd):
            esel = view.find(
                r"""^(?:.*(\{(?:(["\'])(?:[^\\]|\\.)*?\2|#.*$|[^\{\}]|(?1))*\})[^\{\}\n]*)+""",
                view.line(sel).begin()
            )
            if view.line(sel).begin() == esel.begin():
                sel = esel
        return sel

    def python_expand_block(self, sel):
        view = self.view
        thiscmd = view.substr(view.line(sel))
        if re.match(r"^[ \t]*\S", thiscmd):
            indentation = re.match(r"^([ \t]*)", thiscmd).group(1)
            row = view.rowcol(sel.begin())[0]
            prevline = view.line(sel.begin())
            lastrow = view.rowcol(view.size())[0]
            while row < lastrow:
                row = row + 1
                line = view.line(view.text_point(row, 0))
                m = re.match(r"^([ \t]*)([^\n\s]+)", view.substr(line))
                if m and len(m.group(1)) <= len(indentation) and \
                        (len(m.group(1)) < len(indentation) or
                            not re.match(r"else|elif|except|finally", m.group(2))):
                    sel = sublime.Region(sel.begin(), prevline.end())
                    break
                elif re.match(r"^[ \t]*\S", view.substr(line)):
                    prevline = line

            if row == lastrow:
                sel = sublime.Region(sel.begin(), prevline.end())
        return sel

    def julia_expand_block(self, sel):
        view = self.view
        thiscmd = view.substr(view.line(sel))
        if (re.match(r"^\s*(?:function|if|for|while)", thiscmd) and
                not re.match(r".*end\s*$", thiscmd)) or \
                (re.match(r".*begin\s*$", thiscmd)):
            indentation = re.match("^(\s*)", thiscmd).group(1)
            end = view.find("^"+indentation+"end", sel.begin())
            sel = sublime.Region(sel.begin(), view.line(end.end()).end())

        return sel

    def run(self, edit):
        view = self.view
        syntax = self.get_syntax()
        cmd = ''
        for sel in [s for s in view.sel()]:
            if sel.empty():
                if syntax_settings(syntax, "block", False):
                    if syntax == "r":
                        esel = self.r_expand_block(sel)
                    elif syntax == "python":
                        esel = self.python_expand_block(sel)
                    elif syntax == "julia":
                        esel = self.julia_expand_block(sel)

                    thiscmd = view.substr(view.line(esel))
                    line = view.rowcol(esel.end())[0]
                else:
                    thiscmd = view.substr(view.line(sel))
                    line = view.rowcol(sel.end())[0]

                if syntax_settings(syntax, "auto_advance", False):
                    view.sel().subtract(sel)
                    pt = view.text_point(line+1, 0)
                    view.sel().add(sublime.Region(pt, pt))
            else:
                thiscmd = view.substr(sel)
            cmd += thiscmd + '\n'

        # ipython wrapper
        if syntax == "python" and syntax_settings(syntax, "ipython", False):
            cmd = clean(cmd)
            if len(re.findall("\n", cmd)) > 0:
                cmd = "%cpaste\n" + cmd + "\n--"

        prog = syntax_settings(syntax, "prog")
        sendtext(prog, cmd)

        if syntax_settings(syntax, "auto_advance", False):
            view.show(view.sel())

class SendTextPlusChangeDirCommand(sublime_plugin.TextCommand):
    def get_syntax(self):
        view = self.view
        pt = view.sel()[0].begin() if len(view.sel()) > 0 else 0
        if view.score_selector(pt, "source.r"):
            return "r"
        elif view.score_selector(pt, "source.python"):
            return "python"
        elif view.score_selector(pt, "source.julia"):
            return "julia"

    def run(self, edit):
        fname = self.view.file_name()
        if not fname:
            sublime.error_message("Save the file!")
            return

        dirname = os.path.dirname(fname)
        syntax = self.get_syntax()
        prog = syntax_settings(syntax, "prog")

        if syntax == "r":
            cmd = "setwd(\"" + escape_dq(dirname) + "\")"
        elif syntax == "julia":
            cmd = "cd(\"" + escape_dq(dirname) + "\")"
        elif syntax == "python" and syntax_settings(syntax, "ipython", False):
            cmd = "cd \"" + escape_dq(dirname) + "\""
        sendtext(prog, cmd + "\n")
<commit_msg>fix iterm send text for more than 1024 chars<commit_after>import sublime
import sublime_plugin
import os
import subprocess
import re

def syntax_settings(lang, key, default=None):
    settings = sublime.load_settings("SendTextPlus.sublime-settings")
    ret = None
    plat = sublime.platform()
    if lang:
        lang_settings = settings.get(lang)
        os_settings = lang_settings.get(plat)
        if os_settings:
            ret = os_settings.get(key)
        if ret is None:
            ret = lang_settings.get(key)
    if ret is None:
        ret = settings.get("default").get(plat).get(key)
    if ret is None:
        ret = default
    return ret

def clean(cmd):
    cmd = cmd.expandtabs(4)
    cmd = cmd.rstrip('\n')
    if len(re.findall("\n", cmd)) == 0:
        cmd = cmd.lstrip()
    return cmd

def escape_dq(cmd):
    cmd = cmd.replace('\\', '\\\\')
    cmd = cmd.replace('"', '\\"')
    return cmd

def sendtext(prog, cmd):
    if cmd.strip() == "":
        return
    plat = sublime.platform()
    settings = sublime.load_settings("SendTextPlus.sublime-settings")

    if re.match('Terminal', prog):
        cmd = clean(cmd)
        cmd = escape_dq(cmd)
        args = ['osascript']
        args.extend(['-e', 'tell app "Terminal" to do script "' + cmd + '" in front window\n'])
        subprocess.Popen(args)

    elif re.match('iTerm', prog):
        cmd = clean(cmd)
        cmd = escape_dq(cmd)
        # when cmd ends in a space, iterm does not execute. Thus append a line break.
        if (cmd[-1:] == ' '):
            cmd += '\n'
        cmd = cmd.split("\n")
        line_len = [len(c) for c in cmd]
        k = 0
        while k < len(line_len):
            for j in range(k + 1, len(line_len) + 1):
                if sum(line_len[k:j]) > 500:
                    break
            chunk = "\n".join(cmd[k:j])
            try:
                # iterm <2.9
                args = ['osascript', '-e', 'tell app "iTerm" to tell the first terminal '
                        'to tell current session to write text "' + chunk + '"']
                subprocess.check_call(args)
            except:
                # iterm >=2.9
                args = ['osascript', '-e', 'tell app "iTerm" to tell the first terminal window '
                        'to tell current session to write text "' + chunk + '"']
                subprocess.check_call(args)
            k = j

    elif prog == "tmux":
        cmd = clean(cmd) + "\n"
        progpath = settings.get("tmux", "tmux")
        n = 200
        chunks = [cmd[i:i+n] for i in range(0, len(cmd), n)]
        for chunk in chunks:
            subprocess.call([progpath, 'set-buffer', chunk])
            subprocess.call([progpath, 'paste-buffer', '-d'])

    elif prog == "screen":
        cmd = clean(cmd) + "\n"
        progpath = settings.get("screen", "screen")
        n = 200
        chunks = [cmd[i:i+n] for i in range(0, len(cmd), n)]
        for chunk in chunks:
            if plat == "linux":
                chunk = chunk.replace("\\", r"\\")
                chunk = chunk.replace("$", r"\$")
            subprocess.call([progpath, '-X', 'stuff', chunk])

    elif prog == "SublimeREPL":
        cmd = clean(cmd)
        view = sublime.active_window().active_view()
        external_id = view.scope_name(0).split(" ")[0].split(".", 1)[1]
        sublime.active_window().run_command("repl_send", {"external_id": external_id, "text": cmd})
        return

    if plat == 'windows':
        raise Exception("not yet supported")

class SendTextPlusCommand(sublime_plugin.TextCommand):
    def get_syntax(self):
        view = self.view
        pt = view.sel()[0].begin() if len(view.sel()) > 0 else 0
        if view.score_selector(pt, "source.r"):
            return "r"
        elif view.score_selector(pt, "source.python"):
            return "python"
        elif view.score_selector(pt, "source.julia"):
            return "julia"

    def r_expand_block(self, sel):
        # expand selection to {...} when being triggered
        view = self.view
        thiscmd = view.substr(view.line(sel))
        if re.match(r".*\{\s*$", thiscmd):
            esel = view.find(
                r"""^(?:.*(\{(?:(["\'])(?:[^\\]|\\.)*?\2|#.*$|[^\{\}]|(?1))*\})[^\{\}\n]*)+""",
                view.line(sel).begin()
            )
            if view.line(sel).begin() == esel.begin():
                sel = esel
        return sel

    def python_expand_block(self, sel):
        view = self.view
        thiscmd = view.substr(view.line(sel))
        if re.match(r"^[ \t]*\S", thiscmd):
            indentation = re.match(r"^([ \t]*)", thiscmd).group(1)
            row = view.rowcol(sel.begin())[0]
            prevline = view.line(sel.begin())
            lastrow = view.rowcol(view.size())[0]
            while row < lastrow:
                row = row + 1
                line = view.line(view.text_point(row, 0))
                m = re.match(r"^([ \t]*)([^\n\s]+)", view.substr(line))
                if m and len(m.group(1)) <= len(indentation) and \
                        (len(m.group(1)) < len(indentation) or
                            not re.match(r"else|elif|except|finally", m.group(2))):
                    sel = sublime.Region(sel.begin(), prevline.end())
                    break
                elif re.match(r"^[ \t]*\S", view.substr(line)):
                    prevline = line

            if row == lastrow:
                sel = sublime.Region(sel.begin(), prevline.end())
        return sel

    def julia_expand_block(self, sel):
        view = self.view
        thiscmd = view.substr(view.line(sel))
        if (re.match(r"^\s*(?:function|if|for|while)", thiscmd) and
                not re.match(r".*end\s*$", thiscmd)) or \
                (re.match(r".*begin\s*$", thiscmd)):
            indentation = re.match("^(\s*)", thiscmd).group(1)
            end = view.find("^"+indentation+"end", sel.begin())
            sel = sublime.Region(sel.begin(), view.line(end.end()).end())

        return sel

    def run(self, edit):
        view = self.view
        syntax = self.get_syntax()
        cmd = ''
        moved = False
        for sel in [s for s in view.sel()]:
            if sel.empty():
                if syntax_settings(syntax, "block", False):
                    if syntax == "r":
                        esel = self.r_expand_block(sel)
                    elif syntax == "python":
                        esel = self.python_expand_block(sel)
                    elif syntax == "julia":
                        esel = self.julia_expand_block(sel)

                    thiscmd = view.substr(view.line(esel))
                    line = view.rowcol(esel.end())[0]
                else:
                    thiscmd = view.substr(view.line(sel))
                    line = view.rowcol(sel.end())[0]

                if syntax_settings(syntax, "auto_advance", False):
                    view.sel().subtract(sel)
                    pt = view.text_point(line+1, 0)
                    view.sel().add(sublime.Region(pt, pt))
                    moved = True
            else:
                thiscmd = view.substr(sel)
            cmd += thiscmd + '\n'

        # ipython wrapper
        if syntax == "python" and syntax_settings(syntax, "ipython", False):
            cmd = clean(cmd)
            if len(re.findall("\n", cmd)) > 0:
                cmd = "%cpaste\n" + cmd + "\n--"

        prog = syntax_settings(syntax, "prog")
        sendtext(prog, cmd)

        if moved:
            view.show(view.sel())

class SendTextPlusChangeDirCommand(sublime_plugin.TextCommand):
    def get_syntax(self):
        view = self.view
        pt = view.sel()[0].begin() if len(view.sel()) > 0 else 0
        if view.score_selector(pt, "source.r"):
            return "r"
        elif view.score_selector(pt, "source.python"):
            return "python"
        elif view.score_selector(pt, "source.julia"):
            return "julia"

    def run(self, edit):
        fname = self.view.file_name()
        if not fname:
            sublime.error_message("Save the file!")
            return

        dirname = os.path.dirname(fname)
        syntax = self.get_syntax()
        prog = syntax_settings(syntax, "prog")

        if syntax == "r":
            cmd = "setwd(\"" + escape_dq(dirname) + "\")"
        elif syntax == "julia":
            cmd = "cd(\"" + escape_dq(dirname) + "\")"
        elif syntax == "python" and syntax_settings(syntax, "ipython", False):
            cmd = "cd \"" + escape_dq(dirname) + "\""
        sendtext(prog, cmd + "\n")
<|endoftext|>


<commit_before>from django.contrib import admin
from server.models import *

class MachineGroupAdmin(admin.ModelAdmin):
    readonly_fields = ('key',)

class MachineAdmin(admin.ModelAdmin):
    list_display = ('hostname', 'serial')

admin.site.register(UserProfile)
admin.site.register(BusinessUnit)
admin.site.register(MachineGroup, MachineGroupAdmin)
admin.site.register(Machine, MachineAdmin)
admin.site.register(Fact)
admin.site.register(PluginScriptSubmission)
admin.site.register(PluginScriptRow)
admin.site.register(HistoricalFact)
admin.site.register(Condition)
admin.site.register(PendingUpdate)
admin.site.register(InstalledUpdate)
admin.site.register(PendingAppleUpdate)
admin.site.register(ApiKey)
admin.site.register(Plugin)
admin.site.register(Report)
# admin.site.register(OSQueryResult)
# admin.site.register(OSQueryColumn)
admin.site.register(SalSetting)
admin.site.register(UpdateHistory)
admin.site.register(UpdateHistoryItem)
admin.site.register(MachineDetailPlugin)
<commit_msg>Sort registrations. Separate classes of imports. Add API key display.<commit_after>from django.contrib import admin

from server.models import *

class ApiKeyAdmin(admin.ModelAdmin):
    list_display = ('name', 'public_key', 'private_key')

class MachineAdmin(admin.ModelAdmin):
    list_display = ('hostname', 'serial')

class MachineGroupAdmin(admin.ModelAdmin):
    readonly_fields = ('key',)

admin.site.register(ApiKey, ApiKeyAdmin)
admin.site.register(BusinessUnit)
admin.site.register(Condition)
admin.site.register(Fact)
admin.site.register(HistoricalFact)
admin.site.register(InstalledUpdate)
admin.site.register(Machine, MachineAdmin)
admin.site.register(MachineDetailPlugin)
admin.site.register(MachineGroup, MachineGroupAdmin)
# admin.site.register(OSQueryColumn)
# admin.site.register(OSQueryResult)
admin.site.register(PendingAppleUpdate)
admin.site.register(PendingUpdate)
admin.site.register(Plugin)
admin.site.register(PluginScriptRow)
admin.site.register(PluginScriptSubmission)
admin.site.register(Report)
admin.site.register(SalSetting)
admin.site.register(UpdateHistory)
admin.site.register(UpdateHistoryItem)
admin.site.register(UserProfile)
<|endoftext|>


<commit_before>import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,'/var/www/inv')
from inv import app as application

<commit_msg>using create_app to initialize application<commit_after>import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,'/var/www/inv')
from inv import create_app
application = create_app('conf/deploy.cfg')

<|endoftext|>


<commit_before>from lrrbot import bot, log
import utils
import storage
import commands.static, commands.explain
import random
import re

@bot.server_event()
def current_game(lrrbot, user, data):
	game = lrrbot.get_current_game()
	if game:
		return game['id']
	else:
		return None

@bot.server_event()
def get_data(lrrbot, user, data):
	if not isinstance(data['key'], (list, tuple)):
		data['key'] = [data['key']]
	node = storage.data
	for subkey in data['key']:
		node = node.get(subkey, {})
	return node

@bot.server_event()
def set_data(lrrbot, user, data):
	if not isinstance(data['key'], (list, tuple)):
		data['key'] = [data['key']]
	log.info("Setting storage %s to %r" % ('.'.join(data['key']), data['value']))
	# if key is, eg, ["a", "b", "c"]
	# then we want to effectively do:
	# storage.data["a"]["b"]["c"] = value
	# But in case one of those intermediate dicts doesn't exist:
	# storage.data.setdefault("a", {}).setdefault("b", {})["c"] = value
	node = storage.data
	for subkey in data['key'][:-1]:
		node = node.setdefault(subkey, {})
	node[data['key'][-1]] = data['value']
	storage.save()

@bot.server_event()
def modify_commands(lrrbot, user, data):
	commands.static.modify_commands(data)
	bot.compile()

@bot.server_event()
def modify_explanations(lrrbot, user, data):
	commands.explain.modify_explanations(data)
	bot.compile()

@bot.server_event()
def modify_spam_rules(lrrbot, user, data):
	storage.data['spam_rules'] = data
	storage.save()
	lrrbot.spam_rules = [(re.compile(i['re']), i['message']) for i in storage.data['spam_rules']]

@bot.server_event()
def get_commands(lrrbot, user, data):
	bind = lambda maybe, f: f(maybe) if maybe is not None else None
	ret = []
	for command in lrrbot.commands.values():
		doc = utils.parse_docstring(command.__doc__)
		for cmd in doc.walk():
			if cmd.get_content_maintype() == "multipart":
				continue
			if cmd.get_all("command") is None:
				continue
			ret += [{
				"aliases": cmd.get_all("command"),
				"mod-only": cmd.get("mod-only") == "true",
				"sub-only": cmd.get("sub-only") == "true",
				"throttled": bind(cmd.get("throttled"), int),
				"literal-response": cmd.get("literal-response") == "true",
				"description": cmd.get_payload(),
			}]
	return ret

@bot.server_event()
def get_header_info(lrrbot, user, data):
	game = lrrbot.get_current_game()
	data = {}
	if game is not None:
		data['current_game'] = {
			"name": game['name'],
			"display": game.get("display", game["name"]),
			"id": game["id"],
			"is_override": lrrbot.game_override is not None,
		}
		stats = [{
			"count": v,
			"type": storage.data['stats'][k].get("singular" if v == 1 else "plural", k)
		} for (k,v) in game['stats'].items() if v]
		stats.sort(key=lambda i: (-i['count'], i['type']))
		data['current_game']['stats'] = stats
		if game.get("votes"):
			good = sum(game['votes'].values())
			total = len(game['votes'])
			data["current_game"]["rating"] = {
				"good": good,
				"total": total,
				"perc": 100.0 * good / total,
			}
		if user is not None:
			data["current_game"]["my_rating"] = game.get("votes", {}).get(user.lower())
	if 'advice' in storage.data['responses']:
		data['advice'] = random.choice(storage.data['responses']['advice']['response'])
	if user is not None:
		data['is_mod'] = lrrbot.is_mod_nick(user)
		data['is_sub'] = lrrbot.is_sub_nick(user)
	else:
		data['is_mod'] = data['is_sub'] = False
	return data
<commit_msg>Yes, that's right Phil, just keep testing in production, what could possibly go wrong?<commit_after>from lrrbot import bot, log
import utils
import storage
import commands.static, commands.explain
import random
import re

@bot.server_event()
def current_game(lrrbot, user, data):
	game = lrrbot.get_current_game()
	if game:
		return game['id']
	else:
		return None

@bot.server_event()
def get_data(lrrbot, user, data):
	if not isinstance(data['key'], (list, tuple)):
		data['key'] = [data['key']]
	node = storage.data
	for subkey in data['key']:
		node = node.get(subkey, {})
	return node

@bot.server_event()
def set_data(lrrbot, user, data):
	if not isinstance(data['key'], (list, tuple)):
		data['key'] = [data['key']]
	log.info("Setting storage %s to %r" % ('.'.join(data['key']), data['value']))
	# if key is, eg, ["a", "b", "c"]
	# then we want to effectively do:
	# storage.data["a"]["b"]["c"] = value
	# But in case one of those intermediate dicts doesn't exist:
	# storage.data.setdefault("a", {}).setdefault("b", {})["c"] = value
	node = storage.data
	for subkey in data['key'][:-1]:
		node = node.setdefault(subkey, {})
	node[data['key'][-1]] = data['value']
	storage.save()

@bot.server_event()
def modify_commands(lrrbot, user, data):
	commands.static.modify_commands(data)
	bot.compile()

@bot.server_event()
def modify_explanations(lrrbot, user, data):
	commands.explain.modify_explanations(data)
	bot.compile()

@bot.server_event()
def modify_spam_rules(lrrbot, user, data):
	storage.data['spam_rules'] = data
	storage.save()
	lrrbot.spam_rules = [(re.compile(i['re']), i['message']) for i in storage.data['spam_rules']]

@bot.server_event()
def get_commands(lrrbot, user, data):
	bind = lambda maybe, f: f(maybe) if maybe is not None else None
	ret = []
	for command in lrrbot.commands.values():
		doc = utils.parse_docstring(command['func'].__doc__)
		for cmd in doc.walk():
			if cmd.get_content_maintype() == "multipart":
				continue
			if cmd.get_all("command") is None:
				continue
			ret += [{
				"aliases": cmd.get_all("command"),
				"mod-only": cmd.get("mod-only") == "true",
				"sub-only": cmd.get("sub-only") == "true",
				"throttled": bind(cmd.get("throttled"), int),
				"literal-response": cmd.get("literal-response") == "true",
				"description": cmd.get_payload(),
			}]
	return ret

@bot.server_event()
def get_header_info(lrrbot, user, data):
	game = lrrbot.get_current_game()
	data = {}
	if game is not None:
		data['current_game'] = {
			"name": game['name'],
			"display": game.get("display", game["name"]),
			"id": game["id"],
			"is_override": lrrbot.game_override is not None,
		}
		stats = [{
			"count": v,
			"type": storage.data['stats'][k].get("singular" if v == 1 else "plural", k)
		} for (k,v) in game['stats'].items() if v]
		stats.sort(key=lambda i: (-i['count'], i['type']))
		data['current_game']['stats'] = stats
		if game.get("votes"):
			good = sum(game['votes'].values())
			total = len(game['votes'])
			data["current_game"]["rating"] = {
				"good": good,
				"total": total,
				"perc": 100.0 * good / total,
			}
		if user is not None:
			data["current_game"]["my_rating"] = game.get("votes", {}).get(user.lower())
	if 'advice' in storage.data['responses']:
		data['advice'] = random.choice(storage.data['responses']['advice']['response'])
	if user is not None:
		data['is_mod'] = lrrbot.is_mod_nick(user)
		data['is_sub'] = lrrbot.is_sub_nick(user)
	else:
		data['is_mod'] = data['is_sub'] = False
	return data
<|endoftext|>