def addusersitepackages(known_paths):
    """Add a per user site-package to sys.path

    Each user has its own python directory with site-packages in the
    home directory.

    USER_BASE is the root directory for all Python versions

    USER_SITE is the user specific site-packages directory

    USER_SITE/.. can be used for data.
    """
    global USER_BASE, USER_SITE, ENABLE_USER_SITE
    env_base = os.environ.get("PYTHONUSERBASE", None)

    def joinuser(*args):
        return os.path.expanduser(os.path.join(*args))

    #if sys.platform in ('os2emx', 'riscos'):
    #    # Don't know what to put here
    #    USER_BASE = ''
    #    USER_SITE = ''
    if os.name == "nt":
        base = os.environ.get("APPDATA") or "~"
        if env_base:
            USER_BASE = env_base
        else:
            USER_BASE = joinuser(base, "Python")
        USER_SITE = os.path.join(USER_BASE,
                                 "Python" + sys.version[0] + sys.version[2],
                                 "site-packages")
    else:
        if env_base:
            USER_BASE = env_base
        else:
            USER_BASE = joinuser("~", ".local")
        USER_SITE = os.path.join(USER_BASE, "lib",
                                 "python" + sys.version[:3],
                                 "site-packages")

    if ENABLE_USER_SITE and os.path.isdir(USER_SITE):
        addsitedir(USER_SITE, known_paths)
    if ENABLE_USER_SITE:
        for dist_libdir in ("lib", "local/lib"):
            user_site = os.path.join(USER_BASE, dist_libdir,
                                     "python" + sys.version[:3],
                                     "dist-packages")
            if os.path.isdir(user_site):
                addsitedir(user_site, known_paths)
    return known_paths

def addusersitepackages ( known_paths ) : global USER_BASE , USER_SITE , ENABLE_USER_SITE env_base = os . environ . get ( "PYTHONUSERBASE" , None ) def joinuser ( * args ) : return os . path . expanduser ( os . path . join ( * args ) ) if os . name == "nt" : base = os . environ . get ( "APPDATA" ) or "~" if env_base : USER_BASE = env_base else : USER_BASE = joinuser ( base , "Python" ) USER_SITE = os . path . join ( USER_BASE , "Python" + sys . version [ 0 ] + sys . version [ 2 ] , "site-packages" ) else : if env_base : USER_BASE = env_base else : USER_BASE = joinuser ( "~" , ".local" ) USER_SITE = os . path . join ( USER_BASE , "lib" , "python" + sys . version [ : 3 ] , "site-packages" ) if ENABLE_USER_SITE and os . path . isdir ( USER_SITE ) : addsitedir ( USER_SITE , known_paths ) if ENABLE_USER_SITE : for dist_libdir in ( "lib" , "local/lib" ) : user_site = os . path . join ( USER_BASE , dist_libdir , "python" + sys . version [ : 3 ] , "dist-packages" ) if os . path . isdir ( user_site ) : addsitedir ( user_site , known_paths ) return known_paths

Add a per user site - package to sys . path


def setquit():
    """Define new built-ins 'quit' and 'exit'.
    These are simply strings that display a hint on how to exit.

    """
    if os.sep == ':':
        eof = 'Cmd-Q'
    elif os.sep == '\\':
        eof = 'Ctrl-Z plus Return'
    else:
        eof = 'Ctrl-D (i.e. EOF)'

    class Quitter(object):
        def __init__(self, name):
            self.name = name
        def __repr__(self):
            return 'Use %s() or %s to exit' % (self.name, eof)
        def __call__(self, code=None):
            # Shells like IDLE catch the SystemExit, but listen when their
            # stdin wrapper is closed.
            try:
                sys.stdin.close()
            except:
                pass
            raise SystemExit(code)
    builtins.quit = Quitter('quit')
    builtins.exit = Quitter('exit')

def
setquit
(
)
:
if
os
.
sep
==
':'
:
eof
=
'Cmd-Q'
elif
os
.
sep
==
'\\'
:
eof
=
'Ctrl-Z plus Return'
else
:
eof
=
'Ctrl-D (i.e. EOF)'
class
Quitter
(
object
)
:
def
__init__
(
self
,
name
)
:
self
.
name
=
name
def
__repr__
(
self
)
:
return
'Use %s() or %s to exit'
%
(
self
.
name
,
eof
)
def
__call__
(
self
,
code
=
)
:
try
:
sys
.
stdin
.
close
(
)
except
:
pass
raise
SystemExit
(
code
)
builtins
.
quit
=
Quitter
(
'quit'
)
builtins
.
exit
=
Quitter
(
'exit'
)

Define new built - ins quit and exit . These are simply strings that display a hint on how to exit .


def aliasmbcs():
    """On Windows, some default encodings are not provided by Python,
    while they are always available as "mbcs" in each locale. Make
    them usable by aliasing to "mbcs" in such a case."""
    if sys.platform == 'win32':
        import locale, codecs
        enc = locale.getdefaultlocale()[1]
        if enc.startswith('cp'):            # "cp***" ?
            try:
                codecs.lookup(enc)
            except LookupError:
                import encodings
                encodings._cache[enc] = encodings._unknown
                encodings.aliases.aliases[enc] = 'mbcs'

def aliasmbcs ( ) : if sys . platform == 'win32' : import locale , codecs enc = locale . getdefaultlocale ( ) [ 1 ] if enc . startswith ( 'cp' ) : try : codecs . lookup ( enc ) except LookupError : import encodings encodings . _cache [ enc ] = encodings . _unknown encodings . aliases . aliases [ enc ] = 'mbcs'

On Windows some default encodings are not provided by Python while they are always available as mbcs in each locale . Make them usable by aliasing to mbcs in such a case .


def setencoding():
    """Set the string encoding used by the Unicode implementation.  The
    default is 'ascii', but if you're willing to experiment, you can
    change this."""
    encoding = "ascii" # Default value set by _PyUnicode_Init()
    if 0:
        # Enable to support locale aware default string encodings.
        import locale
        loc = locale.getdefaultlocale()
        if loc[1]:
            encoding = loc[1]
    if 0:
        # Enable to switch off string to Unicode coercion and implicit
        # Unicode to string conversion.
        encoding = "undefined"
    if encoding != "ascii":
        # On Non-Unicode builds this will raise an AttributeError...
        sys.setdefaultencoding(encoding)

def setencoding ( ) : encoding = "ascii" if 0 : import locale loc = locale . getdefaultlocale ( ) if loc [ 1 ] : encoding = loc [ 1 ] if 0 : encoding = "undefined" if encoding != "ascii" : sys . setdefaultencoding ( encoding )

Set the string encoding used by the Unicode implementation . The default is ascii but if you re willing to experiment you can change this .


def force_global_eggs_after_local_site_packages():
    """
    Force easy_installed eggs in the global environment to get placed
    in sys.path after all packages inside the virtualenv.  This
    maintains the "least surprise" result that packages in the
    virtualenv always mask global packages, never the other way
    around.

    """
    egginsert = getattr(sys, '__egginsert', 0)
    for i, path in enumerate(sys.path):
        if i > egginsert and path.startswith(sys.prefix):
            egginsert = i
    sys.__egginsert = egginsert + 1

Force easy_installed eggs in the global environment to get placed in sys . path after all packages inside the virtualenv . This maintains the least surprise result that packages in the virtualenv always mask global packages never the other way around .


def fixclasspath():
    """Adjust the special classpath sys.path entries for Jython. These
    entries should follow the base virtualenv lib directories.
    """
    paths = []
    classpaths = []
    for path in sys.path:
        if path == '__classpath__' or path.startswith('__pyclasspath__'):
            classpaths.append(path)
        else:
            paths.append(path)
    sys.path = paths
    sys.path.extend(classpaths)

def fixclasspath ( ) : paths = [ ] classpaths = [ ] for path in sys . path : if path == '__classpath__' or path . startswith ( '__pyclasspath__' ) : classpaths . append ( path ) else : paths . append ( path ) sys . path = paths sys . path . extend ( classpaths )

Adjust the special classpath sys . path entries for Jython . These entries should follow the base virtualenv lib directories .


def Popen_nonblocking(*args, **kwargs):
	"""
	Open a subprocess without blocking. Return a process handle with any
	output streams replaced by queues of lines from that stream.

	Usage::

		proc = Popen_nonblocking(..., stdout=subprocess.PIPE)
		try:
			out_line = proc.stdout.get_nowait()
		except queue.Empty:
			"no output available"
		else:
			handle_output(out_line)
	"""
	kwargs.setdefault('close_fds', 'posix' in sys.builtin_module_names)
	kwargs.setdefault('bufsize', 1)
	proc = subprocess.Popen(*args, **kwargs)
	if proc.stdout:
		q = queue.Queue()
		t = threading.Thread(
			target=enqueue_lines,
			args=(proc.stdout, q))
		proc.stdout = q
		# thread dies with the parent
		t.daemon = True
		t.start()
	if proc.stderr:
		q = queue.Queue()
		t = threading.Thread(
			target=enqueue_lines,
			args=(proc.stderr, q))
		proc.stderr = q
		t.daemon = True
		t.start()
	return proc

def Popen_nonblocking ( * args , ** kwargs ) : kwargs . setdefault ( 'close_fds' , 'posix' in sys . builtin_module_names ) kwargs . setdefault ( 'bufsize' , 1 ) proc = subprocess . Popen ( * args , ** kwargs ) if proc . stdout : q = queue . Queue ( ) t = threading . Thread ( target = enqueue_lines , args = ( proc . stdout , q ) ) proc . stdout = q t . daemon = True t . start ( ) if proc . stderr : q = queue . Queue ( ) t = threading . Thread ( target = enqueue_lines , args = ( proc . stderr , q ) ) proc . stderr = q t . daemon = True t . start ( ) return proc

Open a subprocess without blocking . Return a process handle with any output streams replaced by queues of lines from that stream .


def have_pyrex():
    """
    Return True if Cython or Pyrex can be imported.
    """
    pyrex_impls = 'Cython.Distutils.build_ext', 'Pyrex.Distutils.build_ext'
    for pyrex_impl in pyrex_impls:
        try:
            # from (pyrex_impl) import build_ext
            __import__(pyrex_impl, fromlist=['build_ext']).build_ext
            return True
        except Exception:
            pass
    return False

def have_pyrex ( ) : pyrex_impls = 'Cython.Distutils.build_ext' , 'Pyrex.Distutils.build_ext' for pyrex_impl in pyrex_impls : try : __import__ ( pyrex_impl , fromlist = [ 'build_ext' ] ) . build_ext return True except Exception : pass return False

Return True if Cython or Pyrex can be imported .


def _convert_pyx_sources_to_lang(self):
        """
        Replace sources with .pyx extensions to sources with the target
        language extension. This mechanism allows language authors to supply
        pre-converted sources but to prefer the .pyx sources.
        """
        if have_pyrex():
            # the build has Cython, so allow it to compile the .pyx files
            return
        lang = self.language or ''
        target_ext = '.cpp' if lang.lower() == 'c++' else '.c'
        sub = functools.partial(re.sub, '.pyx$', target_ext)
        self.sources = list(map(sub, self.sources))

def _convert_pyx_sources_to_lang ( self ) : if have_pyrex ( ) : return lang = self . language or '' target_ext = '.cpp' if lang . lower ( ) == 'c++' else '.c' sub = functools . partial ( re . sub , '.pyx$' , target_ext ) self . sources = list ( map ( sub , self . sources ) )

Replace sources with . pyx extensions to sources with the target language extension . This mechanism allows language authors to supply pre - converted sources but to prefer the . pyx sources .


def debug_application(self, environ, start_response):
        """Run the application and conserve the traceback frames."""
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item
            if hasattr(app_iter, 'close'):
                app_iter.close()
        except Exception:
            if hasattr(app_iter, 'close'):
                app_iter.close()
            traceback = get_current_traceback(skip=1, show_hidden_frames=
                                              self.show_hidden_frames,
                                              ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            try:
                start_response('500 INTERNAL SERVER ERROR', [
                    ('Content-Type', 'text/html; charset=utf-8'),
                    # Disable Chrome's XSS protection, the debug
                    # output can cause false-positives.
                    ('X-XSS-Protection', '0'),
                ])
            except Exception:
                # if we end up here there has been output but an error
                # occurred.  in that situation we can do nothing fancy any
                # more, better log something into the error log and fall
                # back gracefully.
                environ['wsgi.errors'].write(
                    'Debugging middleware caught exception in streamed '
                    'response at a point where response headers were already '
                    'sent.\n')
            else:
                yield traceback.render_full(evalex=self.evalex,
                                            secret=self.secret) \
                               .encode('utf-8', 'replace')

            traceback.log(environ['wsgi.errors'])

Run the application and conserve the traceback frames .


def get_resource(self, request, filename):
        """Return a static resource from the shared folder."""
        filename = join(dirname(__file__), 'shared', basename(filename))
        if isfile(filename):
            mimetype = mimetypes.guess_type(filename)[0] \
                or 'application/octet-stream'
            f = open(filename, 'rb')
            try:
                return Response(f.read(), mimetype=mimetype)
            finally:
                f.close()
        return Response('Not Found', status=404)

def
get_resource
(
self
,
request
,
filename
)
:
filename
=
join
(
dirname
(
__file__
)
,
'shared'
,
basename
(
filename
)
)
if
isfile
(
filename
)
:
mimetype
=
mimetypes
.
guess_type
(
filename
)
[
0
]
or
'application/octet-stream'
f
=
open
(
filename
,
'rb'
)
try
:
return
Response
(
f
.
read
(
)
,
mimetype
=
mimetype
)
finally
:
f
.
close
(
)
return
Response
(
'Not Found'
,
status
=
404
)

Return a static resource from the shared folder .


def user_agent():
    """
    Return a string representing the user agent.
    """
    data = {
        "installer": {"name": "pip", "version": pip.__version__},
        "python": platform.python_version(),
        "implementation": {
            "name": platform.python_implementation(),
        },
    }

    if data["implementation"]["name"] == 'CPython':
        data["implementation"]["version"] = platform.python_version()
    elif data["implementation"]["name"] == 'PyPy':
        if sys.pypy_version_info.releaselevel == 'final':
            pypy_version_info = sys.pypy_version_info[:3]
        else:
            pypy_version_info = sys.pypy_version_info
        data["implementation"]["version"] = ".".join(
            [str(x) for x in pypy_version_info]
        )
    elif data["implementation"]["name"] == 'Jython':
        # Complete Guess
        data["implementation"]["version"] = platform.python_version()
    elif data["implementation"]["name"] == 'IronPython':
        # Complete Guess
        data["implementation"]["version"] = platform.python_version()

    if sys.platform.startswith("linux"):
        distro = dict(filter(
            lambda x: x[1],
            zip(["name", "version", "id"], platform.linux_distribution()),
        ))
        libc = dict(filter(
            lambda x: x[1],
            zip(["lib", "version"], platform.libc_ver()),
        ))
        if libc:
            distro["libc"] = libc
        if distro:
            data["distro"] = distro

    if sys.platform.startswith("darwin") and platform.mac_ver()[0]:
        data["distro"] = {"name": "OS X", "version": platform.mac_ver()[0]}

    if platform.system():
        data.setdefault("system", {})["name"] = platform.system()

    if platform.release():
        data.setdefault("system", {})["release"] = platform.release()

    if platform.machine():
        data["cpu"] = platform.machine()

    return "{data[installer][name]}/{data[installer][version]} {json}".format(
        data=data,
        json=json.dumps(data, separators=(",", ":"), sort_keys=True),
    )

Return a string representing the user agent .


def is_url(name):
    """Returns true if the name looks like a URL"""
    if ':' not in name:
        return False
    scheme = name.split(':', 1)[0].lower()
    return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes

def is_url ( name ) : if ':' not in name : return False scheme = name . split ( ':' , 1 ) [ 0 ] . lower ( ) return scheme in [ 'http' , 'https' , 'file' , 'ftp' ] + vcs . all_schemes


def unpack_file_url(link, location, download_dir=None):
    """Unpack link into location.
    If download_dir is provided and link points to a file, make a copy
    of the link file inside download_dir."""

    link_path = url_to_path(link.url_without_fragment)

    # If it's a url to a local directory
    if os.path.isdir(link_path):
        if os.path.isdir(location):
            rmtree(location)
        shutil.copytree(link_path, location, symlinks=True)
        if download_dir:
            logger.info('Link is a directory, ignoring download_dir')
        return

    # if link has a hash, let's confirm it matches
    if link.hash:
        link_path_hash = _get_hash_from_file(link_path, link)
        _check_hash(link_path_hash, link)

    # If a download dir is specified, is the file already there and valid?
    already_downloaded_path = None
    if download_dir:
        already_downloaded_path = _check_download_dir(link, download_dir)

    if already_downloaded_path:
        from_path = already_downloaded_path
    else:
        from_path = link_path

    content_type = mimetypes.guess_type(from_path)[0]

    # unpack the archive to the build dir location. even when only downloading
    # archives, they have to be unpacked to parse dependencies
    unpack_file(from_path, location, content_type, link)

    # a download dir is specified and not already downloaded
    if download_dir and not already_downloaded_path:
        _copy_file(from_path, download_dir, content_type, link)

Unpack link into location . If download_dir is provided and link points to a file make a copy of the link file inside download_dir .


def _download_http_url(link, session, temp_dir):
    """Download link url into temp_dir using provided session"""
    target_url = link.url.split('#', 1)[0]
    try:
        resp = session.get(
            target_url,
            # We use Accept-Encoding: identity here because requests
            # defaults to accepting compressed responses. This breaks in
            # a variety of ways depending on how the server is configured.
            # - Some servers will notice that the file isn't a compressible
            #   file and will leave the file alone and with an empty
            #   Content-Encoding
            # - Some servers will notice that the file is already
            #   compressed and will leave the file alone and will add a
            #   Content-Encoding: gzip header
            # - Some servers won't notice anything at all and will take
            #   a file that's already been compressed and compress it again
            #   and set the Content-Encoding: gzip header
            # By setting this to request only the identity encoding We're
            # hoping to eliminate the third case. Hopefully there does not
            # exist a server which when given a file will notice it is
            # already compressed and that you're not asking for a
            # compressed file and will then decompress it before sending
            # because if that's the case I don't think it'll ever be
            # possible to make this work.
            headers={"Accept-Encoding": "identity"},
            stream=True,
        )
        resp.raise_for_status()
    except requests.HTTPError as exc:
        logger.critical(
            "HTTP error %s while getting %s", exc.response.status_code, link,
        )
        raise

    content_type = resp.headers.get('content-type', '')
    filename = link.filename  # fallback
    # Have a look at the Content-Disposition header for a better guess
    content_disposition = resp.headers.get('content-disposition')
    if content_disposition:
        type, params = cgi.parse_header(content_disposition)
        # We use ``or`` here because we don't want to use an "empty" value
        # from the filename param.
        filename = params.get('filename') or filename
    ext = splitext(filename)[1]
    if not ext:
        ext = mimetypes.guess_extension(content_type)
        if ext:
            filename += ext
    if not ext and link.url != resp.url:
        ext = os.path.splitext(resp.url)[1]
        if ext:
            filename += ext
    file_path = os.path.join(temp_dir, filename)
    with open(file_path, 'wb') as content_file:
        _download_url(resp, link, content_file)
    return file_path, content_type

def
_download_http_url
(
link
,
session
,
temp_dir
)
:
target_url
=
link
.
url
.
split
(
'#'
,
1
)
[
0
]
try
:
resp
=
session
.
get
(
target_url
,
headers
=
{
"Accept-Encoding"
:
"identity"
}
,
stream
=
True
,
)
resp
.
raise_for_status
(
)
except
requests
.
HTTPError
as
exc
:
logger
.
critical
(
"HTTP error %s while getting %s"
,
exc
.
response
.
status_code
,
link
,
)
raise
content_type
=
resp
.
headers
.
get
(
'content-type'
,
''
)
filename
=
link
.
filename
content_disposition
=
resp
.
headers
.
get
(
'content-disposition'
)
if
content_disposition
:
type
,
params
=
cgi
.
parse_header
(
content_disposition
)
filename
=
params
.
get
(
'filename'
)
or
filename
ext
=
splitext
(
filename
)
[
1
]
if
not
ext
:
ext
=
mimetypes
.
guess_extension
(
content_type
)
if
ext
:
filename
+=
ext
if
not
ext
and
link
.
url
!=
resp
.
url
:
ext
=
os
.
path
.
splitext
(
resp
.
url
)
[
1
]
if
ext
:
filename
+=
ext
file_path
=
os
.
path
.
join
(
temp_dir
,
filename
)
with
open
(
file_path
,
'wb'
)
as
content_file
:
_download_url
(
resp
,
link
,
content_file
)
return
file_path
,
content_type


def _check_download_dir(link, download_dir):
    """ Check download_dir for previously downloaded file with correct hash
        If a correct file is found return its path else None
    """
    download_path = os.path.join(download_dir, link.filename)
    if os.path.exists(download_path):
        # If already downloaded, does its hash match?
        logger.info('File was already downloaded %s', download_path)
        if link.hash:
            download_hash = _get_hash_from_file(download_path, link)
            try:
                _check_hash(download_hash, link)
            except HashMismatch:
                logger.warning(
                    'Previously-downloaded file %s has bad hash, '
                    're-downloading.',
                    download_path
                )
                os.unlink(download_path)
                return None
        return download_path
    return None


def currencyFormat(_context, code, symbol, format,
                       currency_digits=True, decimal_quantization=True,
                       name=''):
        """Handle currencyFormat subdirectives."""
        _context.action(
            discriminator=('currency', name, code),
            callable=_register_currency,
            args=(name, code, symbol, format, currency_digits,
                  decimal_quantization)
            )

def currencyFormat ( _context , code , symbol , format , currency_digits = True , decimal_quantization = True , name = '' ) : _context . action ( discriminator = ( 'currency' , name , code ) , callable = _register_currency , args = ( name , code , symbol , format , currency_digits , decimal_quantization ) )


def exchange(_context, component, backend, base, name=''):
        """Handle exchange subdirectives."""
        _context.action(
            discriminator=('currency', 'exchange', component),
            callable=_register_exchange,
            args=(name, component, backend, base)
        )

def exchange ( _context , component , backend , base , name = '' ) : _context . action ( discriminator = ( 'currency' , 'exchange' , component ) , callable = _register_exchange , args = ( name , component , backend , base ) )


def _decode(self, data, decode_content, flush_decoder):
        """
        Decode the data passed in and potentially flush the decoder.
        """
        try:
            if decode_content and self._decoder:
                data = self._decoder.decompress(data)
        except (IOError, zlib.error) as e:
            content_encoding = self.headers.get('content-encoding', '').lower()
            raise DecodeError(
                "Received response with content-encoding: %s, but "
                "failed to decode it." % content_encoding, e)

        if flush_decoder and decode_content and self._decoder:
            buf = self._decoder.decompress(binary_type())
            data += buf + self._decoder.flush()

        return data

Decode the data passed in and potentially flush the decoder .


def _default_template_ctx_processor():
    """Default template context processor.  Injects `request`,
    `session` and `g`.
    """
    reqctx = _request_ctx_stack.top
    appctx = _app_ctx_stack.top
    rv = {}
    if appctx is not None:
        rv['g'] = appctx.g
    if reqctx is not None:
        rv['request'] = reqctx.request
        rv['session'] = reqctx.session
    return rv

def _default_template_ctx_processor ( ) : reqctx = _request_ctx_stack . top appctx = _app_ctx_stack . top rv = { } if appctx is not None : rv [ 'g' ] = appctx . g if reqctx is not None : rv [ 'request' ] = reqctx . request rv [ 'session' ] = reqctx . session return rv

Default template context processor . Injects request session and g .


def _render(template, context, app):
    """Renders the template and fires the signal"""
    rv = template.render(context)
    template_rendered.send(app, template=template, context=context)
    return rv

def _render ( template , context , app ) : rv = template . render ( context ) template_rendered . send ( app , template = template , context = context ) return rv


def render_template(template_name_or_list, **context):
    """Renders a template from the template folder with the given
    context.

    :param template_name_or_list: the name of the template to be
                                  rendered, or an iterable with template names
                                  the first one existing will be rendered
    :param context: the variables that should be available in the
                    context of the template.
    """
    ctx = _app_ctx_stack.top
    ctx.app.update_template_context(context)
    return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
                   context, ctx.app)

def render_template ( template_name_or_list , ** context ) : ctx = _app_ctx_stack . top ctx . app . update_template_context ( context ) return _render ( ctx . app . jinja_env . get_or_select_template ( template_name_or_list ) , context , ctx . app )

Renders a template from the template folder with the given context .


def render_template_string(source, **context):
    """Renders a template from the given template source string
    with the given context.

    :param source: the sourcecode of the template to be
                   rendered
    :param context: the variables that should be available in the
                    context of the template.
    """
    ctx = _app_ctx_stack.top
    ctx.app.update_template_context(context)
    return _render(ctx.app.jinja_env.from_string(source),
                   context, ctx.app)

def render_template_string ( source , ** context ) : ctx = _app_ctx_stack . top ctx . app . update_template_context ( context ) return _render ( ctx . app . jinja_env . from_string ( source ) , context , ctx . app )

Renders a template from the given template source string with the given context .


def parse_version(version):
    """Use parse_version from pkg_resources or distutils as available."""
    global parse_version
    try:
        from pkg_resources import parse_version
    except ImportError:
        from distutils.version import LooseVersion as parse_version
    return parse_version(version)

def parse_version ( version ) : global parse_version try : from pkg_resources import parse_version except ImportError : from distutils . version import LooseVersion as parse_version return parse_version ( version )

Use parse_version from pkg_resources or distutils as available .


def is_declared(self, name):
        """Check if a name is declared in this or an outer scope."""
        if name in self.declared_locally or name in self.declared_parameter:
            return True
        return name in self.declared

def is_declared ( self , name ) : if name in self . declared_locally or name in self . declared_parameter : return True return name in self . declared

Check if a name is declared in this or an outer scope .


def visit_Name(self, node):
        """All assignments to names go through this function."""
        if node.ctx == 'store':
            self.identifiers.declared_locally.add(node.name)
        elif node.ctx == 'param':
            self.identifiers.declared_parameter.add(node.name)
        elif node.ctx == 'load' and not \
             self.identifiers.is_declared(node.name):
            self.identifiers.undeclared.add(node.name)

def visit_Name ( self , node ) : if node . ctx == 'store' : self . identifiers . declared_locally . add ( node . name ) elif node . ctx == 'param' : self . identifiers . declared_parameter . add ( node . name ) elif node . ctx == 'load' and not self . identifiers . is_declared ( node . name ) : self . identifiers . undeclared . add ( node . name )

All assignments to names go through this function .


def visit_Include(self, node, frame):
        """Handles includes."""
        if node.with_context:
            self.unoptimize_scope(frame)
        if node.ignore_missing:
            self.writeline('try:')
            self.indent()

        func_name = 'get_or_select_template'
        if isinstance(node.template, nodes.Const):
            if isinstance(node.template.value, string_types):
                func_name = 'get_template'
            elif isinstance(node.template.value, (tuple, list)):
                func_name = 'select_template'
        elif isinstance(node.template, (nodes.Tuple, nodes.List)):
            func_name = 'select_template'

        self.writeline('template = environment.%s(' % func_name, node)
        self.visit(node.template, frame)
        self.write(', %r)' % self.name)
        if node.ignore_missing:
            self.outdent()
            self.writeline('except TemplateNotFound:')
            self.indent()
            self.writeline('pass')
            self.outdent()
            self.writeline('else:')
            self.indent()

        if node.with_context:
            self.writeline('for event in template.root_render_func('
                           'template.new_context(context.parent, True, '
                           'locals())):')
        else:
            self.writeline('for event in template.module._body_stream:')

        self.indent()
        self.simple_write('event', frame)
        self.outdent()

        if node.ignore_missing:
            self.outdent()


def visit_FromImport(self, node, frame):
        """Visit named imports."""
        self.newline(node)
        self.write('included_template = environment.get_template(')
        self.visit(node.template, frame)
        self.write(', %r).' % self.name)
        if node.with_context:
            self.write('make_module(context.parent, True)')
        else:
            self.write('module')

        var_names = []
        discarded_names = []
        for name in node.names:
            if isinstance(name, tuple):
                name, alias = name
            else:
                alias = name
            self.writeline('l_%s = getattr(included_template, '
                           '%r, missing)' % (alias, name))
            self.writeline('if l_%s is missing:' % alias)
            self.indent()
            self.writeline('l_%s = environment.undefined(%r %% '
                           'included_template.__name__, '
                           'name=%r)' %
                           (alias, 'the template %%r (imported on %s) does '
                           'not export the requested name %s' % (
                                self.position(node),
                                repr(name)
                           ), name))
            self.outdent()
            if frame.toplevel:
                var_names.append(alias)
                if not alias.startswith('_'):
                    discarded_names.append(alias)
            frame.assigned_names.add(alias)

        if var_names:
            if len(var_names) == 1:
                name = var_names[0]
                self.writeline('context.vars[%r] = l_%s' % (name, name))
            else:
                self.writeline('context.vars.update({%s})' % ', '.join(
                    '%r: l_%s' % (name, name) for name in var_names
                ))
        if discarded_names:
            if len(discarded_names) == 1:
                self.writeline('context.exported_vars.discard(%r)' %
                               discarded_names[0])
            else:
                self.writeline('context.exported_vars.difference_'
                               'update((%s))' % ', '.join(imap(repr, discarded_names)))


def make_wheelfile_inner(base_name, base_dir='.'):
    """Create a whl file from all the files under 'base_dir'.

    Places .dist-info at the end of the archive."""

    zip_filename = base_name + ".whl"

    log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir)

    # XXX support bz2, xz when available
    zip = zipfile.ZipFile(open(zip_filename, "wb+"), "w",
                          compression=zipfile.ZIP_DEFLATED)

    score = {'WHEEL': 1, 'METADATA': 2, 'RECORD': 3}
    deferred = []

    def writefile(path):
        zip.write(path, path)
        log.info("adding '%s'" % path)

    for dirpath, dirnames, filenames in os.walk(base_dir):
        for name in filenames:
            path = os.path.normpath(os.path.join(dirpath, name))

            if os.path.isfile(path):
                if dirpath.endswith('.dist-info'):
                    deferred.append((score.get(name, 0), path))
                else:
                    writefile(path)

    deferred.sort()
    for score, path in deferred:
        writefile(path)

    zip.close()

    return zip_filename

def
make_wheelfile_inner
(
base_name
,
base_dir
=
'.'
)
:
zip_filename
=
base_name
+
".whl"
log
.
info
(
"creating '%s' and adding '%s' to it"
,
zip_filename
,
base_dir
)
zip
=
zipfile
.
ZipFile
(
open
(
zip_filename
,
"wb+"
)
,
"w"
,
compression
=
zipfile
.
ZIP_DEFLATED
)
score
=
{
'WHEEL'
:
1
,
'METADATA'
:
2
,
'RECORD'
:
3
}
deferred
=
[
]
def
writefile
(
path
)
:
zip
.
write
(
path
,
path
)
log
.
info
(
"adding '%s'"
%
path
)
for
dirpath
,
dirnames
,
filenames
in
os
.
walk
(
base_dir
)
:
for
name
in
filenames
:
path
=
os
.
path
.
normpath
(
os
.
path
.
join
(
dirpath
,
name
)
)
if
os
.
path
.
isfile
(
path
)
:
if
dirpath
.
endswith
(
'.dist-info'
)
:
deferred
.
append
(
(
score
.
get
(
name
,
0
)
,
path
)
)
else
:
writefile
(
path
)
deferred
.
sort
(
)
for
score
,
path
in
deferred
:
writefile
(
path
)
zip
.
close
(
)
return
zip_filename

Create a whl file from all the files under base_dir .


def atomize(f, lock=None):
	"""
	Decorate a function with a reentrant lock to prevent multiple
	threads from calling said thread simultaneously.
	"""
	lock = lock or threading.RLock()

	@functools.wraps(f)
	def exec_atomic(*args, **kwargs):
		lock.acquire()
		try:
			return f(*args, **kwargs)
		finally:
			lock.release()
	return exec_atomic

def atomize ( f , lock = None ) : lock = lock or threading . RLock ( ) @ functools . wraps ( f ) def exec_atomic ( * args , ** kwargs ) : lock . acquire ( ) try : return f ( * args , ** kwargs ) finally : lock . release ( ) return exec_atomic

Decorate a function with a reentrant lock to prevent multiple threads from calling said thread simultaneously .


def service_factory(app, host, port,
                    report_message='service factory port {port}',
                    provider_cls=HTTPServiceProvider):
    """Create service, start server.

    :param app: application to instantiate a service
    :param host: interface to bound provider
    :param port: port to bound provider
    :param report_message: message format to report port
    :param provider_cls: server class provide a service

    """

    service = Service(app)
    server = provider_cls(service, host, port, report_message)
    server.serve_forever()

def
service_factory
(
app
,
host
,
port
,
report_message
=
'service factory port {port}'
,
provider_cls
=
HTTPServiceProvider
)
:
service
=
Service
(
app
)
server
=
provider_cls
(
service
,
host
,
port
,
report_message
)
server
.
serve_forever
(
)


def unicode_urlencode(obj, charset='utf-8'):
    """URL escapes a single bytestring or unicode string with the
    given charset if applicable to URL safe quoting under all rules
    that need to be considered under all supported Python versions.

    If non strings are provided they are converted to their unicode
    representation first.
    """
    if not isinstance(obj, string_types):
        obj = text_type(obj)
    if isinstance(obj, text_type):
        obj = obj.encode(charset)
    return text_type(url_quote(obj))

def unicode_urlencode ( obj , charset = 'utf-8' ) : if not isinstance ( obj , string_types ) : obj = text_type ( obj ) if isinstance ( obj , text_type ) : obj = obj . encode ( charset ) return text_type ( url_quote ( obj ) )

URL escapes a single bytestring or unicode string with the given charset if applicable to URL safe quoting under all rules that need to be considered under all supported Python versions .


def matches_requirement(req, wheels):
    """List of wheels matching a requirement.

    :param req: The requirement to satisfy
    :param wheels: List of wheels to search.
    """
    try:
        from pkg_resources import Distribution, Requirement
    except ImportError:
        raise RuntimeError("Cannot use requirements without pkg_resources")

    req = Requirement.parse(req)

    selected = []
    for wf in wheels:
        f = wf.parsed_filename
        dist = Distribution(project_name=f.group("name"), version=f.group("ver"))
        if dist in req:
            selected.append(wf)
    return selected


def populate_requirement_set(requirement_set, args, options, finder,
                                 session, name, wheel_cache):
        """
        Marshal cmd line args into a requirement set.
        """
        for req in args:
            requirement_set.add_requirement(
                InstallRequirement.from_line(
                    req, None, isolated=options.isolated_mode,
                    wheel_cache=wheel_cache
                )
            )

        for req in options.editables:
            requirement_set.add_requirement(
                InstallRequirement.from_editable(
                    req,
                    default_vcs=options.default_vcs,
                    isolated=options.isolated_mode,
                    wheel_cache=wheel_cache
                )
            )

        found_req_in_file = False
        for filename in options.requirements:
            for req in parse_requirements(
                    filename,
                    finder=finder, options=options, session=session,
                    wheel_cache=wheel_cache):
                found_req_in_file = True
                requirement_set.add_requirement(req)

        if not (args or options.editables or found_req_in_file):
            opts = {'name': name}
            if options.find_links:
                msg = ('You must give at least one requirement to '
                       '%(name)s (maybe you meant "pip %(name)s '
                       '%(links)s"?)' %
                       dict(opts, links=' '.join(options.find_links)))
            else:
                msg = ('You must give at least one requirement '
                       'to %(name)s (see "pip help %(name)s")' % opts)
            logger.warning(msg)

Marshal cmd line args into a requirement set .


def export(self, location):
        """
        Export the Bazaar repository at the url to the destination location
        """
        temp_dir = tempfile.mkdtemp('-export', 'pip-')
        self.unpack(temp_dir)
        if os.path.exists(location):
            # Remove the location to make sure Bazaar can export it correctly
            rmtree(location)
        try:
            self.run_command(['export', location], cwd=temp_dir,
                             show_stdout=False)
        finally:
            rmtree(temp_dir)

def export ( self , location ) : temp_dir = tempfile . mkdtemp ( '-export' , 'pip-' ) self . unpack ( temp_dir ) if os . path . exists ( location ) : rmtree ( location ) try : self . run_command ( [ 'export' , location ] , cwd = temp_dir , show_stdout = False ) finally : rmtree ( temp_dir )


def lookup(self, ResponseGroup="Large", **kwargs):
        """Lookup an Amazon Product.

        :return:
            An instance of :class:`~.AmazonProduct` if one item was returned,
            or a list of  :class:`~.AmazonProduct` instances if multiple
            items where returned.
        """
        response = self.api.ItemLookup(ResponseGroup=ResponseGroup, **kwargs)
        root = objectify.fromstring(response)
        if root.Items.Request.IsValid == 'False':
            code = root.Items.Request.Errors.Error.Code
            msg = root.Items.Request.Errors.Error.Message
            raise LookupException(
                "Amazon Product Lookup Error: '{0}', '{1}'".format(code, msg))
        if not hasattr(root.Items, 'Item'):
            raise AsinNotFound("ASIN(s) not found: '{0}'".format(
                etree.tostring(root, pretty_print=True)))
        if len(root.Items.Item) > 1:
            return [
                AmazonProduct(
                    item,
                    self.aws_associate_tag,
                    self,
                    region=self.region) for item in root.Items.Item
            ]
        else:
            return AmazonProduct(
                root.Items.Item,
                self.aws_associate_tag,
                self,
                region=self.region
            )


def iterate_pages(self):
        """Iterate Pages.

        A generator which iterates over all pages.
        Keep in mind that Amazon limits the number of pages it makes available.

        :return:
            Yields lxml root elements.
        """
        try:
            while True:
                yield self._query(ItemPage=self.current_page, **self.kwargs)
                self.current_page += 1
        except NoMorePages:
            pass

def iterate_pages ( self ) : try : while True : yield self . _query ( ItemPage = self . current_page , ** self . kwargs ) self . current_page += 1 except NoMorePages : pass


def ancestor(self):
        """This browse node's immediate ancestor in the browse node tree.

        :return:
            The ancestor as an :class:`~.AmazonBrowseNode`, or None.
        """
        ancestors = getattr(self.element, 'Ancestors', None)
        if hasattr(ancestors, 'BrowseNode'):
            return AmazonBrowseNode(ancestors['BrowseNode'])
        return None

def ancestor ( self ) : ancestors = getattr ( self . element , 'Ancestors' , None ) if hasattr ( ancestors , 'BrowseNode' ) : return AmazonBrowseNode ( ancestors [ 'BrowseNode' ] ) return None

This browse node s immediate ancestor in the browse node tree .


def children(self):
        """This browse node's children in the browse node tree.

    :return:
    A list of this browse node's children in the browse node tree.
    """
        children = []
        child_nodes = getattr(self.element, 'Children')
        for child in getattr(child_nodes, 'BrowseNode', []):
                children.append(AmazonBrowseNode(child))
        return children

def children ( self ) : children = [ ] child_nodes = getattr ( self . element , 'Children' ) for child in getattr ( child_nodes , 'BrowseNode' , [ ] ) : children . append ( AmazonBrowseNode ( child ) ) return children

This browse node s children in the browse node tree .


def _safe_get_element(self, path, root=None):
        """Safe Get Element.

        Get a child element of root (multiple levels deep) failing silently
        if any descendant does not exist.

        :param root:
            Lxml element.
        :param path:
            String path (i.e. 'Items.Item.Offers.Offer').
        :return:
            Element or None.
        """
        elements = path.split('.')
        parent = root if root is not None else self.item
        for element in elements[:-1]:
            parent = getattr(parent, element, None)
            if parent is None:
                return None
        return getattr(parent, elements[-1], None)

def _safe_get_element ( self , path , root = None ) : elements = path . split ( '.' ) parent = root if root is not None else self . item for element in elements [ : - 1 ] : parent = getattr ( parent , element , None ) if parent is None : return None return getattr ( parent , elements [ - 1 ] , None )


def _safe_get_element_text(self, path, root=None):
        """Safe get element text.

        Get element as string or None,
        :param root:
            Lxml element.
        :param path:
            String path (i.e. 'Items.Item.Offers.Offer').
        :return:
            String or None.
        """
        element = self._safe_get_element(path, root)
        if element:
            return element.text
        else:
            return None

def _safe_get_element_text ( self , path , root = None ) : element = self . _safe_get_element ( path , root ) if element : return element . text else : return None


def _safe_get_element_date(self, path, root=None):
        """Safe get elemnent date.

        Get element as datetime.date or None,
        :param root:
            Lxml element.
        :param path:
            String path (i.e. 'Items.Item.Offers.Offer').
        :return:
            datetime.date or None.
        """
        value = self._safe_get_element_text(path=path, root=root)
        if value is not None:
            try:
                value = datetime.datetime.strptime(value, '%Y-%m-%d').date()
            except ValueError:
                value = None

        return value

def _safe_get_element_date ( self , path , root = None ) : value = self . _safe_get_element_text ( path = path , root = root ) if value is not None : try : value = datetime . datetime . strptime ( value , '%Y-%m-%d' ) . date ( ) except ValueError : value = None return value


def price_and_currency(self):
        """Get Offer Price and Currency.

        Return price according to the following process:

        * If product has a sale return Sales Price, otherwise,
        * Return Price, otherwise,
        * Return lowest offer price, otherwise,
        * Return None.

        :return:
            A tuple containing:

                1. Float representation of price.
                2. ISO Currency code (string).
        """
        price = self._safe_get_element_text(
            'Offers.Offer.OfferListing.SalePrice.Amount')
        if price:
            currency = self._safe_get_element_text(
                'Offers.Offer.OfferListing.SalePrice.CurrencyCode')
        else:
            price = self._safe_get_element_text(
                'Offers.Offer.OfferListing.Price.Amount')
            if price:
                currency = self._safe_get_element_text(
                    'Offers.Offer.OfferListing.Price.CurrencyCode')
            else:
                price = self._safe_get_element_text(
                    'OfferSummary.LowestNewPrice.Amount')
                currency = self._safe_get_element_text(
                    'OfferSummary.LowestNewPrice.CurrencyCode')
        if price:
            return float(price) / 100, currency
        else:
            return None, None


def list_price(self):
        """List Price.

        :return:
            A tuple containing:

                1. Float representation of price.
                2. ISO Currency code (string).
        """
        price = self._safe_get_element_text('ItemAttributes.ListPrice.Amount')
        currency = self._safe_get_element_text(
            'ItemAttributes.ListPrice.CurrencyCode')
        if price:
            return float(price) / 100, currency
        else:
            return None, None

def list_price ( self ) : price = self . _safe_get_element_text ( 'ItemAttributes.ListPrice.Amount' ) currency = self . _safe_get_element_text ( 'ItemAttributes.ListPrice.CurrencyCode' ) if price : return float ( price ) / 100 , currency else : return None , None


def send(self, request, **kw):
        """
        Send a request. Use the request information to see if it
        exists in the cache and cache the response if we need to and can.
        """
        if request.method == 'GET':
            cached_response = self.controller.cached_request(request)
            if cached_response:
                return self.build_response(request, cached_response,
                                           from_cache=True)

            # check for etags and add headers if appropriate
            request.headers.update(
                self.controller.conditional_headers(request)
            )

        resp = super(CacheControlAdapter, self).send(request, **kw)

        return resp

def send ( self , request , ** kw ) : if request . method == 'GET' : cached_response = self . controller . cached_request ( request ) if cached_response : return self . build_response ( request , cached_response , from_cache = True ) request . headers . update ( self . controller . conditional_headers ( request ) ) resp = super ( CacheControlAdapter , self ) . send ( request , ** kw ) return resp

Send a request . Use the request information to see if it exists in the cache and cache the response if we need to and can .


def build_response(self, request, response, from_cache=False):
        """
        Build a response by making a request or using the cache.

        This will end up calling send and returning a potentially
        cached response
        """
        if not from_cache and request.method == 'GET':

            # apply any expiration heuristics
            if response.status == 304:
                # We must have sent an ETag request. This could mean
                # that we've been expired already or that we simply
                # have an etag. In either case, we want to try and
                # update the cache if that is the case.
                cached_response = self.controller.update_cached_response(
                    request, response
                )

                if cached_response is not response:
                    from_cache = True

                # We are done with the server response, read a
                # possible response body (compliant servers will
                # not return one, but we cannot be 100% sure) and
                # release the connection back to the pool.
                response.read(decode_content=False)
                response.release_conn()

                response = cached_response

            # We always cache the 301 responses
            elif response.status == 301:
                self.controller.cache_response(request, response)
            else:
                # Check for any heuristics that might update headers
                # before trying to cache.
                if self.heuristic:
                    response = self.heuristic.apply(response)

                # Wrap the response file with a wrapper that will cache the
                #   response when the stream has been consumed.
                response._fp = CallbackFileWrapper(
                    response._fp,
                    functools.partial(
                        self.controller.cache_response,
                        request,
                        response,
                    )
                )

        resp = super(CacheControlAdapter, self).build_response(
            request, response
        )

        # See if we should invalidate the cache.
        if request.method in self.invalidating_methods and resp.ok:
            cache_url = self.controller.cache_url(request.url)
            self.cache.delete(cache_url)

        # Give the request a from_cache attr to let people use it
        resp.from_cache = from_cache

        return resp

def build_response ( self , request , response , from_cache = False ) : if not from_cache and request . method == 'GET' : if response . status == 304 : cached_response = self . controller . update_cached_response ( request , response ) if cached_response is not response : from_cache = True response . read ( decode_content = False ) response . release_conn ( ) response = cached_response elif response . status == 301 : self . controller . cache_response ( request , response ) else : if self . heuristic : response = self . heuristic . apply ( response ) response . _fp = CallbackFileWrapper ( response . _fp , functools . partial ( self . controller . cache_response , request , response , ) ) resp = super ( CacheControlAdapter , self ) . build_response ( request , response ) if request . method in self . invalidating_methods and resp . ok : cache_url = self . controller . cache_url ( request . url ) self . cache . delete ( cache_url ) resp . from_cache = from_cache return resp

Build a response by making a request or using the cache .


def make_attrgetter(environment, attribute):
    """Returns a callable that looks up the given attribute from a
    passed object with the rules of the environment.  Dots are allowed
    to access attributes of attributes.  Integer parts in paths are
    looked up as integers.
    """
    if not isinstance(attribute, string_types) \
       or ('.' not in attribute and not attribute.isdigit()):
        return lambda x: environment.getitem(x, attribute)
    attribute = attribute.split('.')
    def attrgetter(item):
        for part in attribute:
            if part.isdigit():
                part = int(part)
            item = environment.getitem(item, part)
        return item
    return attrgetter

def make_attrgetter ( environment , attribute ) : if not isinstance ( attribute , string_types ) or ( '.' not in attribute and not attribute . isdigit ( ) ) : return lambda x : environment . getitem ( x , attribute ) attribute = attribute . split ( '.' ) def attrgetter ( item ) : for part in attribute : if part . isdigit ( ) : part = int ( part ) item = environment . getitem ( item , part ) return item return attrgetter

Returns a callable that looks up the given attribute from a passed object with the rules of the environment . Dots are allowed to access attributes of attributes . Integer parts in paths are looked up as integers .


def do_title(s):
    """Return a titlecased version of the value. I.e. words will start with
    uppercase letters, all remaining characters are lowercase.
    """
    rv = []
    for item in re.compile(r'([-\s]+)(?u)').split(s):
        if not item:
            continue
        rv.append(item[0].upper() + item[1:].lower())
    return ''.join(rv)

def do_title ( s ) : rv = [ ] for item in re . compile ( r'([-\s]+)(?u)' ) . split ( s ) : if not item : continue rv . append ( item [ 0 ] . upper ( ) + item [ 1 : ] . lower ( ) ) return '' . join ( rv )

Return a titlecased version of the value . I . e . words will start with uppercase letters all remaining characters are lowercase .


def do_sort(environment, value, reverse=False, case_sensitive=False,
            attribute=None):
    """Sort an iterable.  Per default it sorts ascending, if you pass it
    true as first argument it will reverse the sorting.

    If the iterable is made of strings the third parameter can be used to
    control the case sensitiveness of the comparison which is disabled by
    default.

    .. sourcecode:: jinja

        {% for item in iterable|sort %}
            ...
        {% endfor %}

    It is also possible to sort by an attribute (for example to sort
    by the date of an object) by specifying the `attribute` parameter:

    .. sourcecode:: jinja

        {% for item in iterable|sort(attribute='date') %}
            ...
        {% endfor %}

    .. versionchanged:: 2.6
       The `attribute` parameter was added.
    """
    if not case_sensitive:
        def sort_func(item):
            if isinstance(item, string_types):
                item = item.lower()
            return item
    else:
        sort_func = None
    if attribute is not None:
        getter = make_attrgetter(environment, attribute)
        def sort_func(item, processor=sort_func or (lambda x: x)):
            return processor(getter(item))
    return sorted(value, key=sort_func, reverse=reverse)

def do_sort ( environment , value , reverse = False , case_sensitive = False , attribute = None ) : if not case_sensitive : def sort_func ( item ) : if isinstance ( item , string_types ) : item = item . lower ( ) return item else : sort_func = None if attribute is not None : getter = make_attrgetter ( environment , attribute ) def sort_func ( item , processor = sort_func or ( lambda x : x ) ) : return processor ( getter ( item ) ) return sorted ( value , key = sort_func , reverse = reverse )

Sort an iterable . Per default it sorts ascending if you pass it true as first argument it will reverse the sorting .


def do_groupby(environment, value, attribute):
    """Group a sequence of objects by a common attribute.

    If you for example have a list of dicts or objects that represent persons
    with `gender`, `first_name` and `last_name` attributes and you want to
    group all users by genders you can do something like the following
    snippet:

    .. sourcecode:: html+jinja

        {% for group in persons|groupby('gender') %}

{{ group.grouper }}

            {% for person in group.list %}

{{ person.first_name }} {{ person.last_name }}

            {% endfor %}

        {% endfor %}

    Additionally it's possible to use tuple unpacking for the grouper and
    list:

    .. sourcecode:: html+jinja

        {% for grouper, list in persons|groupby('gender') %}
            ...
        {% endfor %}

    As you can see the item we're grouping by is stored in the `grouper`
    attribute and the `list` contains all the objects that have this grouper
    in common.

    .. versionchanged:: 2.6
       It's now possible to use dotted notation to group by the child
       attribute of another attribute.
    """
    expr = make_attrgetter(environment, attribute)
    return sorted(map(_GroupTuple, groupby(sorted(value, key=expr), expr)))

def do_groupby ( environment , value , attribute ) : expr = make_attrgetter ( environment , attribute ) return sorted ( map ( _GroupTuple , groupby ( sorted ( value , key = expr ) , expr ) ) )

Group a sequence of objects by a common attribute .


def do_map(*args, **kwargs):
    """Applies a filter on a sequence of objects or looks up an attribute.
    This is useful when dealing with lists of objects but you are really
    only interested in a certain value of it.

    The basic usage is mapping on an attribute.  Imagine you have a list
    of users but you are only interested in a list of usernames:

    .. sourcecode:: jinja

        Users on this page: {{ users|map(attribute='username')|join(', ') }}

    Alternatively you can let it invoke a filter by passing the name of the
    filter and the arguments afterwards.  A good example would be applying a
    text conversion filter on a sequence:

    .. sourcecode:: jinja

        Users on this page: {{ titles|map('lower')|join(', ') }}

    .. versionadded:: 2.7
    """
    context = args[0]
    seq = args[1]

    if len(args) == 2 and 'attribute' in kwargs:
        attribute = kwargs.pop('attribute')
        if kwargs:
            raise FilterArgumentError('Unexpected keyword argument %r' %
                next(iter(kwargs)))
        func = make_attrgetter(context.environment, attribute)
    else:
        try:
            name = args[2]
            args = args[3:]
        except LookupError:
            raise FilterArgumentError('map requires a filter argument')
        func = lambda item: context.environment.call_filter(
            name, item, args, kwargs, context=context)

    if seq:
        for item in seq:
            yield func(item)

def
do_map
(
*
args
,
**
kwargs
)
:
context
=
args
[
0
]
seq
=
args
[
1
]
if
len
(
args
)
==
2
and
'attribute'
in
kwargs
:
attribute
=
kwargs
.
pop
(
'attribute'
)
if
kwargs
:
raise
FilterArgumentError
(
'Unexpected keyword argument %r'
%
next
(
iter
(
kwargs
)
)
)
func
=
make_attrgetter
(
context
.
environment
,
attribute
)
else
:
try
:
name
=
args
[
2
]
args
=
args
[
3
:
]
except
LookupError
:
raise
FilterArgumentError
(
'map requires a filter argument'
)
func
=
lambda
item
:
context
.
environment
.
call_filter
(
name
,
item
,
args
,
kwargs
,
context
=
context
)
if
seq
:
for
item
in
seq
:
yield
func
(
item
)

Applies a filter on a sequence of objects or looks up an attribute . This is useful when dealing with lists of objects but you are really only interested in a certain value of it .


def create_logger(app):
    """Creates a logger for the given application.  This logger works
    similar to a regular Python logger but changes the effective logging
    level based on the application's debug flag.  Furthermore this
    function also removes all attached handlers in case there was a
    logger with the log name before.
    """
    Logger = getLoggerClass()

    class DebugLogger(Logger):
        def getEffectiveLevel(x):
            if x.level == 0 and app.debug:
                return DEBUG
            return Logger.getEffectiveLevel(x)

    class DebugHandler(StreamHandler):
        def emit(x, record):
            StreamHandler.emit(x, record) if app.debug else None

    handler = DebugHandler()
    handler.setLevel(DEBUG)
    handler.setFormatter(Formatter(app.debug_log_format))
    logger = getLogger(app.logger_name)
    # just in case that was not a new logger, get rid of all the handlers
    # already attached to it.
    del logger.handlers[:]
    logger.__class__ = DebugLogger
    logger.addHandler(handler)
    return logger

def create_logger ( app ) : Logger = getLoggerClass ( ) class DebugLogger ( Logger ) : def getEffectiveLevel ( x ) : if x . level == 0 and app . debug : return DEBUG return Logger . getEffectiveLevel ( x ) class DebugHandler ( StreamHandler ) : def emit ( x , record ) : StreamHandler . emit ( x , record ) if app . debug else None handler = DebugHandler ( ) handler . setLevel ( DEBUG ) handler . setFormatter ( Formatter ( app . debug_log_format ) ) logger = getLogger ( app . logger_name ) del logger . handlers [ : ] logger . __class__ = DebugLogger logger . addHandler ( handler ) return logger

Creates a logger for the given application . This logger works similar to a regular Python logger but changes the effective logging level based on the application s debug flag . Furthermore this function also removes all attached handlers in case there was a logger with the log name before .


def constant_time_compare(val1, val2):
    """Returns True if the two strings are equal, False otherwise.

    The time taken is independent of the number of characters that match.  Do
    not use this function for anything else than comparision with known
    length targets.

    This is should be implemented in C in order to get it completely right.
    """
    if _builtin_constant_time_compare is not None:
        return _builtin_constant_time_compare(val1, val2)
    len_eq = len(val1) == len(val2)
    if len_eq:
        result = 0
        left = val1
    else:
        result = 1
        left = val2
    for x, y in izip(bytearray(left), bytearray(val2)):
        result |= x ^ y
    return result == 0

def constant_time_compare ( val1 , val2 ) : if _builtin_constant_time_compare is not None : return _builtin_constant_time_compare ( val1 , val2 ) len_eq = len ( val1 ) == len ( val2 ) if len_eq : result = 0 left = val1 else : result = 1 left = val2 for x , y in izip ( bytearray ( left ) , bytearray ( val2 ) ) : result |= x ^ y return result == 0

Returns True if the two strings are equal False otherwise .


def verify_signature(self, key, value, sig):
        """Verifies the given signature matches the expected signature"""
        return constant_time_compare(sig, self.get_signature(key, value))

def verify_signature ( self , key , value , sig ) : return constant_time_compare ( sig , self . get_signature ( key , value ) )


def derive_key(self):
        """This method is called to derive the key.  If you're unhappy with
        the default key derivation choices you can override them here.
        Keep in mind that the key derivation in itsdangerous is not intended
        to be used as a security method to make a complex key out of a short
        password.  Instead you should use large random secret keys.
        """
        salt = want_bytes(self.salt)
        if self.key_derivation == 'concat':
            return self.digest_method(salt + self.secret_key).digest()
        elif self.key_derivation == 'django-concat':
            return self.digest_method(salt + b'signer' +
                self.secret_key).digest()
        elif self.key_derivation == 'hmac':
            mac = hmac.new(self.secret_key, digestmod=self.digest_method)
            mac.update(salt)
            return mac.digest()
        elif self.key_derivation == 'none':
            return self.secret_key
        else:
            raise TypeError('Unknown key derivation method')

def
derive_key
(
self
)
:
salt
=
want_bytes
(
self
.
salt
)
if
self
.
key_derivation
==
'concat'
:
return
self
.
digest_method
(
salt
+
self
.
secret_key
)
.
digest
(
)
elif
self
.
key_derivation
==
'django-concat'
:
return
self
.
digest_method
(
salt
+
b'signer'
+
self
.
secret_key
)
.
digest
(
)
elif
self
.
key_derivation
==
'hmac'
:
mac
=
hmac
.
new
(
self
.
secret_key
,
digestmod
=
self
.
digest_method
)
mac
.
update
(
salt
)
return
mac
.
digest
(
)
elif
self
.
key_derivation
==
'none'
:
return
self
.
secret_key
else
:
raise
TypeError
(
'Unknown key derivation method'
)

This method is called to derive the key . If you re unhappy with the default key derivation choices you can override them here . Keep in mind that the key derivation in itsdangerous is not intended to be used as a security method to make a complex key out of a short password . Instead you should use large random secret keys .


def get_signature(self, value):
        """Returns the signature for the given value"""
        value = want_bytes(value)
        key = self.derive_key()
        sig = self.algorithm.get_signature(key, value)
        return base64_encode(sig)

def get_signature ( self , value ) : value = want_bytes ( value ) key = self . derive_key ( ) sig = self . algorithm . get_signature ( key , value ) return base64_encode ( sig )


def sign(self, value):
        """Signs the given string."""
        return value + want_bytes(self.sep) + self.get_signature(value)

def sign ( self , value ) : return value + want_bytes ( self . sep ) + self . get_signature ( value )


def verify_signature(self, value, sig):
        """Verifies the signature for the given value."""
        key = self.derive_key()
        try:
            sig = base64_decode(sig)
        except Exception:
            return False
        return self.algorithm.verify_signature(key, value, sig)

def verify_signature ( self , value , sig ) : key = self . derive_key ( ) try : sig = base64_decode ( sig ) except Exception : return False return self . algorithm . verify_signature ( key , value , sig )

Verifies the signature for the given value .


def unsign(self, signed_value):
        """Unsigns the given string."""
        signed_value = want_bytes(signed_value)
        sep = want_bytes(self.sep)
        if sep not in signed_value:
            raise BadSignature('No %r found in value' % self.sep)
        value, sig = signed_value.rsplit(sep, 1)
        if self.verify_signature(value, sig):
            return value
        raise BadSignature('Signature %r does not match' % sig,
                           payload=value)

def
unsign
(
self
,
signed_value
)
:
signed_value
=
want_bytes
(
signed_value
)
sep
=
want_bytes
(
self
.
sep
)
if
sep
not
in
signed_value
:
raise
BadSignature
(
'No %r found in value'
%
self
.
sep
)
value
,
sig
=
signed_value
.
rsplit
(
sep
,
1
)
if
self
.
verify_signature
(
value
,
sig
)
:
return
value
raise
BadSignature
(
'Signature %r does not match'
%
sig
,
payload
=
value
)


def sign(self, value):
        """Signs the given string and also attaches a time information."""
        value = want_bytes(value)
        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))
        sep = want_bytes(self.sep)
        value = value + sep + timestamp
        return value + sep + self.get_signature(value)

def sign ( self , value ) : value = want_bytes ( value ) timestamp = base64_encode ( int_to_bytes ( self . get_timestamp ( ) ) ) sep = want_bytes ( self . sep ) value = value + sep + timestamp return value + sep + self . get_signature ( value )

Signs the given string and also attaches a time information .


def validate(self, signed_value, max_age=None):
        """Just validates the given signed value.  Returns `True` if the
        signature exists and is valid, `False` otherwise."""
        try:
            self.unsign(signed_value, max_age=max_age)
            return True
        except BadSignature:
            return False

def validate ( self , signed_value , max_age = None ) : try : self . unsign ( signed_value , max_age = max_age ) return True except BadSignature : return False

Just validates the given signed value . Returns True if the signature exists and is valid False otherwise .


def dumps(self, obj, salt=None):
        """Returns a signed string serialized with the internal serializer.
        The return value can be either a byte or unicode string depending
        on the format of the internal serializer.
        """
        payload = want_bytes(self.dump_payload(obj))
        rv = self.make_signer(salt).sign(payload)
        if self.is_text_serializer:
            rv = rv.decode('utf-8')
        return rv

def dumps ( self , obj , salt = None ) : payload = want_bytes ( self . dump_payload ( obj ) ) rv = self . make_signer ( salt ) . sign ( payload ) if self . is_text_serializer : rv = rv . decode ( 'utf-8' ) return rv

Returns a signed string serialized with the internal serializer . The return value can be either a byte or unicode string depending on the format of the internal serializer .


def server_error(request_id, error):
    """JSON-RPC server error.

    :param request_id: JSON-RPC request id
    :type request_id: int or str or None
    :param error: server error
    :type error: Exception

    """

    response = {
        'jsonrpc': '2.0',
        'id': request_id,
        'error': {
            'code': -32000,
            'message': 'Server error',
            'data': repr(error),
        },
    }
    raise ServiceException(500, dumps(response))

def
server_error
(
request_id
,
error
)
:
response
=
{
'jsonrpc'
:
'2.0'
,
'id'
:
request_id
,
'error'
:
{
'code'
:
32000
,
'message'
:
'Server error'
,
'data'
:
repr
(
error
)
,
}
,
}
raise
ServiceException
(
500
,
dumps
(
response
)
)


def find(cls, where='.', exclude=(), include=('*',)):
        """Return a list all Python packages found within directory 'where'

        'where' should be supplied as a "cross-platform" (i.e. URL-style)
        path; it will be converted to the appropriate local path syntax.
        'exclude' is a sequence of package names to exclude; '*' can be used
        as a wildcard in the names, such that 'foo.*' will exclude all
        subpackages of 'foo' (but not 'foo' itself).

        'include' is a sequence of package names to include.  If it's
        specified, only the named packages will be included.  If it's not
        specified, all found packages will be included.  'include' can contain
        shell style wildcard patterns just like 'exclude'.

        The list of included packages is built up first and then any
        explicitly excluded packages are removed from it.
        """
        out = cls._find_packages_iter(convert_path(where))
        out = cls.require_parents(out)
        includes = cls._build_filter(*include)
        excludes = cls._build_filter('ez_setup', '*__pycache__', *exclude)
        out = filter(includes, out)
        out = filterfalse(excludes, out)
        return list(out)

def find ( cls , where = '.' , exclude = ( ) , include = ( '*' , ) ) : out = cls . _find_packages_iter ( convert_path ( where ) ) out = cls . require_parents ( out ) includes = cls . _build_filter ( * include ) excludes = cls . _build_filter ( 'ez_setup' , '*__pycache__' , * exclude ) out = filter ( includes , out ) out = filterfalse ( excludes , out ) return list ( out )

Return a list all Python packages found within directory where


def require_parents(packages):
        """
        Exclude any apparent package that apparently doesn't include its
        parent.

        For example, exclude 'foo.bar' if 'foo' is not present.
        """
        found = []
        for pkg in packages:
            base, sep, child = pkg.rpartition('.')
            if base and base not in found:
                continue
            found.append(pkg)
            yield pkg

def require_parents ( packages ) : found = [ ] for pkg in packages : base , sep , child = pkg . rpartition ( '.' ) if base and base not in found : continue found . append ( pkg ) yield pkg

Exclude any apparent package that apparently doesn t include its parent .


def _all_dirs(base_path):
        """
        Return all dirs in base_path, relative to base_path
        """
        for root, dirs, files in os.walk(base_path, followlinks=True):
            for dir in dirs:
                yield os.path.relpath(os.path.join(root, dir), base_path)

def _all_dirs ( base_path ) : for root , dirs , files in os . walk ( base_path , followlinks = True ) : for dir in dirs : yield os . path . relpath ( os . path . join ( root , dir ) , base_path )

Return all dirs in base_path relative to base_path


def prepare_response(self, request, cached):
        """Verify our vary headers match and construct a real urllib3
        HTTPResponse object.
        """
        # Special case the '*' Vary value as it means we cannot actually
        # determine if the cached response is suitable for this request.
        if "*" in cached.get("vary", {}):
            return

        # Ensure that the Vary headers for the cached response match our
        # request
        for header, value in cached.get("vary", {}).items():
            if request.headers.get(header, None) != value:
                return

        body_raw = cached["response"].pop("body")

        try:
            body = io.BytesIO(body_raw)
        except TypeError:
            # This can happen if cachecontrol serialized to v1 format (pickle)
            # using Python 2. A Python 2 str(byte string) will be unpickled as
            # a Python 3 str (unicode string), which will cause the above to
            # fail with:
            #
            #     TypeError: 'str' does not support the buffer interface
            body = io.BytesIO(body_raw.encode('utf8'))

        return HTTPResponse(
            body=body,
            preload_content=False,
            **cached["response"]
        )

def prepare_response ( self , request , cached ) : if "*" in cached . get ( "vary" , { } ) : return for header , value in cached . get ( "vary" , { } ) . items ( ) : if request . headers . get ( header , None ) != value : return body_raw = cached [ "response" ] . pop ( "body" ) try : body = io . BytesIO ( body_raw ) except TypeError : body = io . BytesIO ( body_raw . encode ( 'utf8' ) ) return HTTPResponse ( body = body , preload_content = False , ** cached [ "response" ] )

Verify our vary headers match and construct a real urllib3 HTTPResponse object .


def unsign(wheelfile):
    """
    Remove RECORD.jws from a wheel by truncating the zip file.

    RECORD.jws must be at the end of the archive. The zip file must be an
    ordinary archive, with the compressed files and the directory in the same
    order, and without any non-zip content after the truncation point.
    """
    import wheel.install
    vzf = wheel.install.VerifyingZipFile(wheelfile, "a")
    info = vzf.infolist()
    if not (len(info) and info[-1].filename.endswith('/RECORD.jws')):
        raise WheelError("RECORD.jws not found at end of archive.")
    vzf.pop()
    vzf.close()

Remove RECORD . jws from a wheel by truncating the zip file . RECORD . jws must be at the end of the archive . The zip file must be an ordinary archive with the compressed files and the directory in the same order and without any non - zip content after the truncation point .


def unpack(wheelfile, dest='.'):
    """Unpack a wheel.

    Wheel content will be unpacked to {dest}/{name}-{ver}, where {name}
    is the package name and {ver} its version.

    :param wheelfile: The path to the wheel.
    :param dest: Destination directory (default to current directory).
    """
    wf = WheelFile(wheelfile)
    namever = wf.parsed_filename.group('namever')
    destination = os.path.join(dest, namever)
    sys.stderr.write("Unpacking to: %s\n" % (destination))
    wf.zipfile.extractall(destination)
    wf.zipfile.close()

def
unpack
(
wheelfile
,
dest
=
'.'
)
:
wf
=
WheelFile
(
wheelfile
)
namever
=
wf
.
parsed_filename
.
group
(
'namever'
)
destination
=
os
.
path
.
join
(
dest
,
namever
)
sys
.
stderr
.
write
(
"Unpacking to: %s\n"
%
(
destination
)
)
wf
.
zipfile
.
extractall
(
destination
)
wf
.
zipfile
.
close
(
)


def install_scripts(distributions):
    """
    Regenerate the entry_points console_scripts for the named distribution.
    """
    try:
        from setuptools.command import easy_install
        import pkg_resources
    except ImportError:
        raise RuntimeError("'wheel install_scripts' needs setuptools.")

    for dist in distributions:
        pkg_resources_dist = pkg_resources.get_distribution(dist)
        install = wheel.paths.get_install_command(dist)
        command = easy_install.easy_install(install.distribution)
        command.args = ['wheel'] # dummy argument
        command.finalize_options()
        command.install_egg_scripts(pkg_resources_dist)

Regenerate the entry_points console_scripts for the named distribution .


def arrange_all(self):
        """ Sets for the _draw_ and _ldraw_ attributes for each of the graph
            sub-elements by processing the xdot format of the graph.
        """
        import godot.dot_data_parser

        parser = godot.dot_data_parser.GodotDataParser()

        xdot_data = self.create( format = "xdot" )
#        print "GRAPH DOT:\n", str( self )
#        print "XDOT DATA:\n", xdot_data

        parser.dotparser.parseWithTabs()
        ndata = xdot_data.replace( "\\\n", "" )
        tokens = parser.dotparser.parseString( ndata )[0]
        parser.build_graph( graph=self, tokens=tokens[3] )

        self.redraw_canvas()

def arrange_all ( self ) : import godot . dot_data_parser parser = godot . dot_data_parser . GodotDataParser ( ) xdot_data = self . create ( format = "xdot" ) parser . dotparser . parseWithTabs ( ) ndata = xdot_data . replace ( "\\\n" , "" ) tokens = parser . dotparser . parseString ( ndata ) [ 0 ] parser . build_graph ( graph = self , tokens = tokens [ 3 ] ) self . redraw_canvas ( )

Sets for the _draw_ and _ldraw_ attributes for each of the graph sub - elements by processing the xdot format of the graph .


def redraw_canvas(self):
        """ Parses the Xdot attributes of all graph components and adds
            the components to a new canvas.
        """
        from xdot_parser import XdotAttrParser

        xdot_parser = XdotAttrParser()
        canvas = self._component_default()

        for node in self.nodes:
            components = xdot_parser.parse_xdot_data( node._draw_ )
            canvas.add( *components )

            components = xdot_parser.parse_xdot_data( node._ldraw_ )
            canvas.add( *components )

        for edge in self.edges:
            components = xdot_parser.parse_xdot_data( edge._draw_ )
            canvas.add( *components )
            components = xdot_parser.parse_xdot_data( edge._ldraw_ )
            canvas.add( *components )
            components = xdot_parser.parse_xdot_data( edge._hdraw_ )
            canvas.add( *components )
            components = xdot_parser.parse_xdot_data( edge._tdraw_ )
            canvas.add( *components )
            components = xdot_parser.parse_xdot_data( edge._hldraw_ )
            canvas.add( *components )
            components = xdot_parser.parse_xdot_data( edge._tldraw_ )
            canvas.add( *components )

        self.component = canvas
        self.vp.request_redraw()

def redraw_canvas ( self ) : from xdot_parser import XdotAttrParser xdot_parser = XdotAttrParser ( ) canvas = self . _component_default ( ) for node in self . nodes : components = xdot_parser . parse_xdot_data ( node . _draw_ ) canvas . add ( * components ) components = xdot_parser . parse_xdot_data ( node . _ldraw_ ) canvas . add ( * components ) for edge in self . edges : components = xdot_parser . parse_xdot_data ( edge . _draw_ ) canvas . add ( * components ) components = xdot_parser . parse_xdot_data ( edge . _ldraw_ ) canvas . add ( * components ) components = xdot_parser . parse_xdot_data ( edge . _hdraw_ ) canvas . add ( * components ) components = xdot_parser . parse_xdot_data ( edge . _tdraw_ ) canvas . add ( * components ) components = xdot_parser . parse_xdot_data ( edge . _hldraw_ ) canvas . add ( * components ) components = xdot_parser . parse_xdot_data ( edge . _tldraw_ ) canvas . add ( * components ) self . component = canvas self . vp . request_redraw ( )

Parses the Xdot attributes of all graph components and adds the components to a new canvas .


def get_node(self, ID):
        """ Returns a node given an ID or None if no such node exists.
        """
        node = super(Graph, self).get_node(ID)
        if node is not None:
            return node

        for graph in self.all_graphs:
            for each_node in graph.nodes:
                if each_node.ID == ID:
                    return each_node
        else:
            return None

def get_node ( self , ID ) : node = super ( Graph , self ) . get_node ( ID ) if node is not None : return node for graph in self . all_graphs : for each_node in graph . nodes : if each_node . ID == ID : return each_node else : return None

Returns a node given an ID or None if no such node exists .


def _directed_changed(self, new):
        """ Sets the connection string for all edges.
        """
        if new:
            conn = "->"
        else:
            conn = "--"

        for edge in [e for g in self.all_graphs for e in g.edges]:
            edge.conn = conn

def _directed_changed ( self , new ) : if new : conn = "->" else : conn = "--" for edge in [ e for g in self . all_graphs for e in g . edges ] : edge . conn = conn

Sets the connection string for all edges .


def _on_edges(self, object, name, old, new):
        """ Handles the list of edges for any graph changing.
        """
        if name == "edges_items":
            edges = new.added
        elif name == "edges":
            edges = new
        else:
            edges = []

        all_nodes = [n for g in self.all_graphs for n in g.nodes]

        for each_edge in edges:
            # Ensure the edge's nodes exist in the graph.
            if each_edge.tail_node not in all_nodes:
                object.nodes.append( each_edge.tail_node )

            if each_edge.head_node not in all_nodes:
                object.nodes.append( each_edge.head_node )

            # Initialise the edge's list of available nodes.
            each_edge._nodes = all_nodes

def _on_edges ( self , object , name , old , new ) : if name == "edges_items" : edges = new . added elif name == "edges" : edges = new else : edges = [ ] all_nodes = [ n for g in self . all_graphs for n in g . nodes ] for each_edge in edges : if each_edge . tail_node not in all_nodes : object . nodes . append ( each_edge . tail_node ) if each_edge . head_node not in all_nodes : object . nodes . append ( each_edge . head_node ) each_edge . _nodes = all_nodes

Handles the list of edges for any graph changing .


def _component_changed(self, old, new):
        """ Handles the component being changed.
        """
        canvas = self.canvas
        if old is not None:
            canvas.remove(old)
        if new is not None:
            canvas.add(new)

def _component_changed ( self , old , new ) : canvas = self . canvas if old is not None : canvas . remove ( old ) if new is not None : canvas . add ( new )


def normal_left_dclick(self, event):
        """ Handles the left mouse button being double-clicked when the tool
        is in the 'normal' state.

        If the event occurred on this tool's component (or any contained
        component of that component), the method opens a Traits UI view on the
        object referenced by the 'element' trait of the component that was
        double-clicked, setting the tool as the active tool for the duration
        of the view.

        """
        x = event.x
        y = event.y

        # First determine what component or components we are going to hittest
        # on.  If our component is a container, then we add its non-container
        # components to the list of candidates.
#        candidates = []
        component = self.component
#        if isinstance(component, Container):
#            candidates = get_nested_components(self.component)
#        else:
#            # We don't support clicking on unrecognized components
#            return
#
#        # Hittest against all the candidate and take the first one
#        item = None
#        for candidate, offset in candidates:
#            if candidate.is_in(x-offset[0], y-offset[1]):
#                item = candidate
#                break

        if hasattr(component, "element"):
            if component.element is not None:
                component.active_tool = self
                component.element.edit_traits(kind="livemodal")
                event.handled = True
                component.active_tool = None
                component.request_redraw()
        return

def normal_left_dclick ( self , event ) : x = event . x y = event . y component = self . component if hasattr ( component , "element" ) : if component . element is not None : component . active_tool = self component . element . edit_traits ( kind = "livemodal" ) event . handled = True component . active_tool = None component . request_redraw ( ) return

Handles the left mouse button being double - clicked when the tool is in the normal state .


def _diagram_canvas_changed(self, new):
        """ Handles the diagram canvas being set """

        logger.debug("Diagram canvas changed!")
        canvas = self.diagram_canvas

        for tool in self.tools:
            if canvas is not None:
                print "Adding tool: %s" % tool
                canvas.tools.append(tool(canvas))

def
_diagram_canvas_changed
(
self
,
new
)
:
logger
.
debug
(
"Diagram canvas changed!"
)
canvas
=
self
.
diagram_canvas
for
tool
in
self
.
tools
:
if
canvas
is
not
:
print
"Adding tool: %s"
%
tool
canvas
.
tools
.
append
(
tool
(
canvas
)
)


def clear_canvas(self):
        """ Removes all components from the canvas """

        logger.debug("Clearing the diagram canvas!")
        old_canvas = self.diagram_canvas

#        logger.debug("Canvas components: %s" % canvas.components)
#        for component in canvas.components:
#            canvas.remove(component)
#        logger.debug("Canvas components: %s" % canvas.components)
#        for component in canvas.components:
#            canvas.remove(component)
#        logger.debug("Canvas components: %s" % canvas.components)
#        canvas.request_redraw()

        new_canvas = Canvas()
        new_canvas.copy_traits(old_canvas, ["bgcolor", "draw_axes"])
        self.diagram_canvas = new_canvas

        self.viewport.component=new_canvas
        self.viewport.request_redraw()

        return

def
clear_canvas
(
self
)
:
logger
.
debug
(
"Clearing the diagram canvas!"
)
old_canvas
=
self
.
diagram_canvas
new_canvas
=
Canvas
(
)
new_canvas
.
copy_traits
(
old_canvas
,
[
"bgcolor"
,
"draw_axes"
]
)
self
.
diagram_canvas
=
new_canvas
self
.
viewport
.
component
=
new_canvas
self
.
viewport
.
request_redraw
(
)
return


def _domain_model_changed_for_diagram(self, obj, name, old, new):
        """ Handles the domain model changing """

        if old is not None:
            self.unmap_model(old)
        if new is not None:
            self.map_model(new)

def _domain_model_changed_for_diagram ( self , obj , name , old , new ) : if old is not None : self . unmap_model ( old ) if new is not None : self . map_model ( new )


def map_model(self, new):
        """ Maps a domain model to the diagram """

        logger.debug("Mapping the domain model!")
        dot = Dot()

        self.diagram.clear_canvas()

        for node_mapping in self.nodes:
            ct = node_mapping.containment_trait
            logger.debug("Mapping elements contained by the '%s' trait" % ct)
            if hasattr(new, ct):
                elements = getattr(new, ct)
                logger.debug("%d element(s) found" % len(elements))
                for element in elements:
                    pydot_node = Node(str(id(element)))
                    dot_attrs = node_mapping.dot_node
                    if dot_attrs is not None:
                        self._style_node(pydot_node, dot_attrs)
                    dot.add_node(pydot_node)

                    new.on_trait_change(self.map_element, ct+"_items")

        logger.debug("Retrieving xdot data and forming pydot graph!")
        xdot = graph_from_dot_data(dot.create(self.program, "xdot"))
        parser = XDotParser()

        for node in xdot.get_node_list():
            diagram_node = parser.parse_node(node)
            logger.debug(
                "Parsed node [%s] and received diagram node [%s]" %
                (node, diagram_node)
            )
            if diagram_node is not None:
                for node_mapping in self.nodes: # FIXME: slow
                    ct = node_mapping.containment_trait
                    for element in getattr(new, ct):
                        if str(id(element)) == diagram_node.dot_node.get_name():
                            logger.debug(
                                "Referencing element [%s] from diagram node [%s]" %
                                (element, diagram_node)
                            )
                            diagram_node.element = element
                            break

                    # Tools
                    if isinstance(diagram_node.element, node_mapping.element):
                        for tool in node_mapping.tools:
                            logger.debug(
                                "Adding tool [%s] to diagram node [%s]" %
                                (tool, diagram_node)
                            )
                            diagram_node.tools.append(tool(diagram_node))

                else:
                    if diagram_node.element is None:
                        logger.warning("Diagram node not referenced to element")

                self.diagram.diagram_canvas.add(diagram_node)

        del parser


def unmap_model(self, old):
        """ Removes listeners from a domain model """

        for node_mapping in self.nodes:
            ct = node_mapping.containment_trait
            if hasattr(old, ct):
                old_elements = getattr(old, ct)
                for old_element in old_elements:
                    old.on_trait_change(
                        self.map_element, ct+"_items", remove=True
                    )

def unmap_model ( self , old ) : for node_mapping in self . nodes : ct = node_mapping . containment_trait if hasattr ( old , ct ) : old_elements = getattr ( old , ct ) for old_element in old_elements : old . on_trait_change ( self . map_element , ct + "_items" , remove = True )


def map_element(self, obj, name, event):
        """ Handles mapping elements to diagram components """

        canvas = self.diagram.diagram_canvas
        parser = XDotParser()

        for element in event.added:
            logger.debug("Mapping new element [%s] to diagram node" % element)
            for node_mapping in self.nodes:
                ct = name[:-6] #strip '_items'
                if node_mapping.containment_trait == ct:
                    dot_attrs = node_mapping.dot_node
                    dot = Dot()
                    graph_node = Node(str(id(element)))
                    self._style_node(graph_node, dot_attrs)
                    dot.add_node(graph_node)
                    xdot = graph_from_dot_data(dot.create(self.program,"xdot"))
                    diagram_nodes = parser.parse_nodes(xdot)#.get_node_list())
                    for dn in diagram_nodes:
                        if dn is not None:
                            dn.element = element
                            # Tools
                            for tool in node_mapping.tools:
                                dn.tools.append(tool(dn))

                            canvas.add(dn)
                            canvas.request_redraw()

        for element in event.removed:
            logger.debug("Unmapping element [%s] from diagram" % element)
            for component in canvas.components:
                if element == component.element:
                    canvas.remove(component)
                    canvas.request_redraw()
                    break


def _style_node(self, pydot_node, dot_attrs):
        """ Styles a node """

        pydot_node.set_shape(dot_attrs.shape)
        pydot_node.set_fixedsize(str(dot_attrs.fixed_size))
        pydot_node.set_width(str(dot_attrs.width))
        pydot_node.set_height(str(dot_attrs.height))
        pydot_node.set_color(rgba2hex(dot_attrs.color_))
        pydot_node.set_fillcolor(
            rgba2hex(dot_attrs.fill_color_)
        )
        for sty in dot_attrs.style:
            logger.debug("Setting node style: %s" % sty)
            pydot_node.set_style(sty)

        return pydot_node

def
_style_node
(
self
,
pydot_node
,
dot_attrs
)
:
pydot_node
.
set_shape
(
dot_attrs
.
shape
)
pydot_node
.
set_fixedsize
(
str
(
dot_attrs
.
fixed_size
)
)
pydot_node
.
set_width
(
str
(
dot_attrs
.
width
)
)
pydot_node
.
set_height
(
str
(
dot_attrs
.
height
)
)
pydot_node
.
set_color
(
rgba2hex
(
dot_attrs
.
color_
)
)
pydot_node
.
set_fillcolor
(
rgba2hex
(
dot_attrs
.
fill_color_
)
)
for
sty
in
dot_attrs
.
style
:
logger
.
debug
(
"Setting node style: %s"
%
sty
)
pydot_node
.
set_style
(
sty
)
return
pydot_node


def parse_xdot_data(self, data):
        """ Parses xdot data and returns the associated components. """

        parser = self.parser
#        if pyparsing_version >= "1.2":
#            parser.parseWithTabs()
        if data:
            return parser.parseString(data)
        else:
            return []

def parse_xdot_data ( self , data ) : parser = self . parser if data : return parser . parseString ( data ) else : return [ ]

Parses xdot data and returns the associated components .


def proc_font(self, tokens):
        """ Sets the font. """

        size = int(tokens["s"])
        self.pen.font = "%s %d" % (tokens["b"], size)
        return []

def
proc_font
(
self
,
tokens
)
:
size
=
int
(
tokens
[
"s"
]
)
self
.
pen
.
font
=
"%s %d"
%
(
tokens
[
"b"
]
,
size
)
return
[
]


def _proc_ellipse(self, tokens, filled):
        """ Returns the components of an ellipse. """

        component = Ellipse(pen=self.pen,
                            x_origin=tokens["x0"],
                            y_origin=tokens["y0"],
                            e_width=tokens["w"],
                            e_height=tokens["h"],
                            filled=filled)

        return component

def _proc_ellipse ( self , tokens , filled ) : component = Ellipse ( pen = self . pen , x_origin = tokens [ "x0" ] , y_origin = tokens [ "y0" ] , e_width = tokens [ "w" ] , e_height = tokens [ "h" ] , filled = filled ) return component


def _proc_polygon(self, tokens, filled):
        """ Returns the components of a polygon. """

        pts = [(p["x"], p["y"]) for p in tokens["points"]]
        component = Polygon(pen=self.pen, points=pts, filled=filled)

        return component

def _proc_polygon ( self , tokens , filled ) : pts = [ ( p [ "x" ] , p [ "y" ] ) for p in tokens [ "points" ] ] component = Polygon ( pen = self . pen , points = pts , filled = filled ) return component


def proc_polyline(self, tokens):
        """ Returns the components of a polyline. """

        pts = [(p["x"], p["y"]) for p in tokens["points"]]
        component = Polyline(pen=self.pen, points=pts)

        return component

def proc_polyline ( self , tokens ) : pts = [ ( p [ "x" ] , p [ "y" ] ) for p in tokens [ "points" ] ] component = Polyline ( pen = self . pen , points = pts ) return component


def proc_text(self, tokens):
        """ Returns text components. """

        component = Text(pen=self.pen,
                         text_x=tokens["x"],
                         text_y=tokens["y"],
                         justify=tokens["j"],
                         text_w=tokens["w"],
                         text=tokens["b"])

        return component

def proc_text ( self , tokens ) : component = Text ( pen = self . pen , text_x = tokens [ "x" ] , text_y = tokens [ "y" ] , justify = tokens [ "j" ] , text_w = tokens [ "w" ] , text = tokens [ "b" ] ) return component


def proc_image(self, tokens):
        """ Returns the components of an image. """

        print "IMAGE:", tokens, tokens.asList(), tokens.keys()

        raise NotImplementedError

def proc_image ( self , tokens ) : print "IMAGE:" , tokens , tokens . asList ( ) , tokens . keys ( ) raise NotImplementedError