<commit_before>#!/usr/bin/env python

'''
'''

__docformat__ = 'restructuredtext'
__version__ = '$Id: $'

import operator
import os
import sys
import zipfile
import StringIO

import pyglet

class ResourceNotFoundException(Exception):
    '''The named resource was not found on the search path.'''
    def __init__(self, name):
        message = ('Resource "%s" was not found on the path.  '
            'Ensure that the filename has the correct captialisation.') % name
        Exception.__init__(self, message)

def get_script_home():
    '''Get the directory containing the program entry module.

    For ordinary Python scripts, this is the directory containing the
    ``__main__`` module.  For executables created with py2exe the result is
    the directory containing the running executable file.  For OS X bundles
    created using Py2App the result is the Resources directory within the
    running bundle.

    If none of the above cases apply and the file for ``__main__`` cannot
    be determined the working directory is returned.

    :rtype: str
    '''

    frozen = getattr(sys, 'frozen', None)
    if frozen in ('windows_exe', 'console_exe'):
        return os.path.dirname(sys.executable)
    elif frozen == 'macosx_app':
        return os.environ['RESOURCEPATH']
    else:
        main = sys.modules['__main__']
        if hasattr(main, '__file__'):
            return os.path.dirname(main.__file__)

    # Probably interactive
    return ''

def get_settings_path(name):
    if sys.platform in ('cygwin', 'win32'):
        if 'APPDATA' in os.environ:
            return os.path.join(os.environ['APPDATA'], name)
        else:
            return os.path.expanduser('~/%s' % name)
    elif sys.platform == 'darwin':
        return os.path.expanduser('~/Library/Application Support/%s' % name)
    else:
        return os.path.expanduser('~/.%s' % name)

class Loader(object):
    '''Load program resource files from disk.

    The loader contains a search path which can include filesystem
    directories, ZIP archives and Python packages.

    :Ivariables:
        `path` : list of str
            List of search locations.  After modifying the path you must
            call the `reindex` method.
        `script_home` : str
            Base resource location, defaulting to the location of the
            application script.

    '''
    def __init__(self, path=None, script_home=None):
        '''Create a loader for the given path.

        The path is a list of locations to search for resources.  Locations
        are searched in the order given in the path.  If a location is not
        valid (for example, if the directory does not exist), it is skipped.

        Locations in the path beginning with an ampersand (''@'' symbol)
        specify Python packages.  Other locations specify a ZIP archive
        or directory on the filesystem.  Locations that are not absolute
        are assumed to be relative to the script home.

        Paths are always case-sensitive, even if the filesystem is not.  This
        avoids a common error when porting applications between platforms.

        If no path is specified it defaults to ``['.', '@__main__']``; that
        is, the program directory is searched first, followed by the package
        directory of the entry module.

        :Parameters:
            `path` : list of str
                List of locations to search for resources.

        '''
        if path is None:
            path = ['.', '@__main__']
        if type(path) in (str, unicode):
            path = [path]
        self.path = list(path)
        if script_home is None:
            script_home = get_script_home()
        self._script_home = script_home
        self.reindex()

        # Map name to image
        self._cached_textures = {}
        self._cached_images = {}

        # Map bin size to list of atlases
        self._texture_atlas_bins = {}

    def reindex(self):
        '''Refresh the file index.

        You must call this method if `path` is changed or the filesystem
        layout changes.
        '''
        self._index = {}
        for path in self.path:
            if path.startswith('@'):
                # Module
                name = path[1:]

                try:
                    module = __import__(name)
                except:
                    continue

                for component in name.split('.')[1:]:
                    module = getattr(module, component)

                if hasattr(module, '__file__'):
                    path = os.path.dirname(module.__file__)
                else:
                    path = '' # interactive
            elif not os.path.isabs(path):
                # Add script base unless absolute
                assert '\\' not in path, \
                    'Backslashes not permitted in relative path'
                path = os.path.join(self._script_home, path)

            if os.path.isdir(path):
                # Filesystem directory
                for name in os.listdir(path):
                    self._index_file(name, open, os.path.join(path, name))
            else:
                # Find path component that is the ZIP file.
                dir = ''
                while path and not os.path.isfile(path):
                    path, tail_dir = os.path.split(path)
                    dir = '/'.join((tail_dir, dir))
                dir = dir.rstrip('/')

                # path is a ZIP file, dir resides within ZIP
                if path and zipfile.is_zipfile(path):
                    zip = zipfile.ZipFile(path, 'r')
                    zip_open = (lambda z: lambda name, mode:
                        StringIO.StringIO(z.read(name)))(zip)
                    for name_path in zip.namelist():
                        name_dir, name = os.path.split(name_path)
                        assert '\\' not in name_dir
                        assert not name_dir.endswith('/')
                        if name_dir == dir:
                            self._index_file(name, zip_open, name_path)

    def _index_file(self, name, func, path):
        if name not in self._index:
            self._index[name] = (func, path)

    def file(self, name, mode='rb'):
        '''Load a resource.

        :Parameters:
            `name` : str
                Filename of the resource to load.
            `mode` : str
                Combination of ``r``, ``w``, ``a``, ``b`` and ``t`` characters
                with the meaning as for the builtin ``open`` function.

        :rtype: file object
        '''
        try:
            func, path = self._index[name]
            return func(path, mode)
        except KeyError:
            raise ResourceNotFoundException(name)

    def add_font(self, name):
        '''Add a font resource to the application.

        Fonts not installed on the system must be added to pyglet before they
        can be used with `font.load`.  Although the font is added with
        its filename using this function, it is loaded by specifying its
        family name.  For example::

            resource.add_font('action_man.ttf')
            action_man = font.load('Action Man')

        :Parameters:
            `name` : str
                Filename of the font resource to add.

        '''
        from pyglet import font
        file = self.file(name)
        font.add_file(file)

    def _alloc_image(self, name):
        file = self.file(name)
        img = pyglet.image.load(name, file=file)
        bin = self._get_texture_atlas_bin(img.width, img.height)
        if bin is None:
            return img.get_texture(True)

        return bin.add(img)

    def _get_texture_atlas_bin(self, width, height):
        '''A heuristic for determining the atlas bin to use for a given image
        size.  Returns None if the image should not be placed in an atlas (too
        big), otherwise the bin (a list of TextureAtlas).
        '''
        # Large images are not placed in an atlas
        if width > 128 or height > 128:
            return None

        # Group images with small height separately to larger height (as the
        # allocator can't stack within a single row).
        bin_size = 1
        if height > 32:
            bin_size = 2

        try:
            bin = self._texture_atlas_bins[bin_size]
        except KeyError:
            bin = self._texture_atlas_bins[bin_size] = \
                pyglet.image.atlas.TextureBin()

        return bin

    def image(self, name, flip_x=False, flip_y=False, rotate=0):
        '''
        '''
        if name in self._cached_images:
            identity = self._cached_images[name]
        else:
            identity = self._cached_images[name] = self._alloc_image(name)

        if not rotate and not flip_x and not flip_y:
            return identity

        return identity.get_transform(flip_x, flip_y, rotate)

    def get_cached_image_names(self):
        return self._cached_images.keys()

    def get_texture_atlases(self):
        return reduce(operator.add, self._texture_atlas_bins.values())

    def get_texture_atlas_usage(self):
        usage = 0.0
        count = 0
        for bin in self._texture_atlas_bins:
            for atlas in bin.atlases:
                usage += atlas.allocator.get_usage()
                count += 1
        return usage / count

    def get_texture_atlas_fragmentation(self):
        fragmentation = 0.0
        count = 0
        for bin in self._texture_atlas_bins:
            for atlas in bin.atlases:
                usage += atlas.allocator.get_fragmentation()
                count += 1
        return fragmentation / count

    def media(self, name, streaming=True):
        '''Load a sound or video resource.

        The meaning of `streaming` is as for `media.load`.  Compressed
        sources cannot be streamed (that is, video and compressed audio
        cannot be streamed from a ZIP archive).

        :Parameters:
            `name` : str
                Filename of the media source to load.
            `streaming` : bool
                True if the source should be streamed from disk, False if
                it should be entirely decoded into memory immediately.

        :rtype: `media.Source`
        '''
        from pyglet import media
        try:
            func, path = self._index[name]
            if func is open:
                return media.load(path, streaming=streaming)
            else:
                return media.load(name, file=file, streaming=streaming)
        except KeyError:
            raise ResourceNotFoundException(name)

    def texture(self, name):
        '''Load a texture.

        The named image will be loaded as a single OpenGL texture.  If the
        dimensions of the image are not powers of 2 a `TextureRegion` will
        be returned.

        :Parameters:
            `name` : str
                Filename of the image resource to load.

        :rtype: `Texture`
        '''
        if name in self._cached_textures:
            return self._cached_textures[name]

        file = self.file(name)
        texture = pyglet.image.load(name, file=file).get_texture()
        self._cached_textures[name] = texture
        return texture

    def get_cached_texture_names(self):
        '''Get the names of textures currently cached.

        :rtype: list of str
        '''
        return self._cached_textures.keys()

#: Default resource search path.
#:
#: Locations in the search path are searched in order and are always
#: case-sensitive.  After changing the path you must call `reindex`.
#:
#: :type: list of str
path = []

class _DefaultLoader(Loader):
    def _get_path(self):
        return path

    def _set_path(self, value):
        global path
        path = value

    path = property(_get_path, _set_path)

_default_loader = _DefaultLoader()
reindex = _default_loader.reindex
file = _default_loader.file
add_font = _default_loader.add_font
image = _default_loader.image
get_cached_image_names = _default_loader.get_cached_image_names
get_texture_atlases = _default_loader.get_texture_atlases
get_texture_atlas_usage = _default_loader.get_texture_atlas_usage
get_texture_atlas_fragmentation = \
    _default_loader.get_texture_atlas_fragmentation
media = _default_loader.media
texture = _default_loader.texture
get_cached_texture_names = _default_loader.get_cached_texture_names
<commit_msg>Remove some (now invalid) resource debug methods, replace get_texture_atlases with get_texture_bins.<commit_after>#!/usr/bin/env python

'''
'''

__docformat__ = 'restructuredtext'
__version__ = '$Id: $'

import operator
import os
import sys
import zipfile
import StringIO

import pyglet

class ResourceNotFoundException(Exception):
    '''The named resource was not found on the search path.'''
    def __init__(self, name):
        message = ('Resource "%s" was not found on the path.  '
            'Ensure that the filename has the correct captialisation.') % name
        Exception.__init__(self, message)

def get_script_home():
    '''Get the directory containing the program entry module.

    For ordinary Python scripts, this is the directory containing the
    ``__main__`` module.  For executables created with py2exe the result is
    the directory containing the running executable file.  For OS X bundles
    created using Py2App the result is the Resources directory within the
    running bundle.

    If none of the above cases apply and the file for ``__main__`` cannot
    be determined the working directory is returned.

    :rtype: str
    '''

    frozen = getattr(sys, 'frozen', None)
    if frozen in ('windows_exe', 'console_exe'):
        return os.path.dirname(sys.executable)
    elif frozen == 'macosx_app':
        return os.environ['RESOURCEPATH']
    else:
        main = sys.modules['__main__']
        if hasattr(main, '__file__'):
            return os.path.dirname(main.__file__)

    # Probably interactive
    return ''

def get_settings_path(name):
    if sys.platform in ('cygwin', 'win32'):
        if 'APPDATA' in os.environ:
            return os.path.join(os.environ['APPDATA'], name)
        else:
            return os.path.expanduser('~/%s' % name)
    elif sys.platform == 'darwin':
        return os.path.expanduser('~/Library/Application Support/%s' % name)
    else:
        return os.path.expanduser('~/.%s' % name)

class Loader(object):
    '''Load program resource files from disk.

    The loader contains a search path which can include filesystem
    directories, ZIP archives and Python packages.

    :Ivariables:
        `path` : list of str
            List of search locations.  After modifying the path you must
            call the `reindex` method.
        `script_home` : str
            Base resource location, defaulting to the location of the
            application script.

    '''
    def __init__(self, path=None, script_home=None):
        '''Create a loader for the given path.

        The path is a list of locations to search for resources.  Locations
        are searched in the order given in the path.  If a location is not
        valid (for example, if the directory does not exist), it is skipped.

        Locations in the path beginning with an ampersand (''@'' symbol)
        specify Python packages.  Other locations specify a ZIP archive
        or directory on the filesystem.  Locations that are not absolute
        are assumed to be relative to the script home.

        Paths are always case-sensitive, even if the filesystem is not.  This
        avoids a common error when porting applications between platforms.

        If no path is specified it defaults to ``['.', '@__main__']``; that
        is, the program directory is searched first, followed by the package
        directory of the entry module.

        :Parameters:
            `path` : list of str
                List of locations to search for resources.

        '''
        if path is None:
            path = ['.', '@__main__']
        if type(path) in (str, unicode):
            path = [path]
        self.path = list(path)
        if script_home is None:
            script_home = get_script_home()
        self._script_home = script_home
        self.reindex()

        # Map name to image
        self._cached_textures = {}
        self._cached_images = {}

        # Map bin size to list of atlases
        self._texture_atlas_bins = {}

    def reindex(self):
        '''Refresh the file index.

        You must call this method if `path` is changed or the filesystem
        layout changes.
        '''
        self._index = {}
        for path in self.path:
            if path.startswith('@'):
                # Module
                name = path[1:]

                try:
                    module = __import__(name)
                except:
                    continue

                for component in name.split('.')[1:]:
                    module = getattr(module, component)

                if hasattr(module, '__file__'):
                    path = os.path.dirname(module.__file__)
                else:
                    path = '' # interactive
            elif not os.path.isabs(path):
                # Add script base unless absolute
                assert '\\' not in path, \
                    'Backslashes not permitted in relative path'
                path = os.path.join(self._script_home, path)

            if os.path.isdir(path):
                # Filesystem directory
                for name in os.listdir(path):
                    self._index_file(name, open, os.path.join(path, name))
            else:
                # Find path component that is the ZIP file.
                dir = ''
                while path and not os.path.isfile(path):
                    path, tail_dir = os.path.split(path)
                    dir = '/'.join((tail_dir, dir))
                dir = dir.rstrip('/')

                # path is a ZIP file, dir resides within ZIP
                if path and zipfile.is_zipfile(path):
                    zip = zipfile.ZipFile(path, 'r')
                    zip_open = (lambda z: lambda name, mode:
                        StringIO.StringIO(z.read(name)))(zip)
                    for name_path in zip.namelist():
                        name_dir, name = os.path.split(name_path)
                        assert '\\' not in name_dir
                        assert not name_dir.endswith('/')
                        if name_dir == dir:
                            self._index_file(name, zip_open, name_path)

    def _index_file(self, name, func, path):
        if name not in self._index:
            self._index[name] = (func, path)

    def file(self, name, mode='rb'):
        '''Load a resource.

        :Parameters:
            `name` : str
                Filename of the resource to load.
            `mode` : str
                Combination of ``r``, ``w``, ``a``, ``b`` and ``t`` characters
                with the meaning as for the builtin ``open`` function.

        :rtype: file object
        '''
        try:
            func, path = self._index[name]
            return func(path, mode)
        except KeyError:
            raise ResourceNotFoundException(name)

    def add_font(self, name):
        '''Add a font resource to the application.

        Fonts not installed on the system must be added to pyglet before they
        can be used with `font.load`.  Although the font is added with
        its filename using this function, it is loaded by specifying its
        family name.  For example::

            resource.add_font('action_man.ttf')
            action_man = font.load('Action Man')

        :Parameters:
            `name` : str
                Filename of the font resource to add.

        '''
        from pyglet import font
        file = self.file(name)
        font.add_file(file)

    def _alloc_image(self, name):
        file = self.file(name)
        img = pyglet.image.load(name, file=file)
        bin = self._get_texture_atlas_bin(img.width, img.height)
        if bin is None:
            return img.get_texture(True)

        return bin.add(img)

    def _get_texture_atlas_bin(self, width, height):
        '''A heuristic for determining the atlas bin to use for a given image
        size.  Returns None if the image should not be placed in an atlas (too
        big), otherwise the bin (a list of TextureAtlas).
        '''
        # Large images are not placed in an atlas
        if width > 128 or height > 128:
            return None

        # Group images with small height separately to larger height (as the
        # allocator can't stack within a single row).
        bin_size = 1
        if height > 32:
            bin_size = 2

        try:
            bin = self._texture_atlas_bins[bin_size]
        except KeyError:
            bin = self._texture_atlas_bins[bin_size] = \
                pyglet.image.atlas.TextureBin()

        return bin

    def image(self, name, flip_x=False, flip_y=False, rotate=0):
        '''
        '''
        if name in self._cached_images:
            identity = self._cached_images[name]
        else:
            identity = self._cached_images[name] = self._alloc_image(name)

        if not rotate and not flip_x and not flip_y:
            return identity

        return identity.get_transform(flip_x, flip_y, rotate)

    def get_cached_image_names(self):
        '''Get a list of image filenames that have been cached.

        This is useful for debugging and profiling only.

        :rtype: list
        :return: List of str
        '''
        return self._cached_images.keys()

    def get_texture_bins(self):
        '''Get a list of texture bins in use.

        This is useful for debugging and profiling only.

        :rtype: list
        :return: List of `TextureBin`
        '''
        return self._texture_atlas_bins.values()

    def media(self, name, streaming=True):
        '''Load a sound or video resource.

        The meaning of `streaming` is as for `media.load`.  Compressed
        sources cannot be streamed (that is, video and compressed audio
        cannot be streamed from a ZIP archive).

        :Parameters:
            `name` : str
                Filename of the media source to load.
            `streaming` : bool
                True if the source should be streamed from disk, False if
                it should be entirely decoded into memory immediately.

        :rtype: `media.Source`
        '''
        from pyglet import media
        try:
            func, path = self._index[name]
            if func is open:
                return media.load(path, streaming=streaming)
            else:
                return media.load(name, file=file, streaming=streaming)
        except KeyError:
            raise ResourceNotFoundException(name)

    def texture(self, name):
        '''Load a texture.

        The named image will be loaded as a single OpenGL texture.  If the
        dimensions of the image are not powers of 2 a `TextureRegion` will
        be returned.

        :Parameters:
            `name` : str
                Filename of the image resource to load.

        :rtype: `Texture`
        '''
        if name in self._cached_textures:
            return self._cached_textures[name]

        file = self.file(name)
        texture = pyglet.image.load(name, file=file).get_texture()
        self._cached_textures[name] = texture
        return texture

    def get_cached_texture_names(self):
        '''Get the names of textures currently cached.

        :rtype: list of str
        '''
        return self._cached_textures.keys()

#: Default resource search path.
#:
#: Locations in the search path are searched in order and are always
#: case-sensitive.  After changing the path you must call `reindex`.
#:
#: :type: list of str
path = []

class _DefaultLoader(Loader):
    def _get_path(self):
        return path

    def _set_path(self, value):
        global path
        path = value

    path = property(_get_path, _set_path)

_default_loader = _DefaultLoader()
reindex = _default_loader.reindex
file = _default_loader.file
add_font = _default_loader.add_font
image = _default_loader.image
get_cached_image_names = _default_loader.get_cached_image_names
get_texture_bins = _default_loader.get_texture_bins
media = _default_loader.media
texture = _default_loader.texture
get_cached_texture_names = _default_loader.get_cached_texture_names
<|endoftext|>


<commit_before>#!/usr/bin/env python

# Copyright 2015 University of Chicago
# Available under Apache 2.0 License

from distutils.core import setup

setup(name='fsurf',
      version='0.6.0',
      description='Command line tool to submit freesurfer workflows',
      author='Suchandra Thapa',
      author_email='sthapa@ci.uchicago.edu',
      url='https://github.com/OSGConnect/freesurfer_workflow',
      packages=['fsurfer'],
      scripts=['fsurf', 'fsurf-config'],
      data_files=[('/usr/share/fsurfer/scripts', ["bash/autorecon1.sh",
                                                  "bash/autorecon2.sh",
                                                  "bash/autorecon2-whole.sh",
                                                  "bash/autorecon3.sh",
                                                  "bash/autorecon-all.sh"])],
      license='Apache 2.0')
<commit_msg>Update package version<commit_after>#!/usr/bin/env python

# Copyright 2015 University of Chicago
# Available under Apache 2.0 License

from distutils.core import setup

setup(name='fsurf',
      version='0.6.1',
      description='Command line tool to submit freesurfer workflows',
      author='Suchandra Thapa',
      author_email='sthapa@ci.uchicago.edu',
      url='https://github.com/OSGConnect/freesurfer_workflow',
      packages=['fsurfer'],
      scripts=['fsurf', 'fsurf-config'],
      data_files=[('/usr/share/fsurfer/scripts', ["bash/autorecon1.sh",
                                                  "bash/autorecon2.sh",
                                                  "bash/autorecon2-whole.sh",
                                                  "bash/autorecon3.sh",
                                                  "bash/autorecon-all.sh"])],
      license='Apache 2.0')
<|endoftext|>


<commit_before># -*- coding: UTF-8 -*-
# Copyright (C) 2009 Itaapy, ArsAperta, Pierlis, Talend

# Import from lpod
from element import register_element_class, odf_create_element, odf_element
from paragraph import odf_create_paragraph
from utils import _get_style_tagname, _expand_properties, _merge_dicts

def odf_create_style(family, name=None, display_name=None, parent=None,
                     area=None, **kw):
    """Create a style of the given family. The name is not mandatory at this
    point but will become required when inserting in a document as a common
    style.

    The display name is the name the user sees in an office application.

    The parent is the name of the style this style will inherit from.

    To set properties, pass them as keyword arguments. The area properties
    apply to is optional and defaults to the family.

    Arguments:

        family -- 'paragraph', 'text', 'section', 'table', 'tablecolumn',
                  'table-row', 'table-cell', 'table-page', 'chart',
                  'drawing-page', 'graphic', 'presentation',
                  'control', 'ruby', 'list', 'number', 'page-layout' or
                  'master-page'

        name -- unicode

        display_name -- unicode

        parent -- unicode

        area -- str

    Return: odf_style
    """
    tagname, famattr = _get_style_tagname(family)
    element = odf_create_element('<%s/>' % tagname)
    if name:
        element.set_style_name(name)
    if famattr:
        element.set_attribute('style:family', famattr)
    if display_name:
        element.set_attribute('style:display-name', display_name)
    if parent:
        element.set_attribute('style:parent-style-name', parent)
    if kw:
        if area is None:
            area = family
        element.set_style_properties(kw, area=area)
    return element

class odf_style(odf_element):
    """Specialised element for styles, yet generic to all style types.
    """
    def get_style_name(self):
        return self.get_attribute('style:name')

    def set_style_name(self, name):
        self.set_attribute('style:name', name)

    def get_style_family(self):
        return self.get_attribute('style:family')

    def set_style_family(self, family):
        self.set_attribute('style:family', family)

    def get_parent_style_name(self):
        """Will only return a name, not an object, because we don't have
        access to the XML part from here.

        See odf_styles.get_parent_style
        """
        return self.get_attribute('style:parent-style-name')

    def set_parent_style_name(self, name):
        self.set_attribute('style:parent-style-name', name)

    def get_style_properties(self, area=None):
        """Get the mapping of all properties of this style. By default the
        properties of the same family, e.g. a paragraph style and its
        paragraph properties. Specify the area to get the text properties of
        a paragraph style for example.
        Arguments:

            area -- str

        Return: dict
        """
        if area is None:
            area = self.get_attribute('style:family')
        element = self.get_element('style:%s-properties' % area)
        if element is None:
            return None
        properties = element.get_attributes()
        # Nested properties are nested dictionaries
        for child in element.get_children():
            properties[child.get_name()] = child.get_attributes()
        return properties

    def set_style_properties(self, properties={}, area=None, **kw):
        """Set the properties of the "area" type of this style. Properties
        are given either as a dict or as named arguments (or both). The area
        is identical to the style family by default. If the properties
        element is missing, it is created.
        Arguments:

            properties -- dict
            area -- str
        """
        if area is None:
            area = self.get_attribute('style:family')
        element = self.get_element('style:%s-properties' % area)
        if element is None:
            element = odf_create_element('<style:%s-properties/>' % area)
            self.append_element(element)
        properties = _expand_properties(_merge_dicts(properties, kw))
        for key, value in properties.iteritems():
            if value is None:
                element.del_attribute(key)
            else:
                element.set_attribute(key, value)

    def del_style_properties(self, properties=[], area=None, *args):
        """Delete the given properties, either by list argument or
        positional argument (or both). Remove only from the given area,
        identical to the style family by default.
        Arguments:

            properties -- list
            area -- str
        """
        if area is None:
            area = self.get_attribute('style:family')
        element = self.get_element('style:%s-properties' % area)
        if element is None:
            raise ValueError, "properties element is inexistent"
        for key in _expand_properties(properties):
            element.del_attribute(key)

class odf_page_layout(odf_style):
    """Phyisical presentation of a page.

    XXX to verify
    """
    def get_header_style(self):
        return self.get_element('style:header-style')

    def set_header_style(self, new_style):
        header_style = self.get_header_style()
        if header_style is not None:
            self.delete(header_style)
        self.append_element(new_style)

    def get_footer_style(self):
        return self.get_element('style:footer-style')

    def set_footer_style(self, new_style):
        footer_style = self.get_footer_style()
        if footer_style is not None:
            self.delete(footer_style)
        self.append_element(new_style)

class odf_master_page(odf_style):
    """A master page is the style of a page.

    Phyisical presentation is in the associated page layout.

    XXX to verify
    """
    def __set_header_or_footer(self, text_or_element, name='header',
                               style=u"Header"):
        if name == 'header':
            header_or_footer = self.get_header()
        else:
            header_or_footer = self.get_footer()
        if header_or_footer is None:
            header_or_footer = odf_create_element('<style:%s/>' % name)
            self.append_element(header_or_footer)
        else:
            header_or_footer.clear()
        if not isinstance(text_or_element, (list, tuple)):
            # Already a header or footer?
            if (isinstance(text_or_element, odf_element)
                    and text_or_element.get_name() == 'style:%s' % name):
                self.delete(header_or_footer)
                self.append_element(text_or_element)
                return
            text_or_element = [text_or_element]
        for item in text_or_element:
            if type(item) is unicode:
                paragraph = odf_create_paragraph(item, style=style)
                header_or_footer.append_element(paragraph)
            elif isinstance(item, odf_element):
                header_or_footer.append_element(item)

    #
    # Public API
    #

    def get_page_layout_name(self):
        return self.get_attribute('style:page-layout-name')

    def set_page_layout_name(self, name):
        self.set_attribute('style:page-layout-name', name)

    def get_header(self):
        """Get the element that contains the header contents.

        If None, no header was set.
        """
        return self.get_element('style:header')

    def set_header(self, text_or_element):
        """Create or replace the header by the given content. It can already
        be a complete header.

        If you only want to update the existing header, get it and use the
        API.

        Arguments:

            text_or_element -- unicode or odf_element or a list of them
        """
        return self.__set_header_or_footer(text_or_element)

    def get_footer(self):
        """Get the element that contains the footer contents.

        If None, no footer was set.
        """
        return self.get_element('style:footer')

    def set_footer(self, text_or_element):
        """Create or replace the footer by the given content. It can already
        be a complete footer.

        If you only want to update the existing footer, get it and use the
        API.

        Arguments:

            text_or_element -- unicode or odf_element or a list of them
        """
        return self.__set_header_or_footer(text_or_element, name='footer',
                                           style=u"Footer")

# FIXME there are (many) more
for name in ('style:style', 'style:default-style', 'style:header-style',
             'style:footer-style'):
    register_element_class(name, odf_style)
register_element_class('style:page-layout', odf_page_layout)
register_element_class('style:master-page', odf_master_page)
<commit_msg>python: support setting style properties from another one<commit_after># -*- coding: UTF-8 -*-
# Copyright (C) 2009 Itaapy, ArsAperta, Pierlis, Talend

# Import from lpod
from element import register_element_class, odf_create_element, odf_element
from paragraph import odf_create_paragraph
from utils import _get_style_tagname, _expand_properties, _merge_dicts

def odf_create_style(family, name=None, display_name=None, parent=None,
                     area=None, **kw):
    """Create a style of the given family. The name is not mandatory at this
    point but will become required when inserting in a document as a common
    style.

    The display name is the name the user sees in an office application.

    The parent is the name of the style this style will inherit from.

    To set properties, pass them as keyword arguments. The area properties
    apply to is optional and defaults to the family.

    Arguments:

        family -- 'paragraph', 'text', 'section', 'table', 'tablecolumn',
                  'table-row', 'table-cell', 'table-page', 'chart',
                  'drawing-page', 'graphic', 'presentation',
                  'control', 'ruby', 'list', 'number', 'page-layout' or
                  'master-page'

        name -- unicode

        display_name -- unicode

        parent -- unicode

        area -- str

    Return: odf_style
    """
    tagname, famattr = _get_style_tagname(family)
    element = odf_create_element('<%s/>' % tagname)
    if name:
        element.set_style_name(name)
    if famattr:
        element.set_attribute('style:family', famattr)
    if display_name:
        element.set_attribute('style:display-name', display_name)
    if parent:
        element.set_attribute('style:parent-style-name', parent)
    if kw:
        if area is None:
            area = family
        element.set_style_properties(kw, area=area)
    return element

class odf_style(odf_element):
    """Specialised element for styles, yet generic to all style types.
    """
    def get_style_name(self):
        return self.get_attribute('style:name')

    def set_style_name(self, name):
        self.set_attribute('style:name', name)

    def get_style_family(self):
        return self.get_attribute('style:family')

    def set_style_family(self, family):
        self.set_attribute('style:family', family)

    def get_parent_style_name(self):
        """Will only return a name, not an object, because we don't have
        access to the XML part from here.

        See odf_styles.get_parent_style
        """
        return self.get_attribute('style:parent-style-name')

    def set_parent_style_name(self, name):
        self.set_attribute('style:parent-style-name', name)

    def get_style_properties(self, area=None):
        """Get the mapping of all properties of this style. By default the
        properties of the same family, e.g. a paragraph style and its
        paragraph properties. Specify the area to get the text properties of
        a paragraph style for example.
        Arguments:

            area -- str

        Return: dict
        """
        if area is None:
            area = self.get_attribute('style:family')
        element = self.get_element('style:%s-properties' % area)
        if element is None:
            return None
        properties = element.get_attributes()
        # Nested properties are nested dictionaries
        for child in element.get_children():
            properties[child.get_name()] = child.get_attributes()
        return properties

    def set_style_properties(self, properties={}, style=None, area=None, **kw):
        """Set the properties of the "area" type of this style. Properties
        are given either as a dict or as named arguments (or both). The area
        is identical to the style family by default. If the properties
        element is missing, it is created.

        Instead of properties, you can pass a style with properties of the
        same area. These will be copied.

        Arguments:

            properties -- dict

            style -- odf_style

            area -- 'paragraph', 'text'...
        """
        if area is None:
            area = self.get_attribute('style:family')
        element = self.get_element('style:%s-properties' % area)
        if element is None:
            element = odf_create_element('<style:%s-properties/>' % area)
            self.append_element(element)
        if properties:
            properties = _expand_properties(_merge_dicts(properties, kw))
        elif style is not None:
            properties = style.get_style_properties(area=area)
            if properties is None:
                return
        for key, value in properties.iteritems():
            if value is None:
                element.del_attribute(key)
            else:
                element.set_attribute(key, value)

    def del_style_properties(self, properties=[], area=None, *args):
        """Delete the given properties, either by list argument or
        positional argument (or both). Remove only from the given area,
        identical to the style family by default.
        Arguments:

            properties -- list
            area -- str
        """
        if area is None:
            area = self.get_attribute('style:family')
        element = self.get_element('style:%s-properties' % area)
        if element is None:
            raise ValueError, "properties element is inexistent"
        for key in _expand_properties(properties):
            element.del_attribute(key)

class odf_page_layout(odf_style):
    """Phyisical presentation of a page.

    XXX to verify
    """
    def get_header_style(self):
        return self.get_element('style:header-style')

    def set_header_style(self, new_style):
        header_style = self.get_header_style()
        if header_style is not None:
            self.delete(header_style)
        self.append_element(new_style)

    def get_footer_style(self):
        return self.get_element('style:footer-style')

    def set_footer_style(self, new_style):
        footer_style = self.get_footer_style()
        if footer_style is not None:
            self.delete(footer_style)
        self.append_element(new_style)

class odf_master_page(odf_style):
    """A master page is the style of a page.

    Phyisical presentation is in the associated page layout.

    XXX to verify
    """
    def __set_header_or_footer(self, text_or_element, name='header',
                               style=u"Header"):
        if name == 'header':
            header_or_footer = self.get_header()
        else:
            header_or_footer = self.get_footer()
        if header_or_footer is None:
            header_or_footer = odf_create_element('<style:%s/>' % name)
            self.append_element(header_or_footer)
        else:
            header_or_footer.clear()
        if not isinstance(text_or_element, (list, tuple)):
            # Already a header or footer?
            if (isinstance(text_or_element, odf_element)
                    and text_or_element.get_name() == 'style:%s' % name):
                self.delete(header_or_footer)
                self.append_element(text_or_element)
                return
            text_or_element = [text_or_element]
        for item in text_or_element:
            if type(item) is unicode:
                paragraph = odf_create_paragraph(item, style=style)
                header_or_footer.append_element(paragraph)
            elif isinstance(item, odf_element):
                header_or_footer.append_element(item)

    #
    # Public API
    #

    def get_page_layout_name(self):
        return self.get_attribute('style:page-layout-name')

    def set_page_layout_name(self, name):
        self.set_attribute('style:page-layout-name', name)

    def get_header(self):
        """Get the element that contains the header contents.

        If None, no header was set.
        """
        return self.get_element('style:header')

    def set_header(self, text_or_element):
        """Create or replace the header by the given content. It can already
        be a complete header.

        If you only want to update the existing header, get it and use the
        API.

        Arguments:

            text_or_element -- unicode or odf_element or a list of them
        """
        return self.__set_header_or_footer(text_or_element)

    def get_footer(self):
        """Get the element that contains the footer contents.

        If None, no footer was set.
        """
        return self.get_element('style:footer')

    def set_footer(self, text_or_element):
        """Create or replace the footer by the given content. It can already
        be a complete footer.

        If you only want to update the existing footer, get it and use the
        API.

        Arguments:

            text_or_element -- unicode or odf_element or a list of them
        """
        return self.__set_header_or_footer(text_or_element, name='footer',
                                           style=u"Footer")

# FIXME there are (many) more
for name in ('style:style', 'style:default-style', 'style:header-style',
             'style:footer-style'):
    register_element_class(name, odf_style)
register_element_class('style:page-layout', odf_page_layout)
register_element_class('style:master-page', odf_master_page)
<|endoftext|>


<commit_before># Import the PCA9685 module.
import Adafruit_PCA9685
import time

 # ===========================================================================
 # Simple routine to make K9's tail wag up and down
 # ===========================================================================
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)		# set frequency to 60 Hz

pwm.set_pwm(5, 0, 350)	# tail centre horizontally

count= 0
while count < 4:
    pwm.set_pwm(4, 0, 370)	# tail up
    time.sleep(0.25)
    pwm.set_pwm(4, 0, 270)	# tail down
    time.sleep(0.25)
    count +=1
pwm.set_pwm(4, 0, 350)	# tail centre
<commit_msg>Update wag_v.py<commit_after># ===========================================================================
# Simple routine to make K9's tail wag up and down
# ===========================================================================
# Import the PCA9685 module.
import time
import board
import busio
import adafruit_pca9685
i2c = busio.I2C(board.SCL, board.SDA)
pca = adafruit_pca9685.PCA9685(i2c)
pca.frequency = 60

pca.channels[5].duty_cycle = 5601	# tail left
# pwm.set_pwm(5, 0, 350)	# tail centre horizontally

count= 0
while count < 4:
    pca.channels[4].duty_cycle = 5921	# tail left
    # pwm.set_pwm(4, 0, 370)	# tail up
    time.sleep(0.25)
    pca.channels[4].duty_cycle = 4321	# tail left
    # pwm.set_pwm(4, 0, 270)	# tail down
    time.sleep(0.25)
    count +=1
pca.channels[4].duty_cycle = 5601	# tail left
# pwm.set_pwm(4, 0, 350)	# tail centre

# 270 -> 4321
# 320 -> 5121
# 325 -> 5201
# 350 -> 5601
# 370 -> 5921
# 440 -> 7042<|endoftext|>


<commit_before>"""
Tests for django.core.servers.
"""

import os

import django
from django.test import TestCase
from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.basehttp import AdminMediaHandler

class AdminMediaHandlerTests(TestCase):

    def setUp(self):
        self.admin_media_file_path = \
            os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
        self.handler = AdminMediaHandler(WSGIHandler())

    def test_media_urls(self):
        """
        Tests that URLs that look like absolute file paths after the
        settings.ADMIN_MEDIA_PREFIX don't turn into absolute file paths.
        """
        # Cases that should work on all platforms.
        data = (
            ('/media/css/base.css', ('css', 'base.css')),
        )
        # Cases that should raise an exception.
        bad_data = ()

        # Add platform-specific cases.
        if os.sep == '/':
            data += (
                # URL, tuple of relative path parts.
                ('/media/\\css/base.css', ('\\css', 'base.css')),
            )
            bad_data += (
                '/media//css/base.css',
                '/media////css/base.css',
                '/media/../css/base.css',
            )
        elif os.sep == '\\':
            bad_data += (
                '/media/C:\css/base.css',
                '/media//\\css/base.css',
                '/media/\\css/base.css',
                '/media/\\\\css/base.css'
            )
        for url, path_tuple in data:
            try:
                output = self.handler.file_path(url)
            except ValueError:
                self.fail("Got a ValueError exception, but wasn't expecting"
                          " one. URL was: %s" % url)
            rel_path = os.path.join(*path_tuple)
            desired = os.path.normcase(
                os.path.join(self.admin_media_file_path, rel_path))
            self.assertEqual(output, desired,
                "Got: %s, Expected: %s, URL was: %s" % (output, desired, url))
        for url in bad_data:
            try:
                output = self.handler.file_path(url)
            except ValueError:
                continue
            self.fail('URL: %s should have caused a ValueError exception.'
                      % url)
<commit_msg>Fixed #14271 -- Use absolute path for admin media tests. Thanks, Alex Gaynor.<commit_after>"""
Tests for django.core.servers.
"""

import os

import django
from django.test import TestCase
from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.basehttp import AdminMediaHandler

class AdminMediaHandlerTests(TestCase):

    def setUp(self):
        self.admin_media_file_path = os.path.abspath(
            os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
        )
        self.handler = AdminMediaHandler(WSGIHandler())

    def test_media_urls(self):
        """
        Tests that URLs that look like absolute file paths after the
        settings.ADMIN_MEDIA_PREFIX don't turn into absolute file paths.
        """
        # Cases that should work on all platforms.
        data = (
            ('/media/css/base.css', ('css', 'base.css')),
        )
        # Cases that should raise an exception.
        bad_data = ()

        # Add platform-specific cases.
        if os.sep == '/':
            data += (
                # URL, tuple of relative path parts.
                ('/media/\\css/base.css', ('\\css', 'base.css')),
            )
            bad_data += (
                '/media//css/base.css',
                '/media////css/base.css',
                '/media/../css/base.css',
            )
        elif os.sep == '\\':
            bad_data += (
                '/media/C:\css/base.css',
                '/media//\\css/base.css',
                '/media/\\css/base.css',
                '/media/\\\\css/base.css'
            )
        for url, path_tuple in data:
            try:
                output = self.handler.file_path(url)
            except ValueError:
                self.fail("Got a ValueError exception, but wasn't expecting"
                          " one. URL was: %s" % url)
            rel_path = os.path.join(*path_tuple)
            desired = os.path.normcase(
                os.path.join(self.admin_media_file_path, rel_path))
            self.assertEqual(output, desired,
                "Got: %s, Expected: %s, URL was: %s" % (output, desired, url))
        for url in bad_data:
            try:
                output = self.handler.file_path(url)
            except ValueError:
                continue
            self.fail('URL: %s should have caused a ValueError exception.'
                      % url)
<|endoftext|>


<commit_before>"""
Tests for the Finances API class.
"""
import unittest
import datetime
import mws
from .utils import CommonRequestTestTools

class FinancesTestCase(unittest.TestCase, CommonRequestTestTools):
    """
    Test cases for Finances.
    """
    # TODO: Add remaining methods for Finances
    def setUp(self):
        self.api = mws.Finances(
            self.CREDENTIAL_ACCESS,
            self.CREDENTIAL_SECRET,
            self.CREDENTIAL_ACCOUNT,
            auth_token=self.CREDENTIAL_TOKEN
        )
        self.api._test_request_params = True

    def test_list_financial_event_groups(self):
        """
        ListFinancialEventGroups operation.
        """
        created_after = datetime.datetime.utcnow()
        created_after_stamp = created_after.iso_format()
        created_before = datetime.datetime.utcnow()
        created_before_stamp = created_before.iso_format()
        max_results = 659
        params = self.api.list_financial_event_groups(
            created_after=created_after,
            created_before=created_before,
            max_results=max_results,
        )
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventGroups'
        assert params['FinancialEventGroupStartedAfter'] == created_after_stamp
        assert params['FinancialEventGroupStartedBefore'] == created_before_stamp
        assert params['MaxResultsPerPage'] == str(max_results)

    def test_list_financial_event_groups_by_next_token(self):
        """
        ListFinancialEventGroupsByNextToken operation, via method decorator.
        """
        next_token = 'VcNq06R0dO'
        params = self.api.list_financial_event_groups(next_token=next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventGroupsByNextToken'
        assert params['NextToken'] == next_token

    def test_list_financial_event_groups_by_next_token_alias(self):
        """
        ListFinancialEventGroupsByNextToken operation, via alias method.
        """
        next_token = 'uhEPBAvUYR'
        params = self.api.list_financial_event_groups_by_next_token(next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventGroupsByNextToken'
        assert params['NextToken'] == next_token

    def test_list_financial_events(self):
        """
        ListFinancialEvents operation.
        """
        posted_after = datetime.datetime.utcnow()
        posted_after_stamp = posted_after.iso_format()
        posted_before = datetime.datetime.utcnow()
        posted_before_stamp = posted_before.iso_format()
        amazon_order_id = '123-4567890-1234567'
        financial_event_group_id = '22YgYW55IGNhcm5hbCBwbGVhEXAMPLE'
        max_results = 156
        params = self.api.list_financial_events(
            financial_event_group_id=financial_event_group_id,
            amazon_order_id=amazon_order_id,
            posted_after=posted_after,
            posted_before=posted_before,
            max_results=max_results,
        )
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEvents'
        assert params['FinancialEventGroupId'] == financial_event_group_id
        assert params['AmazonOrderId'] == amazon_order_id
        assert params['PostedAfter'] == posted_after_stamp
        assert params['PostedBefore'] == posted_before_stamp
        assert params['MaxResultsPerPage'] == str(max_results)

    def test_list_financial_events_by_next_token(self):
        """
        ListFinancialEventsByNextToken operation, via method decorator.
        """
        next_token = '2t1DdnGqgf'
        params = self.api.list_financial_events(next_token=next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventsByNextToken'
        assert params['NextToken'] == next_token

    def test_list_financial_events_by_next_token_alias(self):
        """
        ListFinancialEventsByNextToken operation, via alias method.
        """
        next_token = '7Ijm9Kmrgp'
        params = self.api.list_financial_events_by_next_token(next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventsByNextToken'
        assert params['NextToken'] == next_token
<commit_msg>`isoformat`, not `iso_format`. Whoops.<commit_after>"""
Tests for the Finances API class.
"""
import unittest
import datetime
import mws
from .utils import CommonRequestTestTools

class FinancesTestCase(unittest.TestCase, CommonRequestTestTools):
    """
    Test cases for Finances.
    """
    # TODO: Add remaining methods for Finances
    def setUp(self):
        self.api = mws.Finances(
            self.CREDENTIAL_ACCESS,
            self.CREDENTIAL_SECRET,
            self.CREDENTIAL_ACCOUNT,
            auth_token=self.CREDENTIAL_TOKEN
        )
        self.api._test_request_params = True

    def test_list_financial_event_groups(self):
        """
        ListFinancialEventGroups operation.
        """
        created_after = datetime.datetime.utcnow()
        created_after_stamp = created_after.isoformat()
        created_before = datetime.datetime.utcnow()
        created_before_stamp = created_before.isoformat()
        max_results = 659
        params = self.api.list_financial_event_groups(
            created_after=created_after,
            created_before=created_before,
            max_results=max_results,
        )
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventGroups'
        assert params['FinancialEventGroupStartedAfter'] == created_after_stamp
        assert params['FinancialEventGroupStartedBefore'] == created_before_stamp
        assert params['MaxResultsPerPage'] == str(max_results)

    def test_list_financial_event_groups_by_next_token(self):
        """
        ListFinancialEventGroupsByNextToken operation, via method decorator.
        """
        next_token = 'VcNq06R0dO'
        params = self.api.list_financial_event_groups(next_token=next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventGroupsByNextToken'
        assert params['NextToken'] == next_token

    def test_list_financial_event_groups_by_next_token_alias(self):
        """
        ListFinancialEventGroupsByNextToken operation, via alias method.
        """
        next_token = 'uhEPBAvUYR'
        params = self.api.list_financial_event_groups_by_next_token(next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventGroupsByNextToken'
        assert params['NextToken'] == next_token

    def test_list_financial_events(self):
        """
        ListFinancialEvents operation.
        """
        posted_after = datetime.datetime.utcnow()
        posted_after_stamp = posted_after.isoformat()
        posted_before = datetime.datetime.utcnow()
        posted_before_stamp = posted_before.isoformat()
        amazon_order_id = '123-4567890-1234567'
        financial_event_group_id = '22YgYW55IGNhcm5hbCBwbGVhEXAMPLE'
        max_results = 156
        params = self.api.list_financial_events(
            financial_event_group_id=financial_event_group_id,
            amazon_order_id=amazon_order_id,
            posted_after=posted_after,
            posted_before=posted_before,
            max_results=max_results,
        )
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEvents'
        assert params['FinancialEventGroupId'] == financial_event_group_id
        assert params['AmazonOrderId'] == amazon_order_id
        assert params['PostedAfter'] == posted_after_stamp
        assert params['PostedBefore'] == posted_before_stamp
        assert params['MaxResultsPerPage'] == str(max_results)

    def test_list_financial_events_by_next_token(self):
        """
        ListFinancialEventsByNextToken operation, via method decorator.
        """
        next_token = '2t1DdnGqgf'
        params = self.api.list_financial_events(next_token=next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventsByNextToken'
        assert params['NextToken'] == next_token

    def test_list_financial_events_by_next_token_alias(self):
        """
        ListFinancialEventsByNextToken operation, via alias method.
        """
        next_token = '7Ijm9Kmrgp'
        params = self.api.list_financial_events_by_next_token(next_token)
        self.assert_common_params(params)
        assert params['Action'] == 'ListFinancialEventsByNextToken'
        assert params['NextToken'] == next_token
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Test the TcEx Threat Intel Module."""

from ..tcex_init import tcex

# pylint: disable=W0201
class TestVictim:
    """Test TcEx Victim."""

    def setup_class(self):
        """Configure setup before all tests."""
        self.ti = tcex.ti

    def test_victim_get(self, victim_id=None, name='victim-name-42353'):
        """Test victim get."""
        # create
        if not victim_id:
            victim_id = self.victim_create(name)

        # get
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.single(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get(ti.api_entity).get('name') == name

        # delete
        self.victim_delete(victim_id)

    def test_victim_get_attributes(self, victim_id=None, name='victim-name-12453'):
        """Test victim get."""
        # create
        if not victim_id:
            victim_id = self.victim_create(name)

        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test1'
        )
        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test2'
        )
        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test3'
        )

        # get attributes
        ti = self.ti.victim(name, unique_id=victim_id)
        for attribute in ti.attributes():
            assert attribute
            break
        else:
            assert False

        # delete
        self.victim_delete(victim_id)

    def test_victim_get_tags(self, victim_id=None, name='victim-name-64235'):
        """Test victim get."""
        # create
        if not victim_id:
            victim_id = self.victim_create(name)

        self.test_victim_add_tag(victim_id=victim_id, tag='One')
        self.test_victim_add_tag(victim_id=victim_id, tag='Two')

        # get tags
        ti = self.ti.victim(name, unique_id=victim_id)
        for tag in ti.tags():
            assert tag.get('name')
            break
        else:
            assert False

        # delete
        self.victim_delete(victim_id)

    def test_victim_get_include(self, victim_id=None, name='victim-name-78159'):
        """Test victim get."""
        if not victim_id:
            victim_id = self.victim_create(name)

        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test123'
        )
        self.test_victim_add_label(victim_id=victim_id, label='TLP:RED')
        self.test_victim_add_tag(victim_id=victim_id, tag='PyTest')

        parameters = {'includes': ['additional', 'attributes', 'labels', 'tags']}
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.single(owner='TCI', params=parameters)
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get('victim').get('name') == name
        assert ti_data.get('data').get('victim').get('attribute')[0].get('value') == 'test123'
        assert ti_data.get('data').get('victim').get('securityLabel')[0].get('name') == 'TLP:RED'
        assert ti_data.get('data').get('victim').get('tag')[0].get('name') == 'PyTest'

        # delete
        self.victim_delete(victim_id)

    def victim_create(self, name='victim-name-65341'):
        """Test victim create."""
        ti = self.ti.victim(name)
        r = ti.create(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 201
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get('victim').get('name') == name
        return ti.unique_id

    def test_victim_add_attribute(
        self,
        victim_id=None,
        name='victim-name-nkjvb',
        attribute_type='Description',
        attribute_value='Example Description.',
    ):
        """Test victim attribute add."""
        should_delete = False
        if not victim_id:
            should_delete = True
            victim_id = self.victim_create(name)

        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.add_attribute(attribute_type=attribute_type, attribute_value=attribute_value)
        attribute_data = r.json()
        assert r.status_code == 201
        assert attribute_data.get('status') == 'Success'
        assert attribute_data.get('data').get('attribute').get('value') == attribute_value

        if should_delete:
            self.victim_delete(victim_id)

    def test_victim_add_label(self, victim_id=None, name='victim-name-ds4vb', label='TLP:GREEN'):
        """Test victim attribute add."""
        should_delete = False
        if not victim_id:
            should_delete = True
            victim_id = self.victim_create(name)

        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.add_label(label=label)
        label_data = r.json()
        assert r.status_code == 201
        assert label_data.get('status') == 'Success'

        if should_delete:
            self.victim_delete(victim_id)

    def test_victim_add_tag(self, victim_id=None, name='victim-name-fdsv23', tag='Crimeware'):
        """Test victim attribute add."""
        should_delete = False
        if not victim_id:
            should_delete = True
            victim_id = self.victim_create(name)

        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.add_tag(tag)
        tag_data = r.json()
        assert r.status_code == 201
        assert tag_data.get('status') == 'Success'

        if should_delete:
            self.victim_delete(victim_id)

    def victim_delete(self, victim_id=None, name='victim-name-bdsfd'):
        """Test victim delete."""
        # create indicator
        if not victim_id:
            victim_id = self.victim_create(name)

        # delete indicator
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.delete(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'

    def test_victim_update(self, victim_id=None, name='victim-name-b3da3'):
        """Test victim update."""
        # create indicator
        if not victim_id:
            victim_id = self.victim_create(name)

        name = 'victim-new-name-fdasb3'

        # update indicator
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.update(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get('victim').get('name') == name

        # delete indicator
        self.victim_delete(victim_id)
<commit_msg>+ removed check for label on victims due to non-support in 5.7.<commit_after># -*- coding: utf-8 -*-
"""Test the TcEx Threat Intel Module."""

from ..tcex_init import tcex

# pylint: disable=W0201
class TestVictim:
    """Test TcEx Victim."""

    def setup_class(self):
        """Configure setup before all tests."""
        self.ti = tcex.ti

    def test_victim_get(self, victim_id=None, name='victim-name-42353'):
        """Test victim get."""
        # create
        if not victim_id:
            victim_id = self.victim_create(name)

        # get
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.single(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get(ti.api_entity).get('name') == name

        # delete
        self.victim_delete(victim_id)

    def test_victim_get_attributes(self, victim_id=None, name='victim-name-12453'):
        """Test victim get."""
        # create
        if not victim_id:
            victim_id = self.victim_create(name)

        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test1'
        )
        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test2'
        )
        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test3'
        )

        # get attributes
        ti = self.ti.victim(name, unique_id=victim_id)
        for attribute in ti.attributes():
            assert attribute
            break
        else:
            assert False

        # delete
        self.victim_delete(victim_id)

    def test_victim_get_tags(self, victim_id=None, name='victim-name-64235'):
        """Test victim get."""
        # create
        if not victim_id:
            victim_id = self.victim_create(name)

        self.test_victim_add_tag(victim_id=victim_id, tag='One')
        self.test_victim_add_tag(victim_id=victim_id, tag='Two')

        # get tags
        ti = self.ti.victim(name, unique_id=victim_id)
        for tag in ti.tags():
            assert tag.get('name')
            break
        else:
            assert False

        # delete
        self.victim_delete(victim_id)

    def test_victim_get_include(self, victim_id=None, name='victim-name-78159'):
        """Test victim get."""
        if not victim_id:
            victim_id = self.victim_create(name)

        self.test_victim_add_attribute(
            victim_id=victim_id, attribute_type='Description', attribute_value='test123'
        )
        self.test_victim_add_label(victim_id=victim_id, label='TLP:RED')
        self.test_victim_add_tag(victim_id=victim_id, tag='PyTest')

        parameters = {'includes': ['additional', 'attributes', 'labels', 'tags']}
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.single(owner='TCI', params=parameters)
        print(r.url)

        ti_data = r.json()
        print(ti_data)
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get('victim').get('name') == name
        assert ti_data.get('data').get('victim').get('attribute')[0].get('value') == 'test123'
        # assert ti_data.get('data').get('victim').get('securityLabel')[0].get('name') == 'TLP:RED'
        assert ti_data.get('data').get('victim').get('tag')[0].get('name') == 'PyTest'

        # delete
        self.victim_delete(victim_id)

    def victim_create(self, name='victim-name-65341'):
        """Test victim create."""
        ti = self.ti.victim(name)
        r = ti.create(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 201
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get('victim').get('name') == name
        return ti.unique_id

    def test_victim_add_attribute(
        self,
        victim_id=None,
        name='victim-name-nkjvb',
        attribute_type='Description',
        attribute_value='Example Description.',
    ):
        """Test victim attribute add."""
        should_delete = False
        if not victim_id:
            should_delete = True
            victim_id = self.victim_create(name)

        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.add_attribute(attribute_type=attribute_type, attribute_value=attribute_value)
        attribute_data = r.json()
        assert r.status_code == 201
        assert attribute_data.get('status') == 'Success'
        assert attribute_data.get('data').get('attribute').get('value') == attribute_value

        if should_delete:
            self.victim_delete(victim_id)

    def test_victim_add_label(self, victim_id=None, name='victim-name-ds4vb', label='TLP:GREEN'):
        """Test victim attribute add."""
        should_delete = False
        if not victim_id:
            should_delete = True
            victim_id = self.victim_create(name)

        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.add_label(label=label)
        label_data = r.json()
        assert r.status_code == 201
        assert label_data.get('status') == 'Success'

        if should_delete:
            self.victim_delete(victim_id)

    def test_victim_add_tag(self, victim_id=None, name='victim-name-fdsv23', tag='Crimeware'):
        """Test victim attribute add."""
        should_delete = False
        if not victim_id:
            should_delete = True
            victim_id = self.victim_create(name)

        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.add_tag(tag)
        tag_data = r.json()
        assert r.status_code == 201
        assert tag_data.get('status') == 'Success'

        if should_delete:
            self.victim_delete(victim_id)

    def victim_delete(self, victim_id=None, name='victim-name-bdsfd'):
        """Test victim delete."""
        # create indicator
        if not victim_id:
            victim_id = self.victim_create(name)

        # delete indicator
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.delete(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'

    def test_victim_update(self, victim_id=None, name='victim-name-b3da3'):
        """Test victim update."""
        # create indicator
        if not victim_id:
            victim_id = self.victim_create(name)

        name = 'victim-new-name-fdasb3'

        # update indicator
        ti = self.ti.victim(name, unique_id=victim_id)
        r = ti.update(owner='TCI')
        ti_data = r.json()
        assert r.status_code == 200
        assert ti_data.get('status') == 'Success'
        assert ti_data.get('data').get('victim').get('name') == name

        # delete indicator
        self.victim_delete(victim_id)
<|endoftext|>


<commit_before>"""Implementation of magic functions related to History.
"""
#-----------------------------------------------------------------------------
#  Copyright (c) 2012, IPython Development Team.
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Stdlib
import os
import sys
from io import open as io_open
import fnmatch

# Our own packages
from IPython.core.error import StdinNotImplementedError
from IPython.core.magic import Magics, magics_class, line_magic
from IPython.core.magic_arguments import (argument, magic_arguments,
                                          parse_argstring)
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils import io

#-----------------------------------------------------------------------------
# Magics class implementation
#-----------------------------------------------------------------------------

_unspecified = object()

@magics_class
class HistoryMagics(Magics):

    @magic_arguments()
    @argument(
        '-n', dest='print_nums', action='store_true', default=False,
        help="""
        print line numbers for each input.
        This feature is only available if numbered prompts are in use.
        """)
    @argument(
        '-o', dest='get_output', action='store_true', default=False,
        help="also print outputs for each input.")
    @argument(
        '-p', dest='pyprompts', action='store_true', default=False,
        help="""
        print classic '>>>' python prompts before each input.
        This is useful for making documentation, and in conjunction
        with -o, for producing doctest-ready output.
        """)
    @argument(
        '-t', dest='raw', action='store_false', default=True,
        help="""
        print the 'translated' history, as IPython understands it.
        IPython filters your input and converts it all into valid Python
        source before executing it (things like magics or aliases are turned
        into function calls, for example). With this option, you'll see the
        native history instead of the user-entered version: '%%cd /' will be
        seen as 'get_ipython().run_line_magic("cd", "/")' instead of '%%cd /'.
        """)
    @argument(
        '-f', dest='filename',
        help="""
        FILENAME: instead of printing the output to the screen, redirect
        it to the given file.  The file is always overwritten, though *when
        it can*, IPython asks for confirmation first. In particular, running
        the command 'history -f FILENAME' from the IPython Notebook
        interface will replace FILENAME even if it already exists *without*
        confirmation.
        """)
    @argument(
        '-g', dest='pattern', nargs='*', default=None,
        help="""
        treat the arg as a glob pattern to search for in (full) history.
        This includes the saved history (almost all commands ever written).
        The pattern may contain '?' to match one unknown character and '*'
        to match any number of unknown characters. Use '%%hist -g' to show
        full saved history (may be very long).
        """)
    @argument(
        '-l', dest='limit', type=int, nargs='?', default=_unspecified,
        help="""
        get the last n lines from all sessions. Specify n as a single
        arg, or the default is the last 10 lines.
        """)
    @argument(
        '-u', dest='unique', action='store_true',
        help="""
        when searching history using `-g`, show only unique history.
        """)
    @argument('range', nargs='*')
    @skip_doctest
    @line_magic
    def history(self, parameter_s = ''):
        """Print input history (_i<n> variables), with most recent last.

        By default, input history is printed without line numbers so it can be
        directly pasted into an editor. Use -n to show them.

        By default, all input history from the current session is displayed.
        Ranges of history can be indicated using the syntax:

        ``4``
            Line 4, current session
        ``4-6``
            Lines 4-6, current session
        ``243/1-5``
            Lines 1-5, session 243
        ``~2/7``
            Line 7, session 2 before current
        ``~8/1-~6/5``
            From the first line of 8 sessions ago, to the fifth line of 6
            sessions ago.

        Multiple ranges can be entered, separated by spaces

        The same syntax is used by %macro, %save, %edit, %rerun

        Examples
        --------
        ::

          In [6]: %history -n 4-6
          4:a = 12
          5:print a**2
          6:%history -n 4-6

        """

        args = parse_argstring(self.history, parameter_s)

        # For brevity
        history_manager = self.shell.history_manager

        def _format_lineno(session, line):
            """Helper function to format line numbers properly."""
            if session in (0, history_manager.session_number):
                return str(line)
            return "%s/%s" % (session, line)

        # Check if output to specific file was requested.
        outfname = args.filename
        if not outfname:
            outfile = sys.stdout  # default
            # We don't want to close stdout at the end!
            close_at_end = False
        else:
            if os.path.exists(outfname):
                try:
                    ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
                except StdinNotImplementedError:
                    ans = True
                if not ans:
                    print('Aborting.')
                    return
                print("Overwriting file.")
            outfile = io_open(outfname, 'w', encoding='utf-8')
            close_at_end = True

        print_nums = args.print_nums
        get_output = args.get_output
        pyprompts = args.pyprompts
        raw = args.raw

        pattern = None
        limit = None if args.limit is _unspecified else args.limit

        range_pattern = False
        if args.pattern is not None and not args.range:
            if args.pattern:
                pattern = "*" + " ".join(args.pattern) + "*"
            else:
                pattern = "*"
            hist = history_manager.search(pattern, raw=raw, output=get_output,
                                          n=limit, unique=args.unique)
            print_nums = True
        elif args.limit is not _unspecified:
            n = 10 if limit is None else limit
            hist = history_manager.get_tail(n, raw=raw, output=get_output)
        else:
            if args.range:      # Get history by ranges
                if args.pattern:
                    range_pattern = "*" + " ".join(args.pattern) + "*"
                    print_nums = True
                hist = history_manager.get_range_by_str(" ".join(args.range),
                                                        raw, get_output)
            else:               # Just get history for the current session
                hist = history_manager.get_range(raw=raw, output=get_output)

        # We could be displaying the entire history, so let's not try to pull
        # it into a list in memory. Anything that needs more space will just
        # misalign.
        width = 4

        for session, lineno, inline in hist:
            # Print user history with tabs expanded to 4 spaces.  The GUI
            # clients use hard tabs for easier usability in auto-indented code,
            # but we want to produce PEP-8 compliant history for safe pasting
            # into an editor.
            if get_output:
                inline, output = inline
            if range_pattern:
                if not fnmatch.fnmatch(inline,range_pattern): continue;
            inline = inline.expandtabs(4).rstrip()

            multiline = "\n" in inline
            line_sep = '\n' if multiline else ' '
            if print_nums:
                print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
                        line_sep),  file=outfile, end=u'')
            if pyprompts:
                print(u">>> ", end=u"", file=outfile)
                if multiline:
                    inline = "\n... ".join(inline.splitlines()) + "\n..."
            print(inline, file=outfile)
            if get_output and output:
                print(output, file=outfile)

        if close_at_end:
            outfile.close()

    @line_magic
    def recall(self, arg):
        r"""Repeat a command, or get command to input line for editing.

        %recall and %rep are equivalent.

        - %recall (no arguments):

        Place a string version of last computation result (stored in the
        special '_' variable) to the next input prompt. Allows you to create
        elaborate command lines without using copy-paste::

             In[1]: l = ["hei", "vaan"]
             In[2]: "".join(l)
            Out[2]: heivaan
             In[3]: %recall
             In[4]: heivaan_ <== cursor blinking

        %recall 45

        Place history line 45 on the next input prompt. Use %hist to find
        out the number.

        %recall 1-4

        Combine the specified lines into one cell, and place it on the next
        input prompt. See %history for the slice syntax.

        %recall foo+bar

        If foo+bar can be evaluated in the user namespace, the result is
        placed at the next input prompt. Otherwise, the history is searched
        for lines which contain that substring, and the most recent one is
        placed at the next input prompt.
        """
        if not arg:                 # Last output
            self.shell.set_next_input(str(self.shell.user_ns["_"]))
            return
                                    # Get history range
        histlines = self.shell.history_manager.get_range_by_str(arg)
        cmd = "\n".join(x[2] for x in histlines)
        if cmd:
            self.shell.set_next_input(cmd.rstrip())
            return

        try:                        # Variable in user namespace
            cmd = str(eval(arg, self.shell.user_ns))
        except Exception:           # Search for term in history
            histlines = self.shell.history_manager.search("*"+arg+"*")
            for h in reversed([x[2] for x in histlines]):
                if 'recall' in h or 'rep' in h:
                    continue
                self.shell.set_next_input(h.rstrip())
                return
        else:
            self.shell.set_next_input(cmd.rstrip())
        print("Couldn't evaluate or find in history:", arg)

    @line_magic
    def rerun(self, parameter_s=''):
        """Re-run previous input

        By default, you can specify ranges of input history to be repeated
        (as with %history). With no arguments, it will repeat the last line.

        Options:

          -l <n> : Repeat the last n lines of input, not including the
          current command.

          -g foo : Repeat the most recent line which contains foo
        """
        opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
        if "l" in opts:         # Last n lines
            n = int(opts['l'])
            hist = self.shell.history_manager.get_tail(n)
        elif "g" in opts:       # Search
            p = "*"+opts['g']+"*"
            hist = list(self.shell.history_manager.search(p))
            for l in reversed(hist):
                if "rerun" not in l[2]:
                    hist = [l]     # The last match which isn't a %rerun
                    break
            else:
                hist = []          # No matches except %rerun
        elif args:              # Specify history ranges
            hist = self.shell.history_manager.get_range_by_str(args)
        else:                   # Last line
            hist = self.shell.history_manager.get_tail(1)
        hist = [x[2] for x in hist]
        if not hist:
            print("No lines in history match specification")
            return
        histlines = "\n".join(hist)
        print("=== Executing: ===")
        print(histlines)
        print("=== Output: ===")
        self.shell.run_cell("\n".join(hist), store_history=False)
<commit_msg>darker -r 60625f241f298b5039cb2debc365db38aa7bb522<commit_after>"""Implementation of magic functions related to History.
"""
#-----------------------------------------------------------------------------
#  Copyright (c) 2012, IPython Development Team.
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Stdlib
import os
import sys
from io import open as io_open
import fnmatch

# Our own packages
from IPython.core.error import StdinNotImplementedError
from IPython.core.magic import Magics, magics_class, line_magic
from IPython.core.magic_arguments import (argument, magic_arguments,
                                          parse_argstring)
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils import io

#-----------------------------------------------------------------------------
# Magics class implementation
#-----------------------------------------------------------------------------

_unspecified = object()

@magics_class
class HistoryMagics(Magics):

    @magic_arguments()
    @argument(
        '-n', dest='print_nums', action='store_true', default=False,
        help="""
        print line numbers for each input.
        This feature is only available if numbered prompts are in use.
        """)
    @argument(
        '-o', dest='get_output', action='store_true', default=False,
        help="also print outputs for each input.")
    @argument(
        '-p', dest='pyprompts', action='store_true', default=False,
        help="""
        print classic '>>>' python prompts before each input.
        This is useful for making documentation, and in conjunction
        with -o, for producing doctest-ready output.
        """)
    @argument(
        '-t', dest='raw', action='store_false', default=True,
        help="""
        print the 'translated' history, as IPython understands it.
        IPython filters your input and converts it all into valid Python
        source before executing it (things like magics or aliases are turned
        into function calls, for example). With this option, you'll see the
        native history instead of the user-entered version: '%%cd /' will be
        seen as 'get_ipython().run_line_magic("cd", "/")' instead of '%%cd /'.
        """)
    @argument(
        '-f', dest='filename',
        help="""
        FILENAME: instead of printing the output to the screen, redirect
        it to the given file.  The file is always overwritten, though *when
        it can*, IPython asks for confirmation first. In particular, running
        the command 'history -f FILENAME' from the IPython Notebook
        interface will replace FILENAME even if it already exists *without*
        confirmation.
        """)
    @argument(
        '-g', dest='pattern', nargs='*', default=None,
        help="""
        treat the arg as a glob pattern to search for in (full) history.
        This includes the saved history (almost all commands ever written).
        The pattern may contain '?' to match one unknown character and '*'
        to match any number of unknown characters. Use '%%hist -g' to show
        full saved history (may be very long).
        """)
    @argument(
        '-l', dest='limit', type=int, nargs='?', default=_unspecified,
        help="""
        get the last n lines from all sessions. Specify n as a single
        arg, or the default is the last 10 lines.
        """)
    @argument(
        '-u', dest='unique', action='store_true',
        help="""
        when searching history using `-g`, show only unique history.
        """)
    @argument('range', nargs='*')
    @skip_doctest
    @line_magic
    def history(self, parameter_s = ''):
        """Print input history (_i<n> variables), with most recent last.

        By default, input history is printed without line numbers so it can be
        directly pasted into an editor. Use -n to show them.

        By default, all input history from the current session is displayed.
        Ranges of history can be indicated using the syntax:

        ``4``
            Line 4, current session
        ``4-6``
            Lines 4-6, current session
        ``243/1-5``
            Lines 1-5, session 243
        ``~2/7``
            Line 7, session 2 before current
        ``~8/1-~6/5``
            From the first line of 8 sessions ago, to the fifth line of 6
            sessions ago.

        Multiple ranges can be entered, separated by spaces

        The same syntax is used by %macro, %save, %edit, %rerun

        Examples
        --------
        ::

          In [6]: %history -n 4-6
          4:a = 12
          5:print a**2
          6:%history -n 4-6

        """

        args = parse_argstring(self.history, parameter_s)

        # For brevity
        history_manager = self.shell.history_manager

        def _format_lineno(session, line):
            """Helper function to format line numbers properly."""
            if session in (0, history_manager.session_number):
                return str(line)
            return "%s/%s" % (session, line)

        # Check if output to specific file was requested.
        outfname = args.filename
        if not outfname:
            outfile = sys.stdout  # default
            # We don't want to close stdout at the end!
            close_at_end = False
        else:
            if os.path.exists(outfname):
                try:
                    ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
                except StdinNotImplementedError:
                    ans = True
                if not ans:
                    print('Aborting.')
                    return
                print("Overwriting file.")
            outfile = io_open(outfname, 'w', encoding='utf-8')
            close_at_end = True

        print_nums = args.print_nums
        get_output = args.get_output
        pyprompts = args.pyprompts
        raw = args.raw

        pattern = None
        limit = None if args.limit is _unspecified else args.limit

        range_pattern = False
        if args.pattern is not None and not args.range:
            if args.pattern:
                pattern = "*" + " ".join(args.pattern) + "*"
            else:
                pattern = "*"
            hist = history_manager.search(pattern, raw=raw, output=get_output,
                                          n=limit, unique=args.unique)
            print_nums = True
        elif args.limit is not _unspecified:
            n = 10 if limit is None else limit
            hist = history_manager.get_tail(n, raw=raw, output=get_output)
        else:
            if args.range:      # Get history by ranges
                if args.pattern:
                    range_pattern = "*" + " ".join(args.pattern) + "*"
                    print_nums = True
                hist = history_manager.get_range_by_str(" ".join(args.range),
                                                        raw, get_output)
            else:               # Just get history for the current session
                hist = history_manager.get_range(raw=raw, output=get_output)

        # We could be displaying the entire history, so let's not try to pull
        # it into a list in memory. Anything that needs more space will just
        # misalign.
        width = 4

        for session, lineno, inline in hist:
            # Print user history with tabs expanded to 4 spaces.  The GUI
            # clients use hard tabs for easier usability in auto-indented code,
            # but we want to produce PEP-8 compliant history for safe pasting
            # into an editor.
            if get_output:
                inline, output = inline
            if range_pattern:
                if not fnmatch.fnmatch(inline, range_pattern):
                    continue
            inline = inline.expandtabs(4).rstrip()

            multiline = "\n" in inline
            line_sep = '\n' if multiline else ' '
            if print_nums:
                print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
                        line_sep),  file=outfile, end=u'')
            if pyprompts:
                print(u">>> ", end=u"", file=outfile)
                if multiline:
                    inline = "\n... ".join(inline.splitlines()) + "\n..."
            print(inline, file=outfile)
            if get_output and output:
                print(output, file=outfile)

        if close_at_end:
            outfile.close()

    @line_magic
    def recall(self, arg):
        r"""Repeat a command, or get command to input line for editing.

        %recall and %rep are equivalent.

        - %recall (no arguments):

        Place a string version of last computation result (stored in the
        special '_' variable) to the next input prompt. Allows you to create
        elaborate command lines without using copy-paste::

             In[1]: l = ["hei", "vaan"]
             In[2]: "".join(l)
            Out[2]: heivaan
             In[3]: %recall
             In[4]: heivaan_ <== cursor blinking

        %recall 45

        Place history line 45 on the next input prompt. Use %hist to find
        out the number.

        %recall 1-4

        Combine the specified lines into one cell, and place it on the next
        input prompt. See %history for the slice syntax.

        %recall foo+bar

        If foo+bar can be evaluated in the user namespace, the result is
        placed at the next input prompt. Otherwise, the history is searched
        for lines which contain that substring, and the most recent one is
        placed at the next input prompt.
        """
        if not arg:                 # Last output
            self.shell.set_next_input(str(self.shell.user_ns["_"]))
            return
                                    # Get history range
        histlines = self.shell.history_manager.get_range_by_str(arg)
        cmd = "\n".join(x[2] for x in histlines)
        if cmd:
            self.shell.set_next_input(cmd.rstrip())
            return

        try:                        # Variable in user namespace
            cmd = str(eval(arg, self.shell.user_ns))
        except Exception:           # Search for term in history
            histlines = self.shell.history_manager.search("*"+arg+"*")
            for h in reversed([x[2] for x in histlines]):
                if 'recall' in h or 'rep' in h:
                    continue
                self.shell.set_next_input(h.rstrip())
                return
        else:
            self.shell.set_next_input(cmd.rstrip())
        print("Couldn't evaluate or find in history:", arg)

    @line_magic
    def rerun(self, parameter_s=''):
        """Re-run previous input

        By default, you can specify ranges of input history to be repeated
        (as with %history). With no arguments, it will repeat the last line.

        Options:

          -l <n> : Repeat the last n lines of input, not including the
          current command.

          -g foo : Repeat the most recent line which contains foo
        """
        opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
        if "l" in opts:         # Last n lines
            n = int(opts['l'])
            hist = self.shell.history_manager.get_tail(n)
        elif "g" in opts:       # Search
            p = "*"+opts['g']+"*"
            hist = list(self.shell.history_manager.search(p))
            for l in reversed(hist):
                if "rerun" not in l[2]:
                    hist = [l]     # The last match which isn't a %rerun
                    break
            else:
                hist = []          # No matches except %rerun
        elif args:              # Specify history ranges
            hist = self.shell.history_manager.get_range_by_str(args)
        else:                   # Last line
            hist = self.shell.history_manager.get_tail(1)
        hist = [x[2] for x in hist]
        if not hist:
            print("No lines in history match specification")
            return
        histlines = "\n".join(hist)
        print("=== Executing: ===")
        print(histlines)
        print("=== Output: ===")
        self.shell.run_cell("\n".join(hist), store_history=False)
<|endoftext|>