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

#-------------------------------------------------------------------------
# drawElements Quality Program utilities
# --------------------------------------
#
# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#-------------------------------------------------------------------------

import os
import argparse
import tempfile
import sys

from build.common import *
from build.build import *

pythonExecutable = sys.executable or "python"

class Environment:
	def __init__ (self, srcDir, tmpDir):
		self.srcDir	= srcDir
		self.tmpDir	= tmpDir

class BuildTestStep:
	def getName (self):
		return "<unknown>"

	def isAvailable (self, env):
		return True

	def run (self, env):
		raise Exception("Not implemented")

class RunScript(BuildTestStep):
	def __init__ (self, scriptPath, getExtraArgs = None):
		self.scriptPath		= scriptPath
		self.getExtraArgs	= getExtraArgs

	def getName (self):
		return self.scriptPath

	def run (self, env):
		args = [pythonExecutable, os.path.join(env.srcDir, self.scriptPath)]

		if self.getExtraArgs != None:
			args += self.getExtraArgs(env)

		execute(args)

def makeCflagsArgs (cflags):
	cflagsStr = " ".join(cflags)
	return ["-DCMAKE_C_FLAGS=%s" % cflagsStr, "-DCMAKE_CXX_FLAGS=%s" % cflagsStr]

def makeBuildArgs (target, cc, cpp, cflags):
	return ["-DDEQP_TARGET=%s" % target, "-DCMAKE_C_COMPILER=%s" % cc, "-DCMAKE_CXX_COMPILER=%s" % cpp] + makeCflagsArgs(cflags)

class BuildConfigGen:
	def isAvailable (self, env):
		return True

class UnixConfig(BuildConfigGen):
	def __init__ (self, target, buildType, cc, cpp, cflags):
		self.target		= target
		self.buildType	= buildType
		self.cc			= cc
		self.cpp		= cpp
		self.cflags		= cflags

	def isAvailable (self, env):
		return which(self.cc) != None and which(self.cpp) != None

	def getBuildConfig (self, env, buildDir):
		args = makeBuildArgs(self.target, self.cc, self.cpp, self.cflags)
		return BuildConfig(buildDir, self.buildType, args, env.srcDir)

class VSConfig(BuildConfigGen):
	def __init__ (self, buildType):
		self.buildType = buildType

	def getBuildConfig (self, env, buildDir):
		args = ["-DCMAKE_C_FLAGS=/WX -DCMAKE_CXX_FLAGS=/WX"]
		return BuildConfig(buildDir, self.buildType, args, env.srcDir)

class Build(BuildTestStep):
	def __init__ (self, buildDir, configGen, generator):
		self.buildDir	= buildDir
		self.configGen	= configGen
		self.generator	= generator

	def getName (self):
		return self.buildDir

	def isAvailable (self, env):
		return self.configGen.isAvailable(env) and self.generator != None and self.generator.isAvailable()

	def run (self, env):
		# specialize config for env
		buildDir	= os.path.join(env.tmpDir, self.buildDir)
		curConfig	= self.configGen.getBuildConfig(env, buildDir)

		build(curConfig, self.generator)

class CheckSrcChanges(BuildTestStep):
	def getName (self):
		return "check for changes"

	def run (self, env):
		pushWorkingDir(env.srcDir)
		execute(["git", "diff", "--exit-code"])
		popWorkingDir()

def getClangVersion ():
	knownVersions = ["4.0", "3.9", "3.8", "3.7", "3.6", "3.5"]
	for version in knownVersions:
		if which("clang-" + version) != None:
			return "-" + version
	return ""

def runSteps (steps):
	for step in steps:
		if step.isAvailable(env):
			print("Run: %s" % step.getName())
			step.run(env)
		else:
			print("Skip: %s" % step.getName())

COMMON_CFLAGS		= ["-Werror", "-Wno-error=unused-function"]
COMMON_GCC_CFLAGS	= COMMON_CFLAGS + ["-Wno-implicit-fallthrough"]
COMMON_CLANG_CFLAGS	= COMMON_CFLAGS + ["-Wno-error=unused-command-line-argument"]
GCC_32BIT_CFLAGS	= COMMON_GCC_CFLAGS + ["-m32"]
CLANG_32BIT_CFLAGS	= COMMON_CLANG_CFLAGS + ["-m32"]
GCC_64BIT_CFLAGS	= COMMON_GCC_CFLAGS + ["-m64"]
CLANG_64BIT_CFLAGS	= COMMON_CLANG_CFLAGS + ["-m64"]
CLANG_VERSION		= getClangVersion()

# Always ran before any receipe
PREREQUISITES		= [
	RunScript(os.path.join("external", "fetch_sources.py"))
]

# Always ran after any receipe
POST_CHECKS			= [
	CheckSrcChanges()
]

BUILD_TARGETS		= [
	Build("clang-64-debug",
		  UnixConfig("null",
					 "Debug",
					 "clang" + CLANG_VERSION,
					 "clang++" + CLANG_VERSION,
					 CLANG_64BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("gcc-32-debug",
		  UnixConfig("null",
					 "Debug",
					 "gcc",
					 "g++",
					 GCC_32BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("gcc-64-release",
		  UnixConfig("null",
					 "Release",
					 "gcc",
					 "g++",
					 GCC_64BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("vs-64-debug",
		  VSConfig("Debug"),
		  ANY_VS_X64_GENERATOR),
]

EARLY_SPECIAL_RECIPES	= [
	('gen-inl-files', [
			RunScript(os.path.join("scripts", "gen_egl.py")),
			RunScript(os.path.join("scripts", "opengl", "gen_all.py")),
			RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework.py")),
			RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework_c.py")),
			RunScript(os.path.join("scripts", "gen_android_mk.py")),
		]),
	('gen-ext-deps', [
			RunScript(os.path.join("external", "vulkancts", "scripts", "gen_ext_deps.py"))
		]),
]

LATE_SPECIAL_RECIPES	= [
	('android-mustpass', [
			RunScript(os.path.join("scripts", "build_android_mustpass.py"),
					  lambda env: ["--build-dir", os.path.join(env.tmpDir, "android-mustpass")]),
		]),
	('vulkan-mustpass', [
			RunScript(os.path.join("external", "vulkancts", "scripts", "build_mustpass.py"),
					  lambda env: ["--build-dir", os.path.join(env.tmpDir, "vulkan-mustpass")]),
		]),
	('spirv-binaries', [
			RunScript(os.path.join("external", "vulkancts", "scripts", "build_spirv_binaries.py"),
					  lambda env: ["--build-dir", os.path.join(env.tmpDir, "spirv-binaries"),
									"--dst-path", os.path.join(env.tmpDir, "spirv-binaries")]),
		]),
	('check-all', [
			RunScript(os.path.join("scripts", "src_util", "check_all.py")),
		])
]

def getBuildRecipes ():
	return [(b.getName(), [b]) for b in BUILD_TARGETS]

def getAllRecipe (recipes):
	allSteps = []
	for name, steps in recipes:
		allSteps += steps
	return ("all", allSteps)

def getRecipes ():
	recipes = EARLY_SPECIAL_RECIPES + getBuildRecipes() + LATE_SPECIAL_RECIPES
	return recipes

def getRecipe (recipes, recipeName):
	for curName, steps in recipes:
		if curName == recipeName:
			return (curName, steps)
	return None

RECIPES			= getRecipes()

def parseArgs ():
	parser = argparse.ArgumentParser(description = "Build and test source",
									 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
	parser.add_argument("-s",
						"--src-dir",
						dest="srcDir",
						default=DEQP_DIR,
						help="Source directory")
	parser.add_argument("-t",
						"--tmp-dir",
						dest="tmpDir",
						default=os.path.join(tempfile.gettempdir(), "deqp-build-test"),
						help="Temporary directory")
	parser.add_argument("-r",
						"--recipe",
						dest="recipe",
						choices=[n for n, s in RECIPES] + ["all"],
						default="all",
						help="Build / test recipe")
	parser.add_argument("-d",
						"--dump-recipes",
						dest="dumpRecipes",
						action="store_true",
						help="Print out recipes that have any available actions")
	parser.add_argument("--skip-prerequisites",
						dest="skipPrerequisites",
						action="store_true",
						help="Skip external dependency fetch")

	return parser.parse_args()

if __name__ == "__main__":
	args	= parseArgs()
	env		= Environment(args.srcDir, args.tmpDir)

	if args.dumpRecipes:
		for name, steps in RECIPES:
			for step in steps:
				if step.isAvailable(env):
					print(name)
					break
	else:
		name, steps	= getAllRecipe(RECIPES) if args.recipe == "all" \
					  else getRecipe(RECIPES, args.recipe)

		print("Running %s" % name)

		allSteps = (PREREQUISITES if (args.skipPrerequisites == False) else []) + steps + POST_CHECKS
		runSteps(allSteps)

		print("All steps completed successfully")
<commit_msg>Squash ext-dep-target into gen-inl-files<commit_after># -*- coding: utf-8 -*-

#-------------------------------------------------------------------------
# drawElements Quality Program utilities
# --------------------------------------
#
# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#-------------------------------------------------------------------------

import os
import argparse
import tempfile
import sys

from build.common import *
from build.build import *

pythonExecutable = sys.executable or "python"

class Environment:
	def __init__ (self, srcDir, tmpDir):
		self.srcDir	= srcDir
		self.tmpDir	= tmpDir

class BuildTestStep:
	def getName (self):
		return "<unknown>"

	def isAvailable (self, env):
		return True

	def run (self, env):
		raise Exception("Not implemented")

class RunScript(BuildTestStep):
	def __init__ (self, scriptPath, getExtraArgs = None):
		self.scriptPath		= scriptPath
		self.getExtraArgs	= getExtraArgs

	def getName (self):
		return self.scriptPath

	def run (self, env):
		args = [pythonExecutable, os.path.join(env.srcDir, self.scriptPath)]

		if self.getExtraArgs != None:
			args += self.getExtraArgs(env)

		execute(args)

def makeCflagsArgs (cflags):
	cflagsStr = " ".join(cflags)
	return ["-DCMAKE_C_FLAGS=%s" % cflagsStr, "-DCMAKE_CXX_FLAGS=%s" % cflagsStr]

def makeBuildArgs (target, cc, cpp, cflags):
	return ["-DDEQP_TARGET=%s" % target, "-DCMAKE_C_COMPILER=%s" % cc, "-DCMAKE_CXX_COMPILER=%s" % cpp] + makeCflagsArgs(cflags)

class BuildConfigGen:
	def isAvailable (self, env):
		return True

class UnixConfig(BuildConfigGen):
	def __init__ (self, target, buildType, cc, cpp, cflags):
		self.target		= target
		self.buildType	= buildType
		self.cc			= cc
		self.cpp		= cpp
		self.cflags		= cflags

	def isAvailable (self, env):
		return which(self.cc) != None and which(self.cpp) != None

	def getBuildConfig (self, env, buildDir):
		args = makeBuildArgs(self.target, self.cc, self.cpp, self.cflags)
		return BuildConfig(buildDir, self.buildType, args, env.srcDir)

class VSConfig(BuildConfigGen):
	def __init__ (self, buildType):
		self.buildType = buildType

	def getBuildConfig (self, env, buildDir):
		args = ["-DCMAKE_C_FLAGS=/WX -DCMAKE_CXX_FLAGS=/WX"]
		return BuildConfig(buildDir, self.buildType, args, env.srcDir)

class Build(BuildTestStep):
	def __init__ (self, buildDir, configGen, generator):
		self.buildDir	= buildDir
		self.configGen	= configGen
		self.generator	= generator

	def getName (self):
		return self.buildDir

	def isAvailable (self, env):
		return self.configGen.isAvailable(env) and self.generator != None and self.generator.isAvailable()

	def run (self, env):
		# specialize config for env
		buildDir	= os.path.join(env.tmpDir, self.buildDir)
		curConfig	= self.configGen.getBuildConfig(env, buildDir)

		build(curConfig, self.generator)

class CheckSrcChanges(BuildTestStep):
	def getName (self):
		return "check for changes"

	def run (self, env):
		pushWorkingDir(env.srcDir)
		execute(["git", "diff", "--exit-code"])
		popWorkingDir()

def getClangVersion ():
	knownVersions = ["4.0", "3.9", "3.8", "3.7", "3.6", "3.5"]
	for version in knownVersions:
		if which("clang-" + version) != None:
			return "-" + version
	return ""

def runSteps (steps):
	for step in steps:
		if step.isAvailable(env):
			print("Run: %s" % step.getName())
			step.run(env)
		else:
			print("Skip: %s" % step.getName())

COMMON_CFLAGS		= ["-Werror", "-Wno-error=unused-function"]
COMMON_GCC_CFLAGS	= COMMON_CFLAGS + ["-Wno-implicit-fallthrough"]
COMMON_CLANG_CFLAGS	= COMMON_CFLAGS + ["-Wno-error=unused-command-line-argument"]
GCC_32BIT_CFLAGS	= COMMON_GCC_CFLAGS + ["-m32"]
CLANG_32BIT_CFLAGS	= COMMON_CLANG_CFLAGS + ["-m32"]
GCC_64BIT_CFLAGS	= COMMON_GCC_CFLAGS + ["-m64"]
CLANG_64BIT_CFLAGS	= COMMON_CLANG_CFLAGS + ["-m64"]
CLANG_VERSION		= getClangVersion()

# Always ran before any receipe
PREREQUISITES		= [
	RunScript(os.path.join("external", "fetch_sources.py"))
]

# Always ran after any receipe
POST_CHECKS			= [
	CheckSrcChanges()
]

BUILD_TARGETS		= [
	Build("clang-64-debug",
		  UnixConfig("null",
					 "Debug",
					 "clang" + CLANG_VERSION,
					 "clang++" + CLANG_VERSION,
					 CLANG_64BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("gcc-32-debug",
		  UnixConfig("null",
					 "Debug",
					 "gcc",
					 "g++",
					 GCC_32BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("gcc-64-release",
		  UnixConfig("null",
					 "Release",
					 "gcc",
					 "g++",
					 GCC_64BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("vs-64-debug",
		  VSConfig("Debug"),
		  ANY_VS_X64_GENERATOR),
]

EARLY_SPECIAL_RECIPES	= [
	('gen-inl-files', [
			RunScript(os.path.join("scripts", "gen_egl.py")),
			RunScript(os.path.join("scripts", "opengl", "gen_all.py")),
			RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework.py")),
			RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework_c.py")),
			RunScript(os.path.join("external", "vulkancts", "scripts", "gen_ext_deps.py")),
			RunScript(os.path.join("scripts", "gen_android_mk.py"))
		]),
]

LATE_SPECIAL_RECIPES	= [
	('android-mustpass', [
			RunScript(os.path.join("scripts", "build_android_mustpass.py"),
					  lambda env: ["--build-dir", os.path.join(env.tmpDir, "android-mustpass")]),
		]),
	('vulkan-mustpass', [
			RunScript(os.path.join("external", "vulkancts", "scripts", "build_mustpass.py"),
					  lambda env: ["--build-dir", os.path.join(env.tmpDir, "vulkan-mustpass")]),
		]),
	('spirv-binaries', [
			RunScript(os.path.join("external", "vulkancts", "scripts", "build_spirv_binaries.py"),
					  lambda env: ["--build-dir", os.path.join(env.tmpDir, "spirv-binaries"),
									"--dst-path", os.path.join(env.tmpDir, "spirv-binaries")]),
		]),
	('check-all', [
			RunScript(os.path.join("scripts", "src_util", "check_all.py")),
		])
]

def getBuildRecipes ():
	return [(b.getName(), [b]) for b in BUILD_TARGETS]

def getAllRecipe (recipes):
	allSteps = []
	for name, steps in recipes:
		allSteps += steps
	return ("all", allSteps)

def getRecipes ():
	recipes = EARLY_SPECIAL_RECIPES + getBuildRecipes() + LATE_SPECIAL_RECIPES
	return recipes

def getRecipe (recipes, recipeName):
	for curName, steps in recipes:
		if curName == recipeName:
			return (curName, steps)
	return None

RECIPES			= getRecipes()

def parseArgs ():
	parser = argparse.ArgumentParser(description = "Build and test source",
									 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
	parser.add_argument("-s",
						"--src-dir",
						dest="srcDir",
						default=DEQP_DIR,
						help="Source directory")
	parser.add_argument("-t",
						"--tmp-dir",
						dest="tmpDir",
						default=os.path.join(tempfile.gettempdir(), "deqp-build-test"),
						help="Temporary directory")
	parser.add_argument("-r",
						"--recipe",
						dest="recipe",
						choices=[n for n, s in RECIPES] + ["all"],
						default="all",
						help="Build / test recipe")
	parser.add_argument("-d",
						"--dump-recipes",
						dest="dumpRecipes",
						action="store_true",
						help="Print out recipes that have any available actions")
	parser.add_argument("--skip-prerequisites",
						dest="skipPrerequisites",
						action="store_true",
						help="Skip external dependency fetch")

	return parser.parse_args()

if __name__ == "__main__":
	args	= parseArgs()
	env		= Environment(args.srcDir, args.tmpDir)

	if args.dumpRecipes:
		for name, steps in RECIPES:
			for step in steps:
				if step.isAvailable(env):
					print(name)
					break
	else:
		name, steps	= getAllRecipe(RECIPES) if args.recipe == "all" \
					  else getRecipe(RECIPES, args.recipe)

		print("Running %s" % name)

		allSteps = (PREREQUISITES if (args.skipPrerequisites == False) else []) + steps + POST_CHECKS
		runSteps(allSteps)

		print("All steps completed successfully")
<|endoftext|>


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

"""Provides functions that get the authenticated user from the ``request``."""

from pyramid.security import unauthenticated_userid
from .model import get_existing_user

# Reified request properties.
def get_is_authenticated(request):
    """Has this ``request`` been made by an authenticated user?

      Setup::

          >>> from mock import Mock
          >>> from pyramid_simpleauth import hooks
          >>> _unauthenticated_userid = hooks.unauthenticated_userid
          >>> hooks.unauthenticated_userid = Mock()
          >>> mock_request = Mock()

      When the request is not authenticated, returns ``False``::

          >>> hooks.unauthenticated_userid.return_value = None
          >>> get_is_authenticated(mock_request)
          False

      When the request is authenticated, returns ``True``::

          >>> hooks.unauthenticated_userid.return_value = 1234
          >>> get_is_authenticated(mock_request)
          True

      Teardown::

          >>> hooks.unauthenticated_userid = _unauthenticated_userid

    """

    return bool(unauthenticated_userid(request))

def get_authenticated_user(request):
    """Get the authenticated user for this ``request``, if it has one.

      Setup::

          >>> from mock import Mock
          >>> from pyramid_simpleauth import hooks
          >>> _unauthenticated_userid = hooks.unauthenticated_userid
          >>> _get_existing_user = hooks.get_existing_user
          >>> hooks.unauthenticated_userid = Mock()
          >>> hooks.get_existing_user = Mock()
          >>> mock_request = Mock()

      When the request is authenticated and the user exists, returns the user::

          >>> hooks.unauthenticated_userid.return_value = 1234
          >>> hooks.get_existing_user.return_value = 'user'
          >>> get_authenticated_user(mock_request)
          'user'

      When the request is authenticated but the user doesn't exists, returns
      ``None``::

          >>> hooks.get_existing_user.return_value = None
          >>> get_authenticated_user(mock_request)

      When the request is not authenticated, doesn't try to find the user::

          >>> hooks.get_existing_user = Mock()
          >>> hooks.unauthenticated_userid.return_value = None
          >>> get_authenticated_user(mock_request)
          >>> hooks.get_existing_user.called
          False

      Teardown::

          >>> hooks.unauthenticated_userid = _unauthenticated_userid
          >>> hooks.get_existing_user = _get_existing_user

    """

    canonical_id = unauthenticated_userid(request)
    if canonical_id:
        return get_existing_user(canonical_id=canonical_id)

# Authorization group finder.
def get_roles(canonical_id, request):
    """Get the roles the authenticated user has.

      Setup::

          >>> from mock import Mock
          >>> mock_request = Mock()
          >>> mock_user = Mock()
          >>> mock_role = Mock()
          >>> mock_role.name = 'editor'
          >>> mock_user.roles = [mock_role]
          >>> mock_request.user = mock_user

      Test::

          >>> get_roles(None, mock_request)
          ['editor']

    """

    user = request.user
    if user:
        return [role.name for role in user.roles]

<commit_msg>roles: name roles `r:rolename` to make a username namespace clash impossible.<commit_after># -*- coding: utf-8 -*-

"""Provides functions that get the authenticated user from the ``request``."""

from pyramid.security import unauthenticated_userid
from .model import get_existing_user

# Reified request properties.
def get_is_authenticated(request):
    """Has this ``request`` been made by an authenticated user?

      Setup::

          >>> from mock import Mock
          >>> from pyramid_simpleauth import hooks
          >>> _unauthenticated_userid = hooks.unauthenticated_userid
          >>> hooks.unauthenticated_userid = Mock()
          >>> mock_request = Mock()

      When the request is not authenticated, returns ``False``::

          >>> hooks.unauthenticated_userid.return_value = None
          >>> get_is_authenticated(mock_request)
          False

      When the request is authenticated, returns ``True``::

          >>> hooks.unauthenticated_userid.return_value = 1234
          >>> get_is_authenticated(mock_request)
          True

      Teardown::

          >>> hooks.unauthenticated_userid = _unauthenticated_userid

    """

    return bool(unauthenticated_userid(request))

def get_authenticated_user(request):
    """Get the authenticated user for this ``request``, if it has one.

      Setup::

          >>> from mock import Mock
          >>> from pyramid_simpleauth import hooks
          >>> _unauthenticated_userid = hooks.unauthenticated_userid
          >>> _get_existing_user = hooks.get_existing_user
          >>> hooks.unauthenticated_userid = Mock()
          >>> hooks.get_existing_user = Mock()
          >>> mock_request = Mock()

      When the request is authenticated and the user exists, returns the user::

          >>> hooks.unauthenticated_userid.return_value = 1234
          >>> hooks.get_existing_user.return_value = 'user'
          >>> get_authenticated_user(mock_request)
          'user'

      When the request is authenticated but the user doesn't exists, returns
      ``None``::

          >>> hooks.get_existing_user.return_value = None
          >>> get_authenticated_user(mock_request)

      When the request is not authenticated, doesn't try to find the user::

          >>> hooks.get_existing_user = Mock()
          >>> hooks.unauthenticated_userid.return_value = None
          >>> get_authenticated_user(mock_request)
          >>> hooks.get_existing_user.called
          False

      Teardown::

          >>> hooks.unauthenticated_userid = _unauthenticated_userid
          >>> hooks.get_existing_user = _get_existing_user

    """

    canonical_id = unauthenticated_userid(request)
    if canonical_id:
        return get_existing_user(canonical_id=canonical_id)

# Authorization group finder.
def get_roles(canonical_id, request):
    """Get the roles the authenticated user has.

      Setup::

          >>> from mock import Mock
          >>> mock_request = Mock()
          >>> mock_user = Mock()
          >>> mock_role = Mock()
          >>> mock_role.name = u'editor'
          >>> mock_user.roles = [mock_role]
          >>> mock_request.user = mock_user

      Test::

          >>> get_roles(None, mock_request)
          [u'r:editor']

    """

    user = request.user
    if user:
        return [u'r:{0}'.format(role.name) for role in user.roles]

<|endoftext|>


<commit_before># Copyright (c) 2005 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert

# The SmartDict class fixes a couple of issues with using the content
# of os.environ or similar dicts of strings as Python variables:
#
# 1) Undefined variables should return False rather than raising KeyError.
#
# 2) String values of 'False', '0', etc., should evaluate to False
#    (not just the empty string).
#
# #1 is solved by overriding __getitem__, and #2 is solved by using a
# proxy class for values and overriding __nonzero__ on the proxy.
# Everything else is just to (a) make proxies behave like normal
# values otherwise, (b) make sure any dict operation returns a proxy
# rather than a normal value, and (c) coerce values written to the
# dict to be strings.

from convert import *

class Variable(str):
    """Intelligent proxy class for SmartDict.  Variable will use the
    various convert functions to attempt to convert values to useable
    types"""
    def __int__(self):
        return toInteger(str(self))
    def __long__(self):
        return toLong(str(self))
    def __float__(self):
        return toFloat(str(self))
    def __nonzero__(self):
        return toBool(str(self))
    def convert(self, other):
        t = type(other)
        if t == bool:
            return bool(self)
        if t == int:
            return int(self)
        if t == long:
            return long(self)
        if t == float:
            return float(self)
        return str(self)
    def __lt__(self, other):
        return self.convert(other) < other
    def __le__(self, other):
        return self.convert(other) <= other
    def __eq__(self, other):
        return self.convert(other) == other
    def __ne__(self, other):
        return self.convert(other) != other
    def __gt__(self, other):
        return self.convert(other) > other
    def __ge__(self, other):
        return self.convert(other) >= other

    def __add__(self, other):
        return self.convert(other) + other
    def __sub__(self, other):
        return self.convert(other) - other
    def __mul__(self, other):
        return self.convert(other) * other
    def __div__(self, other):
        return self.convert(other) / other
    def __truediv__(self, other):
        return self.convert(other) / other

    def __radd__(self, other):
        return other + self.convert(other)
    def __rsub__(self, other):
        return other - self.convert(other)
    def __rmul__(self, other):
        return other * self.convert(other)
    def __rdiv__(self, other):
        return other / self.convert(other)
    def __rtruediv__(self, other):
        return other / self.convert(other)

class UndefinedVariable(object):
    """Placeholder class to represent undefined variables.  Will
    generally cause an exception whenever it is used, but evaluates to
    zero for boolean truth testing such as in an if statement"""
    def __nonzero__(self):
        return False

class SmartDict(dict):
    """Dictionary class that holds strings, but intelligently converts
    those strings to other types depending on their usage"""

    def __getitem__(self, key):
        """returns a Variable proxy if the values exists in the database and
        returns an UndefinedVariable otherwise"""

        if key in self:
            return Variable(dict.get(self, key))
        else:
            # Note that this does *not* change the contents of the dict,
            # so that even after we call env['foo'] we still get a
            # meaningful answer from "'foo' in env" (which
            # calls dict.__contains__, which we do not override).
            return UndefinedVariable()

    def __setitem__(self, key, item):
        """intercept the setting of any variable so that we always
        store strings in the dict"""
        dict.__setitem__(self, key, str(item))

    def values(self):
        return [ Variable(v) for v in dict.values(self) ]

    def itervalues(self):
        for value in dict.itervalues(self):
            yield Variable(value)

    def items(self):
        return [ (k, Variable(v)) for k,v in dict.items(self) ]

    def iteritems(self):
        for key,value in dict.iteritems(self):
            yield key, Variable(value)

    def get(self, key, default='False'):
        return Variable(dict.get(self, key, str(default)))

    def setdefault(self, key, default='False'):
        return Variable(dict.setdefault(self, key, str(default)))

__all__ = [ 'SmartDict' ]
<commit_msg>SmartDict: Make SmartDict an attrdict<commit_after># Copyright (c) 2005 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert

# The SmartDict class fixes a couple of issues with using the content
# of os.environ or similar dicts of strings as Python variables:
#
# 1) Undefined variables should return False rather than raising KeyError.
#
# 2) String values of 'False', '0', etc., should evaluate to False
#    (not just the empty string).
#
# #1 is solved by overriding __getitem__, and #2 is solved by using a
# proxy class for values and overriding __nonzero__ on the proxy.
# Everything else is just to (a) make proxies behave like normal
# values otherwise, (b) make sure any dict operation returns a proxy
# rather than a normal value, and (c) coerce values written to the
# dict to be strings.

from convert import *
from attrdict import attrdict

class Variable(str):
    """Intelligent proxy class for SmartDict.  Variable will use the
    various convert functions to attempt to convert values to useable
    types"""
    def __int__(self):
        return toInteger(str(self))
    def __long__(self):
        return toLong(str(self))
    def __float__(self):
        return toFloat(str(self))
    def __nonzero__(self):
        return toBool(str(self))
    def convert(self, other):
        t = type(other)
        if t == bool:
            return bool(self)
        if t == int:
            return int(self)
        if t == long:
            return long(self)
        if t == float:
            return float(self)
        return str(self)
    def __lt__(self, other):
        return self.convert(other) < other
    def __le__(self, other):
        return self.convert(other) <= other
    def __eq__(self, other):
        return self.convert(other) == other
    def __ne__(self, other):
        return self.convert(other) != other
    def __gt__(self, other):
        return self.convert(other) > other
    def __ge__(self, other):
        return self.convert(other) >= other

    def __add__(self, other):
        return self.convert(other) + other
    def __sub__(self, other):
        return self.convert(other) - other
    def __mul__(self, other):
        return self.convert(other) * other
    def __div__(self, other):
        return self.convert(other) / other
    def __truediv__(self, other):
        return self.convert(other) / other

    def __radd__(self, other):
        return other + self.convert(other)
    def __rsub__(self, other):
        return other - self.convert(other)
    def __rmul__(self, other):
        return other * self.convert(other)
    def __rdiv__(self, other):
        return other / self.convert(other)
    def __rtruediv__(self, other):
        return other / self.convert(other)

class UndefinedVariable(object):
    """Placeholder class to represent undefined variables.  Will
    generally cause an exception whenever it is used, but evaluates to
    zero for boolean truth testing such as in an if statement"""
    def __nonzero__(self):
        return False

class SmartDict(attrdict):
    """Dictionary class that holds strings, but intelligently converts
    those strings to other types depending on their usage"""

    def __getitem__(self, key):
        """returns a Variable proxy if the values exists in the database and
        returns an UndefinedVariable otherwise"""

        if key in self:
            return Variable(dict.get(self, key))
        else:
            # Note that this does *not* change the contents of the dict,
            # so that even after we call env['foo'] we still get a
            # meaningful answer from "'foo' in env" (which
            # calls dict.__contains__, which we do not override).
            return UndefinedVariable()

    def __setitem__(self, key, item):
        """intercept the setting of any variable so that we always
        store strings in the dict"""
        dict.__setitem__(self, key, str(item))

    def values(self):
        return [ Variable(v) for v in dict.values(self) ]

    def itervalues(self):
        for value in dict.itervalues(self):
            yield Variable(value)

    def items(self):
        return [ (k, Variable(v)) for k,v in dict.items(self) ]

    def iteritems(self):
        for key,value in dict.iteritems(self):
            yield key, Variable(value)

    def get(self, key, default='False'):
        return Variable(dict.get(self, key, str(default)))

    def setdefault(self, key, default='False'):
        return Variable(dict.setdefault(self, key, str(default)))

__all__ = [ 'SmartDict' ]
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""This script automates the process of getting a signed TLS certificate from
Let's Encrypt using the ACME v2 protocol. It will need to be run on your
server and have access to your private account key, so PLEASE READ THROUGH IT!
It won't take long."""

import base64
import binascii
import copy
import hashlib
import json
import logging
import os
import re
import subprocess
import sys
import textwrap
import time

try:
    from urllib.request import urlopen  # Python 3
    from urllib.error import HTTPError
except ImportError:
    from urllib2 import urlopen, HTTPError  # Python 2

DEFAULT_CA = "https://acme-staging.api.letsencrypt.org/directory"
# DEFAULT_CA = "https://acme-v02.api.letsencrypt.org/directory"

LOGGER = logging.getLogger(__name__)
LOGGER_HANDLER = logging.StreamHandler()
LOGGER_HANDLER.setFormatter(logging.Formatter('%(asctime)s %(message)s'))
LOGGER.addHandler(LOGGER_HANDLER)
LOGGER.setLevel(logging.INFO)

# helper function to base64 encode for jose spec
def _b64(data):
    return base64.urlsafe_b64encode(data).decode('utf8').rstrip('=')

# helper function for openssl subprocess
def _openssl(command, options, communicate=None):
    openssl = subprocess.Popen(["openssl", command] + options, stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = openssl.communicate(communicate)
    if openssl.returncode != 0:
        raise IOError("OpenSSL Error: {0}".format(err))
    return out

class ACMETiny(object):
    """ACMETiny implements a minimal client for the IETF Automatic Certificate
    Management Environment (ACME) protocol"""

    def __init__(self, account_key, csr, acme_dir, ca=None):
        self.paths = {"account_key": account_key, "csr": csr, "acme_dir": acme_dir}
        self.acme_ca = ca or DEFAULT_CA
        self.kid = self.header = self.thumbprint = self.certificate = None
        self.log = LOGGER

    # helper function for rate limited queries
    def _urlopen_retry(self, url, retry_type, error_message):
        while True:
            self.log.debug("Fetching: %s", url)
            try:
                resp = urlopen(url)
                result = json.loads(resp.read().decode('utf8'))
            except HTTPError as err:
                raise ValueError("Error fetching url: {0} {1} {2}".format(
                    url, err.code, json.loads(err.read().decode('utf8'))))
            if result['status'] == retry_type:
                retry_after = resp.info().get('Retry-After')
                if isinstance(retry_after, (str)) and retry_after.isdigit():
                    retry_after = int(retry_after)
                else:
                    retry_after = 2
                self.log.debug("%s: retrying in %d...", retry_type, retry_after)
                time.sleep(retry_after)
            elif result['status'] == 'valid':
                return result
            else:
                raise ValueError(error_message.format(result=result))

    # helper function to make signed requests
    def _send_signed_request(self, url_or_key, payload, return_codes, error_message):
        self.log.debug("Signed request url or key: %s", url_or_key)
        self.log.debug("Signed request payload: %s", payload)
        payload = _b64(json.dumps(payload).encode('utf8'))
        while True:
            protected = copy.deepcopy(self.header)
            resp = urlopen(self.acme_ca)
            result = json.loads(resp.read().decode('utf8'))
            if url_or_key in result:
                url = result[url_or_key]  # Use the URL from the /directory response
            else:
                url = url_or_key
            if url_or_key not in ['newAccount', 'revokeCert']:
                del protected['jwk']
                protected['kid'] = self.kid
            protected['nonce'] = resp.headers['Replay-Nonce']
            protected['url'] = url
            protected = _b64(json.dumps(protected).encode('utf8'))
            sig = _b64(_openssl("dgst", ["-sha256", "-sign", self.paths['account_key']],
                                communicate="{0}.{1}".format(protected, payload).encode("utf8")))
            data = json.dumps({"protected": protected, "payload": payload, "signature": sig})

            try:
                resp = urlopen(url, data.encode('utf8'))
                code, result, headers = resp.getcode(), resp.read().decode('utf8'), resp.info()
                message = return_codes[code]
                break
            except HTTPError as err:
                code, result = err.code, json.loads(err.read().decode('utf8'))
                if code == 400 and result['type'] == 'urn:ietf:params:acme:error:badNonce':
                    self.log.warning("badNonce error: retrying...")
                    continue
                raise ValueError(error_message.format(code=code, result=result))
            except KeyError:
                raise ValueError(error_message.format(code=code, result=json.loads(result)))
        if message is not None:
            self.log.info(message)
        return result, headers

    # helper function to make authorization requests
    def _authz(self, url):
        self.log.debug("Authz: %s", url)
        try:
            resp = urlopen(url)
            resp_data = json.loads(resp.read().decode('utf8'))
        except HTTPError as err:
            error_message = "Error getting authz: {0} {1}"
            raise ValueError(error_message.format(err.code, json.loads(err.read().decode('utf8'))))
        domain = resp_data['identifier']['value']
        self.log.info("Verifying %s...", domain)

        # make the challenge file
        challenge = [c for c in resp_data['challenges'] if c['type'] == "http-01"][0]
        token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
        keyauthorization = "{0}.{1}".format(token, self.thumbprint)
        wellknown_path = os.path.join(self.paths['acme_dir'], token)
        with open(wellknown_path, "w") as wellknown_file:
            wellknown_file.write(keyauthorization)

        # check that the file is in place
        wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(domain, token)
        try:
            resp = urlopen(wellknown_url)
            resp_data = resp.read().decode('utf8').strip()
            assert resp_data == keyauthorization
        except (IOError, AssertionError):
            os.remove(wellknown_path)
            error_message = "Wrote file to {0}, but couldn't download {1}"
            raise ValueError(error_message.format(wellknown_path, wellknown_url))

        # notify that the challenge is met
        payload = {"keyAuthorization": keyauthorization}
        self._send_signed_request(challenge['url'], payload, {200: "Challenge sent!"},
                                  "Error triggering challenge: {code} {result}")
        self._urlopen_retry(challenge['url'], 'pending', "Challenge did not pass: {result}")
        self.log.info("%s verified!", domain)
        os.remove(wellknown_path)

    def parse_account_key(self):
        """Parse account key to get public key and thumbprint."""
        self.log.info("Parsing account key...")
        result = _openssl("rsa", ["-in", self.paths['account_key'], "-noout", "-text"])
        pub_hex, pub_exp = re.search(
            r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)",
            result.decode('utf8'), re.MULTILINE | re.DOTALL).groups()
        pub_exp = "{0:x}".format(int(pub_exp))
        pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
        self.header = {
            "alg": "RS256",
            "jwk": {
                "e": _b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
                "kty": "RSA",
                "n": _b64(binascii.unhexlify(re.sub(r"(\s|:)", "", pub_hex).encode("utf-8")))
            }
        }
        accountkey_json = json.dumps(self.header['jwk'], sort_keys=True, separators=(',', ':'))
        self.thumbprint = _b64(hashlib.sha256(accountkey_json.encode('utf8')).digest())

    def register_account(self):
        """Register the account and obtain Key ID."""
        self.log.info("Registering account...")
        payload = {"termsOfServiceAgreed": True}
        return_codes = {201: "Registered!", 200: "Already registered!"}
        error_message = "Error registering: {code} {result}"
        _result, headers = self._send_signed_request("newAccount", payload,
                                                     return_codes, error_message)
        self.kid = headers['Location']
        self.log.debug("Key ID: %s", self.kid)

    def get_certificate(self):
        """Get signed certificate."""
        if self.thumbprint is None or self.header is None:
            self.parse_account_key()
        if self.kid is None:
            self.register_account()

        self.log.debug("Creating new order from %s", self.paths['csr'])
        # find domains
        self.log.info("Parsing CSR...")
        csr_dump = _openssl("req", ["-in", self.paths['csr'], "-noout", "-text"]).decode("utf8")
        domains = []
        common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", csr_dump)
        if common_name is not None:
            domains.append({"type": "dns", "value": common_name.group(1)})
        subject_alt_names = re.search(r"X509v3 Subject Alternative Name: \n +([^\n]+)\n",
                                      csr_dump, re.MULTILINE|re.DOTALL)
        if subject_alt_names is not None:
            for san in subject_alt_names.group(1).split(", "):
                if san.startswith("DNS:"):
                    domains.append({"type": "dns", "value": san[4:]})
        payload = {"identifiers": domains}
        return_codes = {201: "Success!"}
        error_message = "Error requesting order: {code} {result}"
        self.log.info("Sending newOrder request...")
        result, headers = self._send_signed_request("newOrder", payload,
                                                    return_codes, error_message)

        order_url = headers['Location']
        authorizations = json.loads(result)['authorizations']
        for auth_url in authorizations:
            self._authz(auth_url)

        self.log.debug("Checking order to get finalize URL...")
        resp = urlopen(order_url)
        result = json.loads(resp.read().decode('utf8'))
        payload = {"csr": _b64(_openssl("req", ["-in", self.paths['csr'], "-outform", "DER"]))}
        return_codes = {200: "Success!"}
        error_message = "Error POSTing to finalize URL: {code} {result}"
        self.log.info("POSTing CSR to finalize URL...")
        self._send_signed_request(result['finalize'], payload, return_codes, error_message)
        result = self._urlopen_retry(order_url, 'processing', "Order isn't valid: {result}")
        self.log.debug("Downloading certificate: %s", result['certificate'])
        self.certificate = urlopen(result['certificate']).read().decode('utf8')
        self.log.info("Certificate signed!")

def main(argv):
    """Parse command line arguments and feed them to ACMETiny."""
    import argparse
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent("""\
            This script automates the process of getting a signed TLS certificate from
            Let's Encrypt using the ACME v2 protocol. It will need to be run on your
            server and have access to your private account key, so PLEASE READ THROUGH IT!
            It won't take long.

            ===Example Usage===
            python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ --output ./certificate.pem
            ===================

            ===Example Crontab Renewal (once per month)===
            0 0 1 * * python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ --output /path/to/certificate.pem 2>> /var/log/acme_tiny.log
            ==============================================
            """)
    )
    parser.add_argument("--account-key", required=True,
                        help="path to your Let's Encrypt account private key")
    parser.add_argument("--csr", required=True,
                        help="path to your certificate signing request")
    parser.add_argument("--acme-dir", required=True,
                        help="path to the .well-known/acme-challenge/ directory")
    parser.add_argument("--quiet", action="store_const", const=logging.ERROR,
                        help="suppress output except for errors")
    parser.add_argument("--ca", default=None,
                        help="certificate authority's directory object, default is Let's Encrypt")
    parser.add_argument("--output", "-o", metavar="FILE", default=None,
                        help="output file, default is standard output")

    args = parser.parse_args(argv)

    acme = ACMETiny(args.account_key, args.csr, args.acme_dir, ca=args.ca)
    acme.log.setLevel(args.quiet or acme.log.level)
    acme.get_certificate()
    with open(args.output, 'w') if args.output else sys.stdout as output:
        output.write(acme.certificate)

if __name__ == "__main__":  # pragma: no cover
    main(sys.argv[1:])
<commit_msg>Return decoded JSON object from signed requests.<commit_after>#!/usr/bin/env python
"""This script automates the process of getting a signed TLS certificate from
Let's Encrypt using the ACME v2 protocol. It will need to be run on your
server and have access to your private account key, so PLEASE READ THROUGH IT!
It won't take long."""

import base64
import binascii
import copy
import hashlib
import json
import logging
import os
import re
import subprocess
import sys
import textwrap
import time

try:
    from urllib.request import urlopen  # Python 3
    from urllib.error import HTTPError
except ImportError:
    from urllib2 import urlopen, HTTPError  # Python 2

DEFAULT_CA = "https://acme-staging.api.letsencrypt.org/directory"
# DEFAULT_CA = "https://acme-v02.api.letsencrypt.org/directory"

LOGGER = logging.getLogger(__name__)
LOGGER_HANDLER = logging.StreamHandler()
LOGGER_HANDLER.setFormatter(logging.Formatter('%(asctime)s %(message)s'))
LOGGER.addHandler(LOGGER_HANDLER)
LOGGER.setLevel(logging.INFO)

# helper function to base64 encode for jose spec
def _b64(data):
    return base64.urlsafe_b64encode(data).decode('utf8').rstrip('=')

# helper function for openssl subprocess
def _openssl(command, options, communicate=None):
    openssl = subprocess.Popen(["openssl", command] + options, stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = openssl.communicate(communicate)
    if openssl.returncode != 0:
        raise IOError("OpenSSL Error: {0}".format(err))
    return out

class ACMETiny(object):
    """ACMETiny implements a minimal client for the IETF Automatic Certificate
    Management Environment (ACME) protocol"""

    def __init__(self, account_key, csr, acme_dir, ca=None):
        self.paths = {"account_key": account_key, "csr": csr, "acme_dir": acme_dir}
        self.acme_ca = ca or DEFAULT_CA
        self.kid = self.header = self.thumbprint = self.certificate = None
        self.log = LOGGER

    # helper function for rate limited queries
    def _urlopen_retry(self, url, retry_type, error_message):
        while True:
            self.log.debug("Fetching: %s", url)
            try:
                resp = urlopen(url)
                result = json.loads(resp.read().decode('utf8'))
            except HTTPError as err:
                raise ValueError("Error fetching url: {0} {1} {2}".format(
                    url, err.code, json.loads(err.read().decode('utf8'))))
            if result['status'] == retry_type:
                retry_after = resp.info().get('Retry-After')
                if isinstance(retry_after, (str)) and retry_after.isdigit():
                    retry_after = int(retry_after)
                else:
                    retry_after = 2
                self.log.debug("%s: retrying in %d...", retry_type, retry_after)
                time.sleep(retry_after)
            elif result['status'] == 'valid':
                return result
            else:
                raise ValueError(error_message.format(result=result))

    # helper function to make signed requests
    def _send_signed_request(self, url_or_key, payload, return_codes, error_message):
        self.log.debug("Signed request url or key: %s", url_or_key)
        self.log.debug("Signed request payload: %s", payload)
        payload = _b64(json.dumps(payload).encode('utf8'))
        while True:
            protected = copy.deepcopy(self.header)
            resp = urlopen(self.acme_ca)
            result = json.loads(resp.read().decode('utf8'))
            if url_or_key in result:
                url = result[url_or_key]  # Use the URL from the /directory response
            else:
                url = url_or_key
            if url_or_key not in ['newAccount', 'revokeCert']:
                del protected['jwk']
                protected['kid'] = self.kid
            protected['nonce'] = resp.headers['Replay-Nonce']
            protected['url'] = url
            protected = _b64(json.dumps(protected).encode('utf8'))
            sig = _b64(_openssl("dgst", ["-sha256", "-sign", self.paths['account_key']],
                                communicate="{0}.{1}".format(protected, payload).encode("utf8")))
            data = json.dumps({"protected": protected, "payload": payload, "signature": sig})

            try:
                resp = urlopen(url, data.encode('utf8'))
                code, result = resp.getcode(), json.loads(resp.read().decode('utf8'))
                headers, message = resp.info(), return_codes[code]
                break
            except HTTPError as err:
                code, result = err.code, json.loads(err.read().decode('utf8'))
                if code == 400 and result['type'] == 'urn:ietf:params:acme:error:badNonce':
                    self.log.warning("badNonce error: retrying...")
                    continue
                raise ValueError(error_message.format(code=code, result=result))
            except KeyError:
                raise ValueError(error_message.format(code=code, result=result))
        if message is not None:
            self.log.info(message)
        return result, headers

    # helper function to make authorization requests
    def _authz(self, url):
        self.log.debug("Authz: %s", url)
        try:
            resp = urlopen(url)
            resp_data = json.loads(resp.read().decode('utf8'))
        except HTTPError as err:
            error_message = "Error getting authz: {0} {1}"
            raise ValueError(error_message.format(err.code, json.loads(err.read().decode('utf8'))))
        domain = resp_data['identifier']['value']
        self.log.info("Verifying %s...", domain)

        # make the challenge file
        challenge = [c for c in resp_data['challenges'] if c['type'] == "http-01"][0]
        token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
        keyauthorization = "{0}.{1}".format(token, self.thumbprint)
        wellknown_path = os.path.join(self.paths['acme_dir'], token)
        with open(wellknown_path, "w") as wellknown_file:
            wellknown_file.write(keyauthorization)

        # check that the file is in place
        wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(domain, token)
        try:
            resp = urlopen(wellknown_url)
            resp_data = resp.read().decode('utf8').strip()
            assert resp_data == keyauthorization
        except (IOError, AssertionError):
            os.remove(wellknown_path)
            error_message = "Wrote file to {0}, but couldn't download {1}"
            raise ValueError(error_message.format(wellknown_path, wellknown_url))

        # notify that the challenge is met
        payload = {"keyAuthorization": keyauthorization}
        self._send_signed_request(challenge['url'], payload, {200: "Challenge sent..."},
                                  "Error triggering challenge: {code} {result}")
        self._urlopen_retry(challenge['url'], 'pending', "Challenge did not pass: {result}")
        self.log.info("%s verified!", domain)
        os.remove(wellknown_path)

    def parse_account_key(self):
        """Parse account key to get public key and thumbprint."""
        self.log.info("Parsing account key...")
        result = _openssl("rsa", ["-in", self.paths['account_key'], "-noout", "-text"])
        pub_hex, pub_exp = re.search(
            r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)",
            result.decode('utf8'), re.MULTILINE | re.DOTALL).groups()
        pub_exp = "{0:x}".format(int(pub_exp))
        pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
        self.header = {
            "alg": "RS256",
            "jwk": {
                "e": _b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
                "kty": "RSA",
                "n": _b64(binascii.unhexlify(re.sub(r"(\s|:)", "", pub_hex).encode("utf-8")))
            }
        }
        accountkey_json = json.dumps(self.header['jwk'], sort_keys=True, separators=(',', ':'))
        self.thumbprint = _b64(hashlib.sha256(accountkey_json.encode('utf8')).digest())

    def register_account(self):
        """Register the account and obtain Key ID."""
        self.log.info("Registering account...")
        payload = {"termsOfServiceAgreed": True}
        return_codes = {201: "Registered!", 200: "Already registered!"}
        error_message = "Error registering: {code} {result}"
        _result, headers = self._send_signed_request("newAccount", payload,
                                                     return_codes, error_message)
        self.kid = headers['Location']
        self.log.debug("Key ID: %s", self.kid)

    def get_certificate(self):
        """Get signed certificate."""
        if self.thumbprint is None or self.header is None:
            self.parse_account_key()
        if self.kid is None:
            self.register_account()

        self.log.debug("Creating new order from %s", self.paths['csr'])
        # find domains
        self.log.info("Parsing CSR...")
        csr_dump = _openssl("req", ["-in", self.paths['csr'], "-noout", "-text"]).decode("utf8")
        domains = []
        common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", csr_dump)
        if common_name is not None:
            domains.append({"type": "dns", "value": common_name.group(1)})
        subject_alt_names = re.search(r"X509v3 Subject Alternative Name: \n +([^\n]+)\n",
                                      csr_dump, re.MULTILINE|re.DOTALL)
        if subject_alt_names is not None:
            for san in subject_alt_names.group(1).split(", "):
                if san.startswith("DNS:"):
                    domains.append({"type": "dns", "value": san[4:]})
        payload = {"identifiers": domains}
        return_codes = {201: "Success!"}
        error_message = "Error requesting order: {code} {result}"
        self.log.info("Sending newOrder request...")
        result, headers = self._send_signed_request("newOrder", payload,
                                                    return_codes, error_message)

        order_url = headers['Location']
        for auth_url in result['authorizations']:
            self._authz(auth_url)

        self.log.debug("Checking order to get finalize URL...")
        resp = urlopen(order_url)
        result = json.loads(resp.read().decode('utf8'))
        payload = {"csr": _b64(_openssl("req", ["-in", self.paths['csr'], "-outform", "DER"]))}
        return_codes = {200: "Success!"}
        error_message = "Error POSTing to finalize URL: {code} {result}"
        self.log.info("POSTing CSR to finalize URL...")
        self._send_signed_request(result['finalize'], payload, return_codes, error_message)
        result = self._urlopen_retry(order_url, 'processing', "Order isn't valid: {result}")
        self.log.debug("Downloading certificate: %s", result['certificate'])
        self.certificate = urlopen(result['certificate']).read().decode('utf8')
        self.log.info("Certificate signed!")

def main(argv):
    """Parse command line arguments and feed them to ACMETiny."""
    import argparse
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent("""\
            This script automates the process of getting a signed TLS certificate from
            Let's Encrypt using the ACME v2 protocol. It will need to be run on your
            server and have access to your private account key, so PLEASE READ THROUGH IT!
            It won't take long.

            ===Example Usage===
            python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ --output ./certificate.pem
            ===================

            ===Example Crontab Renewal (once per month)===
            0 0 1 * * python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ --output /path/to/certificate.pem 2>> /var/log/acme_tiny.log
            ==============================================
            """)
    )
    parser.add_argument("--account-key", required=True,
                        help="path to your Let's Encrypt account private key")
    parser.add_argument("--csr", required=True,
                        help="path to your certificate signing request")
    parser.add_argument("--acme-dir", required=True,
                        help="path to the .well-known/acme-challenge/ directory")
    parser.add_argument("--quiet", action="store_const", const=logging.ERROR,
                        help="suppress output except for errors")
    parser.add_argument("--ca", default=None,
                        help="certificate authority's directory object, default is Let's Encrypt")
    parser.add_argument("--output", "-o", metavar="FILE", default=None,
                        help="output file, default is standard output")

    args = parser.parse_args(argv)

    acme = ACMETiny(args.account_key, args.csr, args.acme_dir, ca=args.ca)
    acme.log.setLevel(args.quiet or acme.log.level)
    acme.get_certificate()
    with open(args.output, 'w') if args.output else sys.stdout as output:
        output.write(acme.certificate)

if __name__ == "__main__":  # pragma: no cover
    main(sys.argv[1:])
<|endoftext|>


<commit_before>from PythonQt import QtCore, QtGui, QtUiTools
import ddapp.applogic as app
import math
import numpy as np
from ddapp.timercallback import TimerCallback
from ddapp.simpletimer import SimpleTimer
from ddapp.debugVis import DebugData
import ddapp.visualization as vis
import ddapp.vtkAll as vtk
import scipy.interpolate

def addWidgetsToDict(widgets, d):

    for widget in widgets:
        if widget.objectName:
            d[str(widget.objectName)] = widget
        addWidgetsToDict(widget.children(), d)

class WidgetDict(object):

    def __init__(self, widgets):
        addWidgetsToDict(widgets, self.__dict__)

def clearLayout(w):
    children = w.findChildren(QtGui.QWidget)
    for child in children:
        child.delete()

class PlaybackPanel(object):

    def __init__(self, planPlayback, playbackRobotModel, playbackJointController, robotStateModel, robotStateJointController, manipPlanner):

        self.planPlayback = planPlayback
        self.playbackRobotModel = playbackRobotModel
        self.playbackJointController = playbackJointController
        self.robotStateModel = robotStateModel
        self.robotStateJointController = robotStateJointController
        self.manipPlanner = manipPlanner

        self.planFramesObj = None
        self.plan = None
        self.poseInterpolator = None
        self.startTime = 0.0
        self.endTime = 1.0
        self.animationTimer = TimerCallback()
        self.animationTimer.targetFps = 60
        self.animationTimer.callback = self.updateAnimation
        self.animationClock = SimpleTimer()

        loader = QtUiTools.QUiLoader()
        uifile = QtCore.QFile(':/ui/ddPlaybackPanel.ui')
        assert uifile.open(uifile.ReadOnly)

        self.widget = loader.load(uifile)
        uifile.close()

        self.ui = WidgetDict(self.widget.children())

        self.ui.viewModeCombo.connect('currentIndexChanged(const QString&)', self.viewModeChanged)
        self.ui.playbackSpeedCombo.connect('currentIndexChanged(const QString&)', self.playbackSpeedChanged)
        self.ui.interpolationCombo.connect('currentIndexChanged(const QString&)', self.interpolationChanged)

        self.ui.samplesSpinBox.connect('valueChanged(int)', self.numberOfSamplesChanged)
        self.ui.playbackSlider.connect('valueChanged(int)', self.playbackSliderValueChanged)

        self.ui.animateButton.connect('clicked()', self.animateClicked)
        self.ui.hideButton.connect('clicked()', self.hideClicked)
        self.ui.executeButton.connect('clicked()', self.executeClicked)
        self.ui.stopButton.connect('clicked()', self.stopClicked)

        self.ui.executeButton.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.executeButton.connect('customContextMenuRequested(const QPoint&)', self.showExecuteContextMenu)

        self.setPlan(None)
        self.hideClicked()

    def showExecuteContextMenu(self, clickPosition):

        globalPos = self.ui.executeButton.mapToGlobal(clickPosition)

        menu = QtGui.QMenu()
        menu.addAction('Visualization Only')

        selectedAction = menu.exec_(globalPos)
        if selectedAction is not None:
            self.executePlan(visOnly=True)

    def getViewMode(self):
      return str(self.ui.viewModeCombo.currentText)

    def getPlaybackSpeed(self):
      s = str(self.ui.playbackSpeedCombo.currentText).replace('x', '')
      if '/' in s:
          n, d = s.split('/')
          return float(n)/float(d)
      return float(s)

    def getInterpolationMethod(self):
        return str(self.ui.interpolationCombo.currentText)

    def getNumberOfSamples(self):
        return self.ui.samplesSpinBox.value

    def viewModeChanged(self):
        viewMode = self.getViewMode()
        if viewMode == 'continuous':
            playbackVisible = True
            samplesVisible = False
        else:
            playbackVisible = False
            samplesVisible = True

        self.ui.samplesLabel.setEnabled(samplesVisible)
        self.ui.samplesSpinBox.setEnabled(samplesVisible)

        self.ui.playbackSpeedLabel.setVisible(playbackVisible)
        self.ui.playbackSpeedCombo.setVisible(playbackVisible)
        self.ui.playbackSlider.setEnabled(playbackVisible)
        self.ui.animateButton.setVisible(playbackVisible)
        self.ui.timeLabel.setVisible(playbackVisible)

        if self.plan:

            if self.getViewMode() == 'continuous':
                self.startAnimation()
            else:
                self.ui.playbackSlider.value = 0
                self.stopAnimation()
                self.updatePlanFrames()

    def playbackSpeedChanged(self):
        print self.getPlaybackSpeed()
        self.planPlayback.playbackSpeed = self.getPlaybackSpeed()

    def getPlaybackTime(self):
        sliderValue = self.ui.playbackSlider.value
        return (sliderValue / 1000.0) * self.endTime

    def updateTimeLabel(self):
        playbackTime = self.getPlaybackTime()
        self.ui.timeLabel.text = 'Time: %.2f s' % playbackTime

    def playbackSliderValueChanged(self):
        self.updateTimeLabel()
        self.showPoseAtTime(self.getPlaybackTime())

    def interpolationChanged(self):

        methods = {'linear' : 'slinear',
                   'cubic spline' : 'cubic',
                   'pchip' : 'pchip' }
        self.planPlayback.interpolationMethod = methods[self.getInterpolationMethod()]
        self.poseInterpolator = self.planPlayback.getPoseInterpolatorFromPlan(self.plan)
        self.updatePlanFrames()

    def numberOfSamplesChanged(self):
        self.updatePlanFrames()

    def animateClicked(self):
        self.startAnimation()

    def hideClicked(self):

        if self.ui.hideButton.text == 'hide':
            self.ui.playbackFrame.setEnabled(False)
            self.hidePlan()
            self.ui.hideButton.text = 'show'
            self.ui.executeButton.setEnabled(False)

            if not self.plan:
                self.ui.hideButton.setEnabled(False)
        else:
            self.ui.playbackFrame.setEnabled(True)
            self.ui.hideButton.text = 'hide'
            self.ui.hideButton.setEnabled(True)
            self.ui.executeButton.setEnabled(True)

            self.viewModeChanged()

    def executeClicked(self):
        self.executePlan()

    def executePlan(self, visOnly=False):
        if visOnly:
            _, poses = self.planPlayback.getPlanPoses(self.plan)
            self.robotStateJointController.setPose('EST_ROBOT_STATE', poses[-1])
        else:
            self.manipPlanner.commitManipPlan(self.plan)

        self.setPlan(None)
        self.hideClicked()

    def stopClicked(self):
        self.stopAnimation()
        self.manipPlanner.sendPlanPause()

    def updatePlanFrames(self):

        if self.getViewMode() != 'frames':
            return

        numberOfSamples = self.getNumberOfSamples()

        meshes = self.planPlayback.getPlanPoseMeshes(self.plan, self.playbackJointController, self.playbackRobotModel, numberOfSamples)
        d = DebugData()

        startColor = [0.8, 0.8, 0.8]
        endColor = [85/255.0, 255/255.0, 255/255.0]
        colorFunc = scipy.interpolate.interp1d([0, numberOfSamples-1], [startColor, endColor], axis=0, kind='slinear')

        for i, mesh in reversed(list(enumerate(meshes))):
            d.addPolyData(mesh, color=colorFunc(i))

        pd = d.getPolyData()
        clean = vtk.vtkCleanPolyData()
        clean.SetInput(pd)
        clean.Update()
        pd = clean.GetOutput()

        self.planFramesObj = vis.updatePolyData(d.getPolyData(), 'robot plan', alpha=1.0, visible=False, colorByName='RGB255', parent='planning')
        self.showPlanFrames()

    def showPlanFrames(self):
        self.planFramesObj.setProperty('Visible', True)
        self.robotStateModel.setProperty('Visible', False)
        self.playbackRobotModel.setProperty('Visible', False)

    def startAnimation(self):
        self.showPlaybackModel()
        self.stopAnimation()
        self.ui.playbackSlider.value = 0
        self.animationClock.reset()
        self.animationTimer.start()
        self.updateAnimation()

    def stopAnimation(self):
        self.animationTimer.stop()

    def showPlaybackModel(self):
        self.robotStateModel.setProperty('Visible', True)
        self.robotStateModel.setProperty('Alpha', 0.1)
        self.playbackRobotModel.setProperty('Visible', True)
        if self.planFramesObj:
            self.planFramesObj.setProperty('Visible', False)

    def hidePlan(self):
        self.stopAnimation()
        if self.planFramesObj:
            self.planFramesObj.setProperty('Visible', False)
        if self.playbackRobotModel:
            self.playbackRobotModel.setProperty('Visible', False)

        self.robotStateModel.setProperty('Visible', True)
        self.robotStateModel.setProperty('Alpha', 1.0)

    def showPoseAtTime(self, time):
        pose = self.poseInterpolator(time)
        self.playbackJointController.setPose('plan_playback', pose)

    def updateAnimation(self):

        tNow = self.animationClock.elapsed() * self.planPlayback.playbackSpeed
        if tNow > self.endTime:
            tNow = self.endTime

        sliderValue = int(1000.0 * tNow / self.endTime)

        self.ui.playbackSlider.blockSignals(True)
        self.ui.playbackSlider.value = sliderValue
        self.ui.playbackSlider.blockSignals(False)
        self.updateTimeLabel()

        self.showPoseAtTime(tNow)
        return tNow < self.endTime

    def setPlan(self, plan):

        self.ui.playbackSlider.value = 0
        self.ui.timeLabel.text = 'Time: 0.00 s'
        self.ui.planNameLabel.text = ''
        self.plan = plan
        self.endTime = 1.0

        if not self.plan:
            return

        planText = 'Plan: %d.  %.2f seconds' % (plan.utime, self.planPlayback.getPlanElapsedTime(plan))
        self.ui.planNameLabel.text = planText

        self.startTime = 0.0
        self.endTime = self.planPlayback.getPlanElapsedTime(plan)
        self.interpolationChanged()

        if self.ui.hideButton.text == 'show':
            self.hideClicked()
        else:
            self.viewModeChanged()

        self.widget.parent().show()

def init(planPlayback, playbackRobotModel, playbackJointController, robotStateModel, robotStateJointController, manipPlanner):
    global panel
    panel = PlaybackPanel(planPlayback, playbackRobotModel, playbackJointController, robotStateModel, robotStateJointController, manipPlanner)

    #app.getMainWindow().viewManager().layout().addWidget(panel.widget)
    dock = app.addWidgetToDock(panel.widget, dockArea=QtCore.Qt.BottomDockWidgetArea)
    dock.hide()

    return panel
<commit_msg>add attribute to disable auto play in the plan playback panel<commit_after>from PythonQt import QtCore, QtGui, QtUiTools
import ddapp.applogic as app
import math
import numpy as np
from ddapp.timercallback import TimerCallback
from ddapp.simpletimer import SimpleTimer
from ddapp.debugVis import DebugData
import ddapp.visualization as vis
import ddapp.vtkAll as vtk
import scipy.interpolate

def addWidgetsToDict(widgets, d):

    for widget in widgets:
        if widget.objectName:
            d[str(widget.objectName)] = widget
        addWidgetsToDict(widget.children(), d)

class WidgetDict(object):

    def __init__(self, widgets):
        addWidgetsToDict(widgets, self.__dict__)

def clearLayout(w):
    children = w.findChildren(QtGui.QWidget)
    for child in children:
        child.delete()

class PlaybackPanel(object):

    def __init__(self, planPlayback, playbackRobotModel, playbackJointController, robotStateModel, robotStateJointController, manipPlanner):

        self.planPlayback = planPlayback
        self.playbackRobotModel = playbackRobotModel
        self.playbackJointController = playbackJointController
        self.robotStateModel = robotStateModel
        self.robotStateJointController = robotStateJointController
        self.manipPlanner = manipPlanner

        self.autoPlay = True

        self.planFramesObj = None
        self.plan = None
        self.poseInterpolator = None
        self.startTime = 0.0
        self.endTime = 1.0
        self.animationTimer = TimerCallback()
        self.animationTimer.targetFps = 60
        self.animationTimer.callback = self.updateAnimation
        self.animationClock = SimpleTimer()

        loader = QtUiTools.QUiLoader()
        uifile = QtCore.QFile(':/ui/ddPlaybackPanel.ui')
        assert uifile.open(uifile.ReadOnly)

        self.widget = loader.load(uifile)
        uifile.close()

        self.ui = WidgetDict(self.widget.children())

        self.ui.viewModeCombo.connect('currentIndexChanged(const QString&)', self.viewModeChanged)
        self.ui.playbackSpeedCombo.connect('currentIndexChanged(const QString&)', self.playbackSpeedChanged)
        self.ui.interpolationCombo.connect('currentIndexChanged(const QString&)', self.interpolationChanged)

        self.ui.samplesSpinBox.connect('valueChanged(int)', self.numberOfSamplesChanged)
        self.ui.playbackSlider.connect('valueChanged(int)', self.playbackSliderValueChanged)

        self.ui.animateButton.connect('clicked()', self.animateClicked)
        self.ui.hideButton.connect('clicked()', self.hideClicked)
        self.ui.executeButton.connect('clicked()', self.executeClicked)
        self.ui.stopButton.connect('clicked()', self.stopClicked)

        self.ui.executeButton.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.executeButton.connect('customContextMenuRequested(const QPoint&)', self.showExecuteContextMenu)

        self.setPlan(None)
        self.hideClicked()

    def showExecuteContextMenu(self, clickPosition):

        globalPos = self.ui.executeButton.mapToGlobal(clickPosition)

        menu = QtGui.QMenu()
        menu.addAction('Visualization Only')

        selectedAction = menu.exec_(globalPos)
        if selectedAction is not None:
            self.executePlan(visOnly=True)

    def getViewMode(self):
      return str(self.ui.viewModeCombo.currentText)

    def getPlaybackSpeed(self):
      s = str(self.ui.playbackSpeedCombo.currentText).replace('x', '')
      if '/' in s:
          n, d = s.split('/')
          return float(n)/float(d)
      return float(s)

    def getInterpolationMethod(self):
        return str(self.ui.interpolationCombo.currentText)

    def getNumberOfSamples(self):
        return self.ui.samplesSpinBox.value

    def viewModeChanged(self):
        viewMode = self.getViewMode()
        if viewMode == 'continuous':
            playbackVisible = True
            samplesVisible = False
        else:
            playbackVisible = False
            samplesVisible = True

        self.ui.samplesLabel.setEnabled(samplesVisible)
        self.ui.samplesSpinBox.setEnabled(samplesVisible)

        self.ui.playbackSpeedLabel.setVisible(playbackVisible)
        self.ui.playbackSpeedCombo.setVisible(playbackVisible)
        self.ui.playbackSlider.setEnabled(playbackVisible)
        self.ui.animateButton.setVisible(playbackVisible)
        self.ui.timeLabel.setVisible(playbackVisible)

        if self.plan:

            if self.getViewMode() == 'continuous' and self.autoPlay:
                self.startAnimation()
            else:
                self.ui.playbackSlider.value = 0
                self.stopAnimation()
                self.updatePlanFrames()

    def playbackSpeedChanged(self):
        print self.getPlaybackSpeed()
        self.planPlayback.playbackSpeed = self.getPlaybackSpeed()

    def getPlaybackTime(self):
        sliderValue = self.ui.playbackSlider.value
        return (sliderValue / 1000.0) * self.endTime

    def updateTimeLabel(self):
        playbackTime = self.getPlaybackTime()
        self.ui.timeLabel.text = 'Time: %.2f s' % playbackTime

    def playbackSliderValueChanged(self):
        self.updateTimeLabel()
        self.showPoseAtTime(self.getPlaybackTime())

    def interpolationChanged(self):

        methods = {'linear' : 'slinear',
                   'cubic spline' : 'cubic',
                   'pchip' : 'pchip' }
        self.planPlayback.interpolationMethod = methods[self.getInterpolationMethod()]
        self.poseInterpolator = self.planPlayback.getPoseInterpolatorFromPlan(self.plan)
        self.updatePlanFrames()

    def numberOfSamplesChanged(self):
        self.updatePlanFrames()

    def animateClicked(self):
        self.startAnimation()

    def hideClicked(self):

        if self.ui.hideButton.text == 'hide':
            self.ui.playbackFrame.setEnabled(False)
            self.hidePlan()
            self.ui.hideButton.text = 'show'
            self.ui.executeButton.setEnabled(False)

            if not self.plan:
                self.ui.hideButton.setEnabled(False)
        else:
            self.ui.playbackFrame.setEnabled(True)
            self.ui.hideButton.text = 'hide'
            self.ui.hideButton.setEnabled(True)
            self.ui.executeButton.setEnabled(True)

            self.viewModeChanged()

    def executeClicked(self):
        self.executePlan()

    def executePlan(self, visOnly=False):
        if visOnly:
            _, poses = self.planPlayback.getPlanPoses(self.plan)
            self.robotStateJointController.setPose('EST_ROBOT_STATE', poses[-1])
        else:
            self.manipPlanner.commitManipPlan(self.plan)

        self.setPlan(None)
        self.hideClicked()

    def stopClicked(self):
        self.stopAnimation()
        self.manipPlanner.sendPlanPause()

    def updatePlanFrames(self):

        if self.getViewMode() != 'frames':
            return

        numberOfSamples = self.getNumberOfSamples()

        meshes = self.planPlayback.getPlanPoseMeshes(self.plan, self.playbackJointController, self.playbackRobotModel, numberOfSamples)
        d = DebugData()

        startColor = [0.8, 0.8, 0.8]
        endColor = [85/255.0, 255/255.0, 255/255.0]
        colorFunc = scipy.interpolate.interp1d([0, numberOfSamples-1], [startColor, endColor], axis=0, kind='slinear')

        for i, mesh in reversed(list(enumerate(meshes))):
            d.addPolyData(mesh, color=colorFunc(i))

        pd = d.getPolyData()
        clean = vtk.vtkCleanPolyData()
        clean.SetInput(pd)
        clean.Update()
        pd = clean.GetOutput()

        self.planFramesObj = vis.updatePolyData(d.getPolyData(), 'robot plan', alpha=1.0, visible=False, colorByName='RGB255', parent='planning')
        self.showPlanFrames()

    def showPlanFrames(self):
        self.planFramesObj.setProperty('Visible', True)
        self.robotStateModel.setProperty('Visible', False)
        self.playbackRobotModel.setProperty('Visible', False)

    def startAnimation(self):
        self.showPlaybackModel()
        self.stopAnimation()
        self.ui.playbackSlider.value = 0
        self.animationClock.reset()
        self.animationTimer.start()
        self.updateAnimation()

    def stopAnimation(self):
        self.animationTimer.stop()

    def showPlaybackModel(self):
        self.robotStateModel.setProperty('Visible', True)
        self.robotStateModel.setProperty('Alpha', 0.1)
        self.playbackRobotModel.setProperty('Visible', True)
        if self.planFramesObj:
            self.planFramesObj.setProperty('Visible', False)

    def hidePlan(self):
        self.stopAnimation()
        if self.planFramesObj:
            self.planFramesObj.setProperty('Visible', False)
        if self.playbackRobotModel:
            self.playbackRobotModel.setProperty('Visible', False)

        self.robotStateModel.setProperty('Visible', True)
        self.robotStateModel.setProperty('Alpha', 1.0)

    def showPoseAtTime(self, time):
        pose = self.poseInterpolator(time)
        self.playbackJointController.setPose('plan_playback', pose)

    def updateAnimation(self):

        tNow = self.animationClock.elapsed() * self.planPlayback.playbackSpeed
        if tNow > self.endTime:
            tNow = self.endTime

        sliderValue = int(1000.0 * tNow / self.endTime)

        self.ui.playbackSlider.blockSignals(True)
        self.ui.playbackSlider.value = sliderValue
        self.ui.playbackSlider.blockSignals(False)
        self.updateTimeLabel()

        self.showPoseAtTime(tNow)
        return tNow < self.endTime

    def setPlan(self, plan):

        self.ui.playbackSlider.value = 0
        self.ui.timeLabel.text = 'Time: 0.00 s'
        self.ui.planNameLabel.text = ''
        self.plan = plan
        self.endTime = 1.0

        if not self.plan:
            return

        planText = 'Plan: %d.  %.2f seconds' % (plan.utime, self.planPlayback.getPlanElapsedTime(plan))
        self.ui.planNameLabel.text = planText

        self.startTime = 0.0
        self.endTime = self.planPlayback.getPlanElapsedTime(plan)
        self.interpolationChanged()

        if self.ui.hideButton.text == 'show':
            self.hideClicked()
        else:
            self.viewModeChanged()

        if self.autoPlay:
            self.widget.parent().show()

def init(planPlayback, playbackRobotModel, playbackJointController, robotStateModel, robotStateJointController, manipPlanner):
    global panel
    panel = PlaybackPanel(planPlayback, playbackRobotModel, playbackJointController, robotStateModel, robotStateJointController, manipPlanner)

    #app.getMainWindow().viewManager().layout().addWidget(panel.widget)
    dock = app.addWidgetToDock(panel.widget, dockArea=QtCore.Qt.BottomDockWidgetArea)
    dock.hide()

    return panel
<|endoftext|>


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

# Todo : keras model 에서 predict_probs() 할 때 message off 하는 방법

import cv2
import numpy as np

import digit_detector.region_proposal as rp
import digit_detector.detect as detector
import digit_detector.file_io as file_io
import digit_detector.preprocess as preproc
import digit_detector.annotation as ann

import digit_detector.evaluate as eval

model_filename = "detector_model.hdf5"
mean_value = 107.524
model_input_shape = (32,32,1)
DIR = '../datasets/svhn/train'
ANNOTATION_FILE = "../datasets/svhn/train/digitStruct.json"

if __name__ == "__main__":
    # 1. load test image files, annotation file
    img_files = file_io.list_files(directory=DIR, pattern="*.png", recursive_option=False, n_files_to_sample=1000, random_order=False)
    annotator = ann.SvhnAnnotation(ANNOTATION_FILE)
    classifier = detector.CnnClassifier(model_filename, model_input_shape)
    preprocessor = preproc.GrayImgPreprocessor(mean_value)
    proposer = rp.MserRegionProposer()

    # 2. create detector
    det = detector.Detector(classifier, proposer, preprocessor)

    # 3. Evaluate average precision
    evaluator = eval.Evaluator(det, annotator, rp.OverlapCalculator())
    recall, precision, f1_score = evaluator.run(img_files)
    # recall value : 0.487344684768, precision value : 0.656133828996, f1_score : 0.559281753367

    # 4. Evaluate MSER
    classifier = detector.TrueBinaryClassifier(input_shape=(32,32))
    preprocessor = preproc.NonePreprocessor()
    det = detector.Detector(classifier, proposer, preprocessor)
    evaluator = eval.Evaluator(det, annotator, rp.OverlapCalculator())
    recall, precision, f1_score = evaluator.run(img_files, do_nms=False)
    #recall value : 0.630004601933, precision value : 0.0452547023239, f1_score : 0.0844436220084

<commit_msg>nit : todo<commit_after>#-*- coding: utf-8 -*-

# Todo : keras model 에서 predict_probs() 할 때 message off 하는 방법
# evaluator.run(img_files, do_nms=False) 에서 do_nms option 을 사용하지 않도록 detector 자체의 class 에서 nms 객체를 갖고 있도록 하자.

import cv2
import numpy as np

import digit_detector.region_proposal as rp
import digit_detector.detect as detector
import digit_detector.file_io as file_io
import digit_detector.preprocess as preproc
import digit_detector.annotation as ann

import digit_detector.evaluate as eval

model_filename = "detector_model.hdf5"
mean_value = 107.524
model_input_shape = (32,32,1)
DIR = '../datasets/svhn/train'
ANNOTATION_FILE = "../datasets/svhn/train/digitStruct.json"

if __name__ == "__main__":
    # 1. load test image files, annotation file
    img_files = file_io.list_files(directory=DIR, pattern="*.png", recursive_option=False, n_files_to_sample=1000, random_order=False)
    annotator = ann.SvhnAnnotation(ANNOTATION_FILE)
    classifier = detector.CnnClassifier(model_filename, model_input_shape)
    preprocessor = preproc.GrayImgPreprocessor(mean_value)
    proposer = rp.MserRegionProposer()

    # 2. create detector
    det = detector.Detector(classifier, proposer, preprocessor)

    # 3. Evaluate average precision
    evaluator = eval.Evaluator(det, annotator, rp.OverlapCalculator())
    recall, precision, f1_score = evaluator.run(img_files)
    # recall value : 0.487344684768, precision value : 0.656133828996, f1_score : 0.559281753367

    # 4. Evaluate MSER
    classifier = detector.TrueBinaryClassifier(input_shape=(32,32))
    preprocessor = preproc.NonePreprocessor()
    det = detector.Detector(classifier, proposer, preprocessor)
    evaluator = eval.Evaluator(det, annotator, rp.OverlapCalculator())
    recall, precision, f1_score = evaluator.run(img_files, do_nms=False)
    #recall value : 0.630004601933, precision value : 0.0452547023239, f1_score : 0.0844436220084

<|endoftext|>