def ghuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """Link to a GitHub user.

    Returns 2 part tuple containing list of nodes to insert into the
    document and a list of system messages.  Both are allowed to be
    empty.

    :param name: The role name used in the document.
    :param rawtext: The entire markup snippet, with role.
    :param text: The text marked with the role.
    :param lineno: The line number where rawtext appears in the input.
    :param inliner: The inliner instance that called us.
    :param options: Directive options for customization.
    :param content: The directive content for customization.
    """
    # app = inliner.document.settings.env.app
    #app.info('user link %r' % text)
    ref = 'https://www.github.com/' + text
    node = nodes.reference(rawtext, text, refuri=ref, **options)
    return [node], []


def _infer_tarball_url():
    """Returns the tarball URL inferred from an app.json, if present."""
    try:
        with click.open_file('app.json', 'r') as f:
            contents = f.read()

        app_json = json.loads(contents)
    except IOError:
        return None

    repository = app_json.get('repository')

    if not repository:
        return None
    else:
        return app_json.get('repository') + '/tarball/master/'

def _infer_tarball_url ( ) : try : with click . open_file ( 'app.json' , 'r' ) as f : contents = f . read ( ) app_json = json . loads ( contents ) except IOError : return None repository = app_json . get ( 'repository' ) if not repository : return None else : return app_json . get ( 'repository' ) + '/tarball/master/'

Returns the tarball URL inferred from an app . json if present .


def up(tarball_url, auth_token, env, app_name):
    """Brings up a Heroku app."""
    tarball_url = tarball_url or _infer_tarball_url()

    if not tarball_url:
        click.echo('No tarball URL found.')
        sys.exit(1)

    if env:
        # Split ["KEY=value", ...] into {"KEY": "value", ...}
        env = {
            arg.split('=')[0]: arg.split('=')[1]
            for arg in env
        }

    happy = Happy(auth_token=auth_token)

    click.echo('Creating app... ', nl=False)

    build_id, app_name = happy.create(
        tarball_url=tarball_url,
        env=env,
        app_name=app_name,
    )

    click.echo(app_name)

    click.echo('Building... ', nl=False)

    happy.wait(build_id)

    _write_app_name(app_name)

    click.echo('done')
    click.echo("It's up! :) https://%s.herokuapp.com" % app_name)


def down(auth_token, force, app_name):
    """Brings down a Heroku app."""
    if not app_name:
        click.echo(
            'WARNING: Inferring the app name when deleting is deprecated. '
            'Starting with happy 2.0, the app_name parameter will be required.'
        )

    app_name = app_name or _read_app_name()

    if not app_name:
        click.echo('No app name given.')
        sys.exit(1)

    if not force:
        click.confirm(
            'Are you sure you want to delete %s?' % app_name,
            abort=True,
        )

    happy = Happy(auth_token=auth_token)

    click.echo('Destroying app %s... ' % app_name, nl=False)

    happy.delete(app_name=app_name)

    _delete_app_name_file()

    click.echo('done')
    click.echo("It's down. :(")


def iter_attribute(iterable_name) -> Union[Iterable, Callable]:
    """Decorator implementing Iterator interface with nicer manner.

    Example
    -------

    @iter_attribute('my_attr'):
    class DecoratedClass:
        ...

    Warning:
    ========

    When using PyCharm or MYPY you'll probably see issues with decorated class not being recognized as Iterator.
    That's an issue which I could not overcome yet, it's probably due to the fact that interpretation of object
    is being done statically rather than dynamically. MYPY checks for definition of methods in class code which
    changes at runtime. Since __iter__ and __next__ are added dynamically MYPY cannot find those
    defined in objects before object of a class is created. Possible workarounds for this issue are:

        1. Define ``dummy`` __iter__ class like:

            @iter_attribute('attr')
            class Test:
                def __init__(self) -> None:
                    self.attr = [1, 2, 3]

                def __iter__(self):
                    pass

        2. After creating object use cast or assert function denoting that particular instance inherits
            from collections.Iterator:

            assert isinstance(my_object, collections.Iterator)

    :param iterable_name: string representing attribute name which has to be iterated
    :return: DecoratedClass with implemented '__iter__' and '__next__' methods.
    """

    def create_new_class(decorated_class) -> Union[Iterable, Callable]:
        """Class extender implementing __next__ and __iter__ methods.

        :param decorated_class: class to be extended with iterator interface
        :return: new class
        """
        assert inspect.isclass(decorated_class), 'You can only decorate class objects!'
        assert isinstance(iterable_name, str), 'Please provide attribute name string'

        decorated_class.iterator_attr_index = 0

        def __iter__(instance) -> Iterable:
            """Implement __iter__ method

            :param instance: __iter__ uses instance of class which is being extended
            :return: instance of decorated_class
            """
            return instance

        def __next__(instance) -> Any:
            """Implement __next__ method

            :param instance: __next__ uses instance of class which is being extended
            :return: instance of decorated_class
            """
            assert hasattr(instance, iterable_name), \
                'Decorated object does not have attribute named {}'.format(iterable_name)
            assert isinstance(getattr(instance, iterable_name), collections.Iterable), \
                '{} of object {} is not iterable'.format(iterable_name, instance.__class__.__name__)
            ind = instance.iterator_attr_index
            while ind < len(getattr(instance, iterable_name)):
                val = getattr(instance, iterable_name)[ind]
                instance.iterator_attr_index += 1
                return val
            instance.iterator_attr_index = 0
            raise StopIteration

        dct = dict(decorated_class.__dict__)
        dct['__iter__'] = __iter__
        dct['__next__'] = __next__
        dct['iterator_attr_index'] = decorated_class.iterator_attr_index
        return type(decorated_class.__name__, (collections.Iterable,), dct)

    return create_new_class

Decorator implementing Iterator interface with nicer manner .


def binary(length):
    """
        returns a a random string that represent a binary representation

    :param length: number of bits
    """
    num = randint(1, 999999)
    mask = '0' * length
    return (mask + ''.join([str(num >> i & 1) for i in range(7, -1, -1)]))[-length:]

def binary ( length ) : num = randint ( 1 , 999999 ) mask = '0' * length return ( mask + '' . join ( [ str ( num >> i & 1 ) for i in range ( 7 , - 1 , - 1 ) ] ) ) [ - length : ]


def ipaddress(not_valid=None):
    """
        returns a string representing a random ip address

    :param not_valid: if passed must be a list of integers representing valid class A netoworks that must be ignored
    """
    not_valid_class_A = not_valid or []

    class_a = [r for r in range(1, 256) if r not in not_valid_class_A]
    shuffle(class_a)
    first = class_a.pop()

    return ".".join([str(first), str(randrange(1, 256)),
                     str(randrange(1, 256)), str(randrange(1, 256))])

def ipaddress ( not_valid = None ) : not_valid_class_A = not_valid or [ ] class_a = [ r for r in range ( 1 , 256 ) if r not in not_valid_class_A ] shuffle ( class_a ) first = class_a . pop ( ) return "." . join ( [ str ( first ) , str ( randrange ( 1 , 256 ) ) , str ( randrange ( 1 , 256 ) ) , str ( randrange ( 1 , 256 ) ) ] )


def date(start, end):
    """Get a random date between two dates"""

    stime = date_to_timestamp(start)
    etime = date_to_timestamp(end)

    ptime = stime + random.random() * (etime - stime)

    return datetime.date.fromtimestamp(ptime)

def date ( start , end ) : stime = date_to_timestamp ( start ) etime = date_to_timestamp ( end ) ptime = stime + random . random ( ) * ( etime - stime ) return datetime . date . fromtimestamp ( ptime )


def _get_session(self):
        """Returns a prepared ``Session`` instance."""
        session = Session()

        session.headers = {
            'Content-type': 'application/json',
            'Accept': 'application/vnd.heroku+json; version=3',
        }

        if self._auth_token:
            session.trust_env = False  # Effectively disable netrc auth
            session.headers['Authorization'] = 'Bearer %s' % self._auth_token

        return session


def api_request(self, method, endpoint, data=None, *args, **kwargs):
        """Sends an API request to Heroku.

        :param method: HTTP method.
        :param endpoint: API endpoint, e.g. ``/apps``.
        :param data: A dict sent as JSON in the body of the request.
        :returns: A dict represntation of the JSON response.
        """
        session = self._get_session()

        api_root = 'https://api.heroku.com'
        url = api_root + endpoint

        if data:
            data = json.dumps(data)

        response = session.request(method, url, data=data, *args, **kwargs)

        if not response.ok:
            try:
                message = response.json().get('message')
            except ValueError:
                message = response.content

            raise APIError(message)

        return response.json()

def api_request ( self , method , endpoint , data = None , * args , * * kwargs ) : session = self . _get_session ( ) api_root = 'https://api.heroku.com' url = api_root + endpoint if data : data = json . dumps ( data ) response = session . request ( method , url , data = data , * args , * * kwargs ) if not response . ok : try : message = response . json ( ) . get ( 'message' ) except ValueError : message = response . content raise APIError ( message ) return response . json ( )


def create_build(self, tarball_url, env=None, app_name=None):
        """Creates an app-setups build. Returns response data as a dict.

        :param tarball_url: URL of a tarball containing an ``app.json``.
        :param env: Dict containing environment variable overrides.
        :param app_name: Name of the Heroku app to create.
        :returns: Response data as a ``dict``.
        """
        data = {
            'source_blob': {
                'url': tarball_url
            }
        }

        if env:
            data['overrides'] = {'env': env}

        if app_name:
            data['app'] = {'name': app_name}

        return self.api_request('POST', '/app-setups', data=data)

def create_build ( self , tarball_url , env = None , app_name = None ) : data = { 'source_blob' : { 'url' : tarball_url } } if env : data [ 'overrides' ] = { 'env' : env } if app_name : data [ 'app' ] = { 'name' : app_name } return self . api_request ( 'POST' , '/app-setups' , data = data )

Creates an app - setups build . Returns response data as a dict .


def check_build_status(self, build_id):
        """Checks the status of an app-setups build.

        :param build_id: ID of the build to check.
        :returns: ``True`` if succeeded, ``False`` if pending.
        """
        data = self.api_request('GET', '/app-setups/%s' % build_id)

        status = data.get('status')

        if status == 'pending':
            return False
        elif status == 'succeeded':
            return True
        else:
            raise BuildError(str(data))

def check_build_status ( self , build_id ) : data = self . api_request ( 'GET' , '/app-setups/%s' % build_id ) status = data . get ( 'status' ) if status == 'pending' : return False elif status == 'succeeded' : return True else : raise BuildError ( str ( data ) )

Checks the status of an app - setups build .


def sequence(prefix, cache=None):
    """
    generator that returns an unique string

    :param prefix: prefix of string
    :param cache: cache used to store the last used number

    >>> next(sequence('abc'))
    'abc-0'
    >>> next(sequence('abc'))
    'abc-1'
    """
    if cache is None:
        cache = _sequence_counters
    if cache == -1:
        cache = {}

    if prefix not in cache:
        cache[prefix] = infinite()

    while cache[prefix]:
        yield "{0}-{1}".format(prefix, next(cache[prefix]))

def sequence ( prefix , cache = None ) : if cache is None : cache = _sequence_counters if cache == - 1 : cache = { } if prefix not in cache : cache [ prefix ] = infinite ( ) while cache [ prefix ] : yield "{0}-{1}" . format ( prefix , next ( cache [ prefix ] ) )


def memoize(func):
    """Decorator that stores function results in a dictionary to be used on the
    next time that the same arguments were informed."""

    func._cache_dict = {}

    @wraps(func)
    def _inner(*args, **kwargs):
        return _get_memoized_value(func, args, kwargs)

    return _inner

def memoize ( func ) : func . _cache_dict = { } @ wraps ( func ) def _inner ( * args , * * kwargs ) : return _get_memoized_value ( func , args , kwargs ) return _inner

Decorator that stores function results in a dictionary to be used on the next time that the same arguments were informed .


def unique(func, num_args=0, max_attempts=100, cache=None):
    """
    wraps a function so that produce unique results

    :param func:
    :param num_args:

    >>> import random
    >>> choices = [1,2]
    >>> a = unique(random.choice, 1)
    >>> a,b = a(choices), a(choices)
    >>> a == b
    False
    """
    if cache is None:
        cache = _cache_unique

    @wraps(func)
    def wrapper(*args):
        key = "%s_%s" % (str(func.__name__), str(args[:num_args]))
        attempt = 0
        while attempt < max_attempts:
            attempt += 1
            drawn = cache.get(key, [])
            result = func(*args)
            if result not in drawn:
                drawn.append(result)
                cache[key] = drawn
                return result

        raise MaxAttemptException()

    return wrapper

def unique ( func , num_args = 0 , max_attempts = 100 , cache = None ) : if cache is None : cache = _cache_unique @ wraps ( func ) def wrapper ( * args ) : key = "%s_%s" % ( str ( func . __name__ ) , str ( args [ : num_args ] ) ) attempt = 0 while attempt < max_attempts : attempt += 1 drawn = cache . get ( key , [ ] ) result = func ( * args ) if result not in drawn : drawn . append ( result ) cache [ key ] = drawn return result raise MaxAttemptException ( ) return wrapper


def register_sub_commands(self, parser):
        """
        Add any sub commands to the argument parser.

        :param parser: The argument parser object
        """
        sub_commands = self.get_sub_commands()
        if sub_commands:
            sub_parsers = parser.add_subparsers(dest=self.sub_parser_dest_name)

            for name, cls in sub_commands.items():
                cmd = cls(name)

                sub_parser = sub_parsers.add_parser(name, help=name, description=cmd.get_help(), formatter_class=cmd.get_formatter_class())

                cmd.add_args(sub_parser)
                cmd.register_sub_commands(sub_parser)

def register_sub_commands ( self , parser ) : sub_commands = self . get_sub_commands ( ) if sub_commands : sub_parsers = parser . add_subparsers ( dest = self . sub_parser_dest_name ) for name , cls in sub_commands . items ( ) : cmd = cls ( name ) sub_parser = sub_parsers . add_parser ( name , help = name , description = cmd . get_help ( ) , formatter_class = cmd . get_formatter_class ( ) ) cmd . add_args ( sub_parser ) cmd . register_sub_commands ( sub_parser )

Add any sub commands to the argument parser .


def get_root_argparser(self):
        """
        Gets the root argument parser object.
        """
        return self.arg_parse_class(description=self.get_help(), formatter_class=self.get_formatter_class())

def get_root_argparser ( self ) : return self . arg_parse_class ( description = self . get_help ( ) , formatter_class = self . get_formatter_class ( ) )


def get_description(self):
        """
        Gets the description of the command. If its not supplied the first sentence of the doc string is used.
        """
        if self.description:
            return self.description
        elif self.__doc__ and self.__doc__.strip():
            return self.__doc__.strip().split('.')[0] + '.'
        else:
            return ''

def get_description ( self ) : if self . description : return self . description elif self . __doc__ and self . __doc__ . strip ( ) : return self . __doc__ . strip ( ) . split ( '.' ) [ 0 ] + '.' else : return ''

Gets the description of the command . If its not supplied the first sentence of the doc string is used .


def get_help(self):
        """
        Gets the help text for the command. If its not supplied the doc string is used.
        """
        if self.help:
            return self.help
        elif self.__doc__ and self.__doc__.strip():
            return self.__doc__.strip()
        else:
            return ''

def get_help ( self ) : if self . help : return self . help elif self . __doc__ and self . __doc__ . strip ( ) : return self . __doc__ . strip ( ) else : return ''

Gets the help text for the command . If its not supplied the doc string is used .


def run(self, args=None):
        """
        Runs the command passing in the parsed arguments.

        :param args: The arguments to run the command with. If ``None`` the arguments
            are gathered from the argument parser. This is automatically set when calling
            sub commands and in most cases should not be set for the root command.

        :return: The status code of the action (0 on success)
        """
        args = args or self.parse_args()

        sub_command_name = getattr(args, self.sub_parser_dest_name, None)
        if sub_command_name:
            sub_commands = self.get_sub_commands()
            cmd_cls = sub_commands[sub_command_name]
            return cmd_cls(sub_command_name).run(args)

        return self.action(args) or 0

def run ( self , args = None ) : args = args or self . parse_args ( ) sub_command_name = getattr ( args , self . sub_parser_dest_name , None ) if sub_command_name : sub_commands = self . get_sub_commands ( ) cmd_cls = sub_commands [ sub_command_name ] return cmd_cls ( sub_command_name ) . run ( args ) return self . action ( args ) or 0

Runs the command passing in the parsed arguments .


def encode(self,  *args, **kwargs):
        """Encode wrapper for a dataset with maximum value

        Datasets can be one or two dimensional
        Strings are ignored as ordinal encoding"""
        if isinstance(args[0], str):
            return self.encode([args[0]],**kwargs)
        elif isinstance(args[0], int) or isinstance(args[0], float):
            return self.encode([[args[0]]],**kwargs)
        if len(args)>1:
            dataset = args
        else:
            dataset = args[0]
        typemap = list(map(type,dataset))
        code = self.encoding[0]
        if type('') in typemap:
            data = ','.join(map(str,dataset))
        elif type([]) in typemap or type(()) in typemap:
            data = self.codeset['char'].join(map(self.encodedata, dataset))
        elif len(dataset) == 1 and hasattr(dataset[0], '__iter__'):
            data = self.encodedata(dataset[0])
        else:
            try:
                data = self.encodedata(dataset)
            except ValueError:
                data = self.encodedata(','.join(map(unicode,dataset)))
        if not '.' in data and code == 't':
            code = 'e'
        return '%s%s:%s'%(code,self.series,data)

def encode ( self , * args , * * kwargs ) : if isinstance ( args [ 0 ] , str ) : return self . encode ( [ args [ 0 ] ] , * * kwargs ) elif isinstance ( args [ 0 ] , int ) or isinstance ( args [ 0 ] , float ) : return self . encode ( [ [ args [ 0 ] ] ] , * * kwargs ) if len ( args ) > 1 : dataset = args else : dataset = args [ 0 ] typemap = list ( map ( type , dataset ) ) code = self . encoding [ 0 ] if type ( '' ) in typemap : data = ',' . join ( map ( str , dataset ) ) elif type ( [ ] ) in typemap or type ( ( ) ) in typemap : data = self . codeset [ 'char' ] . join ( map ( self . encodedata , dataset ) ) elif len ( dataset ) == 1 and hasattr ( dataset [ 0 ] , '__iter__' ) : data = self . encodedata ( dataset [ 0 ] ) else : try : data = self . encodedata ( dataset ) except ValueError : data = self . encodedata ( ',' . join ( map ( unicode , dataset ) ) ) if not '.' in data and code == 't' : code = 'e' return '%s%s:%s' % ( code , self . series , data )


def get_athletes(self):
        """Get all available athletes
        This method is cached to prevent unnecessary calls to GC.
        """
        response = self._get_request(self.host)
        response_buffer = StringIO(response.text)

        return pd.read_csv(response_buffer)

def get_athletes ( self ) : response = self . _get_request ( self . host ) response_buffer = StringIO ( response . text ) return pd . read_csv ( response_buffer )

Get all available athletes This method is cached to prevent unnecessary calls to GC .


def get_last_activities(self, n):
        """Get all activity data for the last activity

        Keyword arguments:
        """
        filenames = self.get_activity_list().iloc[-n:].filename.tolist()
        last_activities = [self.get_activity(f) for f in filenames]
        return last_activities

def get_last_activities ( self , n ) : filenames = self . get_activity_list ( ) . iloc [ - n : ] . filename . tolist ( ) last_activities = [ self . get_activity ( f ) for f in filenames ] return last_activities


def _request_activity_list(self, athlete):
        """Actually do the request for activity list
        This call is slow and therefore this method is memory cached.

        Keyword arguments:
        athlete -- Full name of athlete
        """
        response = self._get_request(self._athlete_endpoint(athlete))
        response_buffer = StringIO(response.text)

        activity_list = pd.read_csv(
            filepath_or_buffer=response_buffer,
            parse_dates={'datetime': ['date', 'time']},
            sep=',\s*',
            engine='python'
        )
        activity_list.rename(columns=lambda x: x.lower(), inplace=True)
        activity_list.rename(
            columns=lambda x: '_' + x if x[0].isdigit() else x, inplace=True)

        activity_list['has_hr'] = activity_list.average_heart_rate.map(bool)
        activity_list['has_spd'] = activity_list.average_speed.map(bool)
        activity_list['has_pwr'] = activity_list.average_power.map(bool)
        activity_list['has_cad'] = activity_list.average_heart_rate.map(bool)
        activity_list['data'] = pd.Series(dtype=np.dtype("object"))
        return activity_list

def _request_activity_list ( self , athlete ) : response = self . _get_request ( self . _athlete_endpoint ( athlete ) ) response_buffer = StringIO ( response . text ) activity_list = pd . read_csv ( filepath_or_buffer = response_buffer , parse_dates = { 'datetime' : [ 'date' , 'time' ] } , sep = ',\s*' , engine = 'python' ) activity_list . rename ( columns = lambda x : x . lower ( ) , inplace = True ) activity_list . rename ( columns = lambda x : '_' + x if x [ 0 ] . isdigit ( ) else x , inplace = True ) activity_list [ 'has_hr' ] = activity_list . average_heart_rate . map ( bool ) activity_list [ 'has_spd' ] = activity_list . average_speed . map ( bool ) activity_list [ 'has_pwr' ] = activity_list . average_power . map ( bool ) activity_list [ 'has_cad' ] = activity_list . average_heart_rate . map ( bool ) activity_list [ 'data' ] = pd . Series ( dtype = np . dtype ( "object" ) ) return activity_list

Actually do the request for activity list This call is slow and therefore this method is memory cached .


def _request_activity_data(self, athlete, filename):
        """Actually do the request for activity filename
        This call is slow and therefore this method is memory cached.

        Keyword arguments:
        athlete -- Full name of athlete
        filename -- filename of request activity (e.g. \'2015_04_29_09_03_16.json\')
        """
        response = self._get_request(self._activity_endpoint(athlete, filename)).json()

        activity = pd.DataFrame(response['RIDE']['SAMPLES'])
        activity = activity.rename(columns=ACTIVITY_COLUMN_TRANSLATION)

        activity.index = pd.to_timedelta(activity.time, unit='s')
        activity.drop('time', axis=1, inplace=True)

        return activity[[i for i in ACTIVITY_COLUMN_ORDER if i in activity.columns]]

def _request_activity_data ( self , athlete , filename ) : response = self . _get_request ( self . _activity_endpoint ( athlete , filename ) ) . json ( ) activity = pd . DataFrame ( response [ 'RIDE' ] [ 'SAMPLES' ] ) activity = activity . rename ( columns = ACTIVITY_COLUMN_TRANSLATION ) activity . index = pd . to_timedelta ( activity . time , unit = 's' ) activity . drop ( 'time' , axis = 1 , inplace = True ) return activity [ [ i for i in ACTIVITY_COLUMN_ORDER if i in activity . columns ] ]

Actually do the request for activity filename This call is slow and therefore this method is memory cached .


def _athlete_endpoint(self, athlete):
        """Construct athlete endpoint from host and athlete name

        Keyword arguments:
        athlete -- Full athlete name
        """
        return '{host}{athlete}'.format(
            host=self.host,
            athlete=quote_plus(athlete)
        )

def _athlete_endpoint ( self , athlete ) : return '{host}{athlete}' . format ( host = self . host , athlete = quote_plus ( athlete ) )


def _activity_endpoint(self, athlete, filename):
        """Construct activity endpoint from host, athlete name and filename

        Keyword arguments:
        athlete -- Full athlete name
        filename -- filename of request activity (e.g. \'2015_04_29_09_03_16.json\')
        """
        return '{host}{athlete}/activity/{filename}'.format(
            host=self.host,
            athlete=quote_plus(athlete),
            filename=filename
        )

def _activity_endpoint ( self , athlete , filename ) : return '{host}{athlete}/activity/{filename}' . format ( host = self . host , athlete = quote_plus ( athlete ) , filename = filename )

Construct activity endpoint from host athlete name and filename


def _get_request(self, endpoint):
        """Do actual GET request to GC REST API
        Also validates responses.

        Keyword arguments:
        endpoint -- full endpoint for GET request
        """
        try:
            response = requests.get(endpoint)
        except requests.exceptions.RequestException:
            raise GoldenCheetahNotAvailable(endpoint)

        if response.text.startswith('unknown athlete'):
            match = re.match(
                pattern='unknown athlete (?P<athlete>.+)',
                string=response.text)
            raise AthleteDoesNotExist(
                athlete=match.groupdict()['athlete'])

        elif response.text == 'file not found':
            match = re.match(
                pattern='.+/activity/(?P<filename>.+)',
                string=endpoint)
            raise ActivityDoesNotExist(
                filename=match.groupdict()['filename'])

        return response

def
_get_request
(
self
,
endpoint
)
:
try
:
response
=
requests
.
get
(
endpoint
)
except
requests
.
exceptions
.
RequestException
:
raise
GoldenCheetahNotAvailable
(
endpoint
)
if
response
.
text
.
startswith
(
'unknown athlete'
)
:
match
=
re
.
match
(
pattern
=
'unknown athlete (?P<athlete>.+)'
,
string
=
response
.
text
)
raise
AthleteDoesNotExist
(
athlete
=
match
.
groupdict
(
)
[
'athlete'
]
)
elif
response
.
text
==
'file not found'
:
match
=
re
.
match
(
pattern
=
'.+/activity/(?P<filename>.+)'
,
string
=
endpoint
)
raise
ActivityDoesNotExist
(
filename
=
match
.
groupdict
(
)
[
'filename'
]
)
return
response

Do actual GET request to GC REST API Also validates responses .


def create(self, tarball_url, env=None, app_name=None):
        """Creates a Heroku app-setup build.

        :param tarball_url: URL of a tarball containing an ``app.json``.
        :param env: (optional) Dict containing environment variable overrides.
        :param app_name: (optional) Name of the Heroku app to create.
        :returns: A tuple with ``(build_id, app_name)``.
        """
        data = self._api.create_build(
            tarball_url=tarball_url,
            env=env,
            app_name=app_name,
        )

        return (data['id'], data['app']['name'])

def create ( self , tarball_url , env = None , app_name = None ) : data = self . _api . create_build ( tarball_url = tarball_url , env = env , app_name = app_name , ) return ( data [ 'id' ] , data [ 'app' ] [ 'name' ] )


def url_with_auth(regex, view, kwargs=None, name=None, prefix=''):
    """
    if view is string based, must be a full path
    """
    from djapiauth.auth import api_auth
    if isinstance(view, six.string_types):  # view is a string, must be full path
        return url(regex, api_auth(import_by_path(prefix + "." + view if prefix else view)))
    elif isinstance(view, (list, tuple)):  # include
        return url(regex, view, name, prefix, **kwargs)
    else:  # view is an object
        return url(regex, api_auth(view))

def
url_with_auth
(
regex
,
view
,
kwargs
=
,
name
=
,
prefix
=
''
)
:
from
djapiauth
.
auth
import
api_auth
if
isinstance
(
view
,
six
.
string_types
)
:
# view is a string, must be full path
return
url
(
regex
,
api_auth
(
import_by_path
(
prefix
+
"."
+
view
if
prefix
else
view
)
)
)
elif
isinstance
(
view
,
(
list
,
tuple
)
)
:
# include
return
url
(
regex
,
view
,
name
,
prefix
,
*
*
kwargs
)
else
:
# view is an object
return
url
(
regex
,
api_auth
(
view
)
)

if view is string based must be a full path


def title(languages=None, genders=None):
    """
    returns a random title

    .. code-block:: python

        >>> d.title()
        u'Mrs.'
        >>> d.title(['es'])
        u'El Sr.'
        >>> d.title(None, [GENDER_FEMALE])
        u'Mrs.'

    :param languages: list of allowed languages. ['en'] if None
    :param genders: list of allowed genders. (GENDER_FEMALE, GENDER_MALE) if None
    """
    languages = languages or ['en']
    genders = genders or (GENDER_FEMALE, GENDER_MALE)

    choices = _get_titles(languages)
    gender = {'m':0, 'f':1}[random.choice(genders)]

    return random.choice(choices)[gender]

def title ( languages = None , genders = None ) : languages = languages or [ 'en' ] genders = genders or ( GENDER_FEMALE , GENDER_MALE ) choices = _get_titles ( languages ) gender = { 'm' : 0 , 'f' : 1 } [ random . choice ( genders ) ] return random . choice ( choices ) [ gender ]


def person(languages=None, genders=None):
    """
    returns a random tuple representing person information

    .. code-block:: python

        >>> d.person()
        (u'Derren', u'Powell', 'm')
        >>> d.person(genders=['f'])
        (u'Marge', u'Rodriguez', u'Mrs.', 'f')
        >>> d.person(['es'],['m'])
        (u'Jacinto', u'Delgado', u'El Sr.', 'm')

    :param language:
    :param genders:
    """
    languages = languages or ['en']
    genders = genders or (GENDER_FEMALE, GENDER_MALE)

    lang = random.choice(languages)
    g = random.choice(genders)
    t = title([lang], [g])
    return first_name([lang], [g]), last_name([lang]), t, g

def person ( languages = None , genders = None ) : languages = languages or [ 'en' ] genders = genders or ( GENDER_FEMALE , GENDER_MALE ) lang = random . choice ( languages ) g = random . choice ( genders ) t = title ( [ lang ] , [ g ] ) return first_name ( [ lang ] , [ g ] ) , last_name ( [ lang ] ) , t , g


def last_name(languages=None):
    """
        return a random last name

    >>> from mock import patch
    >>> with patch('%s._get_lastnames' % __name__, lambda *args: ['aaa']):
    ...     last_name()
    'Aaa'
    >>> with patch('%s.get_lastnames' % __name__, lambda lang: ['%s_lastname'% lang]):
    ...     last_name(['it'])
    'It_Lastname'
    """
    choices = []
    languages = languages or ['en']
    for lang in languages:
        samples = _get_lastnames(lang)
        choices.extend(samples)
    return random.choice(choices).title()

def last_name ( languages = None ) : choices = [ ] languages = languages or [ 'en' ] for lang in languages : samples = _get_lastnames ( lang ) choices . extend ( samples ) return random . choice ( choices ) . title ( )


def render(self):
        """Render the axes data into the dict data"""
        for opt,values in self.data.items():
            if opt == 'ticks':
                self['chxtc'] = '|'.join(values)
            else:
                self['chx%s'%opt[0]] = '|'.join(values)
        return self

def render ( self ) : for opt , values in self . data . items ( ) : if opt == 'ticks' : self [ 'chxtc' ] = '|' . join ( values ) else : self [ 'chx%s' % opt [ 0 ] ] = '|' . join ( values ) return self


def dataset(self, data, series=''):
        """
        Update the chart's dataset, can be two dimensional or contain string data
        """
        self._dataset = data
        self._series = series
        return self

def dataset ( self , data , series = '' ) : self . _dataset = data self . _series = series return self

Update the chart s dataset can be two dimensional or contain string data


def render(self):
        """
        Renders the chart context and axes into the dict data
        """
        self.update(self.axes.render())
        encoder = Encoder(self._encoding, None, self._series)
        if not 'chs' in self:
            self['chs'] = '300x150'
        else:
            size = self['chs'].split('x')
            assert len(size) == 2, 'Invalid size, must be in the format WxH'
            self.check_size(*map(int,size))
        assert 'cht' in self, 'No chart type defined, use type method'
        self['cht'] = self.check_type(self['cht'])
        if ('any' in dir(self._dataset) and self._dataset.any()) or self._dataset:
            self['chd'] = encoder.encode(self._dataset)
        elif not 'choe' in self:
            assert 'chd' in self, 'You must have a dataset, or use chd'
        if self._scale:
            assert self['chd'].startswith('t'),\
                'You must use text encoding with chds'
            self['chds'] = ','.join(self._scale)
        if self._geo and self._ld:
            self['chtm'] = self._geo
            self['chld'] = self._ld
        if self.lines:
            self['chls'] = '|'.join(self.lines)
        if self.markers:
            self['chm'] = '|'.join(self.markers)
        if self.fills:
            self['chf'] = '|'.join(self.fills)


def check_type(self, type):
        """Check to see if the type is either in TYPES or fits type name

        Returns proper type
        """
        if type in TYPES:
            return type
        tdict = dict(zip(TYPES,TYPES))
        tdict.update({
            'line': 'lc',
            'bar': 'bvs',
            'pie': 'p',
            'venn': 'v',
            'scater': 's',
            'radar': 'r',
            'meter': 'gom',
        })
        assert type in tdict, 'Invalid chart type: %s'%type
        return tdict[type]

def
check_type
(
self
,
type
)
:
if
type
in
TYPES
:
return
type
tdict
=
dict
(
zip
(
TYPES
,
TYPES
)
)
tdict
.
update
(
{
'line'
:
'lc'
,
'bar'
:
'bvs'
,
'pie'
:
'p'
,
'venn'
:
'v'
,
'scater'
:
's'
,
'radar'
:
'r'
,
'meter'
:
'gom'
,
}
)
assert
type
in
tdict
,
'Invalid chart type: %s'
%
type
return
tdict
[
type
]


def url(self):
        """
        Returns the rendered URL of the chart
        """
        self.render()
        return self._apiurl + '&'.join(self._parts()).replace(' ','+')

def
url
(
self
)
:
self
.
render
(
)
return
self
.
_apiurl
+
'&'
.
join
(
self
.
_parts
(
)
)
.
replace
(
' '
,
'+'
)


def show(self, *args, **kwargs):
        """
        Shows the chart URL in a webbrowser

        Other arguments passed to webbrowser.open
        """
        from webbrowser import open as webopen
        return webopen(str(self), *args, **kwargs)

def show ( self , * args , * * kwargs ) : from webbrowser import open as webopen return webopen ( str ( self ) , * args , * * kwargs )


def save(self, fname=None):
        """
        Download the chart from the URL into a filename as a PNG

        The filename defaults to the chart title (chtt) if any
        """
        if not fname:
            fname = self.getname()
        assert fname != None, 'You must specify a filename to save to'
        if not fname.endswith('.png'):
            fname += '.png'
        try:
            urlretrieve(self.url, fname)
        except Exception:
            raise IOError('Problem saving %s to file'%fname)
        return fname


def urlopen(self):
        """
        Grabs readable PNG file pointer
        """
        req = Request(str(self))
        try:
            return urlopen(req)
        except HTTPError:
            _print('The server couldn\'t fulfill the request.')
        except URLError:
            _print('We failed to reach a server.')


def image(self):
        """
        Returns a PngImageFile instance of the chart

        You must have PIL installed for this to work
        """
        try:
            try:
                import Image
            except ImportError:
                from PIL import Image
        except ImportError:
            raise ImportError('You must install PIL to fetch image objects')
        try:
            from cStringIO import StringIO
        except ImportError:
            from StringIO import StringIO
        return Image.open(StringIO(self.urlopen().read()))


def write(self, fp):
        """
        Writes out PNG image data in chunks to file pointer fp

        fp must support w or wb
        """
        urlfp = self.urlopen().fp
        while 1:
            try:
                fp.write(urlfp.next())
            except StopIteration:
                return

def write ( self , fp ) : urlfp = self . urlopen ( ) . fp while 1 : try : fp . write ( urlfp . next ( ) ) except StopIteration : return


def checksum(self):
        """
        Returns the unique SHA1 hexdigest of the chart URL param parts

        good for unittesting...
        """
        self.render()
        return new_sha(''.join(sorted(self._parts()))).hexdigest()

def checksum ( self ) : self . render ( ) return new_sha ( '' . join ( sorted ( self . _parts ( ) ) ) ) . hexdigest ( )


def amount(min=1, max=sys.maxsize, decimal_places=2):
    """
        return a random floating number

    :param min: minimum value
    :param max: maximum value
    :param decimal_places: decimal places
    :return:
    """
    q = '.%s1' % '0' * (decimal_places - 1)
    return decimal.Decimal(uniform(min, max)).quantize(decimal.Decimal(q))

def amount ( min = 1 , max = sys . maxsize , decimal_places = 2 ) : q = '.%s1' % '0' * ( decimal_places - 1 ) return decimal . Decimal ( uniform ( min , max ) ) . quantize ( decimal . Decimal ( q ) )


def entity_name_decorator(top_cls):
    """
    Assign an entity name based on the class immediately inhering from Base.

    This is needed because we don't want
    entity names to come from any class that simply inherits our classes,
    just the ones in our module.

    For example, if you create a class Project2 that exists outside of
    kalibro_client and inherits from Project, it's entity name should still
    be Project.
    """
    class_name = inflection.underscore(top_cls.__name__).lower()

    def entity_name(cls):
        return class_name

    top_cls.entity_name = classmethod(entity_name)

    return top_cls

def entity_name_decorator ( top_cls ) : class_name = inflection . underscore ( top_cls . __name__ ) . lower ( ) def entity_name ( cls ) : return class_name top_cls . entity_name = classmethod ( entity_name ) return top_cls

Assign an entity name based on the class immediately inhering from Base .


def unprotected_and_protected_claims(self):
        """
        This is both verified and self asserted information. As expected
        verified information beats self-asserted so if there is both
        self-asserted and verified values for a claim then only the verified
        will be returned.
        """
        if self.sup:
            res = {}
            for k, v in self.le.items():
                if k not in self.sup.le:
                    res[k] = v
                else:
                    res[k] = self.sup.le[k]
            return res
        else:
            return self.le

def unprotected_and_protected_claims ( self ) : if self . sup : res = { } for k , v in self . le . items ( ) : if k not in self . sup . le : res [ k ] = v else : res [ k ] = self . sup . le [ k ] return res else : return self . le

This is both verified and self asserted information . As expected verified information beats self - asserted so if there is both self - asserted and verified values for a claim then only the verified will be returned .


def signing_keys_as_jwks(self):
        """
        Build a JWKS from the signing keys belonging to the self signer

        :return: Dictionary
        """
        _l = [x.serialize() for x in self.self_signer.keyjar.get_signing_key()]
        if not _l:
            _l = [x.serialize() for x in
                  self.self_signer.keyjar.get_signing_key(owner=self.iss)]
        return {'keys': _l}

def signing_keys_as_jwks ( self ) : _l = [ x . serialize ( ) for x in self . self_signer . keyjar . get_signing_key ( ) ] if not _l : _l = [ x . serialize ( ) for x in self . self_signer . keyjar . get_signing_key ( owner = self . iss ) ] return { 'keys' : _l }


def unpack_metadata_statement(self, ms_dict=None, jwt_ms='', keyjar=None,
                                  cls=ClientMetadataStatement, liss=None):
        """
        Starting with a signed JWT or a JSON document unpack and verify all
        the separate metadata statements.

        :param ms_dict: Metadata statement as a dictionary
        :param jwt_ms: Metadata statement as JWT
        :param keyjar: Keys that should be used to verify the signature of the
            document
        :param cls: What type (Class) of metadata statement this is
        :param liss: list of FO identifiers that matters. The rest will be
            ignored
        :return: A ParseInfo instance
        """

        if not keyjar:
            if self.jwks_bundle:
                keyjar = self.jwks_bundle.as_keyjar()
            else:
                keyjar = KeyJar()

        if jwt_ms:
            try:
                ms_dict = unfurl(jwt_ms)
            except JWSException as err:
                logger.error('Could not unfurl jwt_ms due to {}'.format(err))
                raise

        if ms_dict:
            return self._unpack(ms_dict, keyjar, cls, jwt_ms, liss)
        else:
            raise AttributeError('Need one of ms_dict or jwt_ms')

def
unpack_metadata_statement
(
self
,
ms_dict
=
,
jwt_ms
=
''
,
keyjar
=
,
cls
=
ClientMetadataStatement
,
liss
=
)
:
if
not
keyjar
:
if
self
.
jwks_bundle
:
keyjar
=
self
.
jwks_bundle
.
as_keyjar
(
)
else
:
keyjar
=
KeyJar
(
)
if
jwt_ms
:
try
:
ms_dict
=
unfurl
(
jwt_ms
)
except
JWSException
as
err
:
logger
.
error
(
'Could not unfurl jwt_ms due to {}'
.
format
(
err
)
)
raise
if
ms_dict
:
return
self
.
_unpack
(
ms_dict
,
keyjar
,
cls
,
jwt_ms
,
liss
)
else
:
raise
AttributeError
(
'Need one of ms_dict or jwt_ms'
)

Starting with a signed JWT or a JSON document unpack and verify all the separate metadata statements .


def pack_metadata_statement(self, metadata, receiver='', iss='', lifetime=0,
                                sign_alg=''):
        """
        Given a MetadataStatement instance create a signed JWT.

        :param metadata: Original metadata statement as a MetadataStatement
            instance
        :param receiver: Receiver (audience) of the JWT
        :param iss: Issuer ID if different from default
        :param lifetime: jWT signature life time
        :param sign_alg: JWT signature algorithm
        :return: A JWT
        """

        return self.self_signer.sign(metadata, receiver=receiver, iss=iss,
                                     lifetime=lifetime, sign_alg=sign_alg)

def pack_metadata_statement ( self , metadata , receiver = '' , iss = '' , lifetime = 0 , sign_alg = '' ) : return self . self_signer . sign ( metadata , receiver = receiver , iss = iss , lifetime = lifetime , sign_alg = sign_alg )

Given a MetadataStatement instance create a signed JWT .


def evaluate_metadata_statement(self, metadata, keyjar=None):
        """
        Computes the resulting metadata statement from a compounded metadata
        statement.
        If something goes wrong during the evaluation an exception is raised

        :param metadata: The compounded metadata statement as a dictionary
        :return: A list of :py:class:`fedoidc.operator.LessOrEqual`
            instances, one per FO.
        """

        # start from the innermost metadata statement and work outwards

        res = dict([(k, v) for k, v in metadata.items() if k not in IgnoreKeys])

        les = []

        if 'metadata_statements' in metadata:
            for fo, ms in metadata['metadata_statements'].items():
                if isinstance(ms, str):
                    ms = json.loads(ms)
                for _le in self.evaluate_metadata_statement(ms):
                    if isinstance(ms, Message):
                        le = LessOrEqual(sup=_le, **ms.to_dict())
                    else:  # Must be a dict
                        le = LessOrEqual(sup=_le, **ms)

                    if le.is_expired():
                        logger.error(
                            'This metadata statement has expired: {}'.format(ms)
                        )
                        logger.info('My time: {}'.format(utc_time_sans_frac()))
                        continue
                    le.eval(res)
                    les.append(le)
            return les
        else:  # this is the innermost
            try:
                _iss = metadata['iss']
            except:
                le = LessOrEqual()
                le.eval(res)
            else:
                le = LessOrEqual(iss=_iss, exp=metadata['exp'])
                le.eval(res)
            les.append(le)
            return les

Computes the resulting metadata statement from a compounded metadata statement . If something goes wrong during the evaluation an exception is raised


def correct_usage(self, metadata, federation_usage):
        """
        Remove MS paths that are marked to be used for another usage

        :param metadata: Metadata statement as dictionary
        :param federation_usage: In which context this is expected to used.
        :return: Filtered Metadata statement.
        """

        if 'metadata_statements' in metadata:
            _msl = {}
            for fo, ms in metadata['metadata_statements'].items():
                if not isinstance(ms, Message):
                    ms = json.loads(ms)

                if self.correct_usage(ms, federation_usage=federation_usage):
                    _msl[fo] = ms
            if _msl:
                metadata['metadata_statements'] = Message(**_msl)
                return metadata
            else:
                return None
        else:  # this is the innermost
            try:
                assert federation_usage == metadata['federation_usage']
            except KeyError:
                pass
            except AssertionError:
                return None
            return metadata

def
correct_usage
(
self
,
metadata
,
federation_usage
)
:
if
'metadata_statements'
in
metadata
:
_msl
=
{
}
for
fo
,
ms
in
metadata
[
'metadata_statements'
]
.
items
(
)
:
if
not
isinstance
(
ms
,
Message
)
:
ms
=
json
.
loads
(
ms
)
if
self
.
correct_usage
(
ms
,
federation_usage
=
federation_usage
)
:
_msl
[
fo
]
=
ms
if
_msl
:
metadata
[
'metadata_statements'
]
=
Message
(
*
*
_msl
)
return
metadata
else
:
return
else
:
# this is the innermost
try
:
assert
federation_usage
==
metadata
[
'federation_usage'
]
except
KeyError
:
pass
except
AssertionError
:
return
return
metadata


def extend_with_ms(self, req, sms_dict):
        """
        Add signed metadata statements to a request

        :param req: The request
        :param sms_dict: A dictionary with FO IDs as keys and signed metadata
            statements (sms) or uris pointing to sms as values.
        :return: The updated request
        """
        _ms_uri = {}
        _ms = {}
        for fo, sms in sms_dict.items():
            if sms.startswith('http://') or sms.startswith('https://'):
                _ms_uri[fo] = sms
            else:
                _ms[fo] = sms

        if _ms:
            req['metadata_statements'] = Message(**_ms)
        if _ms_uri:
            req['metadata_statement_uris'] = Message(**_ms_uri)
        return req

def extend_with_ms ( self , req , sms_dict ) : _ms_uri = { } _ms = { } for fo , sms in sms_dict . items ( ) : if sms . startswith ( 'http://' ) or sms . startswith ( 'https://' ) : _ms_uri [ fo ] = sms else : _ms [ fo ] = sms if _ms : req [ 'metadata_statements' ] = Message ( * * _ms ) if _ms_uri : req [ 'metadata_statement_uris' ] = Message ( * * _ms_uri ) return req


def parse_args():
    """
    Parses command line args using argparse library
    """
    usage = "Usage: create_concordance <infile> [<outfile>]"
    description = "Simple Concordance Generator"
    argparser = argparse.ArgumentParser(
        usage=usage, description=description)

    argparser.add_argument(
        'infile', type=argparse.FileType('r'),
        help="File read in to create concordance")

    argparser.add_argument(
        'outfile', nargs='?', type=argparse.FileType('w'),
        default=sys.stdout, help="File to write concordance to.  "
        "Default is stdout")

    argparser.add_argument(
        '--word', nargs="?", const=str, help="Display a word in concordance")
    args = argparser.parse_args()
    return args


def addCommandLineArgs(arg_parser):
    """Add logging option to an ArgumentParser."""
    arg_parser.register("action", "log_levels", LogLevelAction)
    arg_parser.register("action", "log_files", LogFileAction)
    arg_parser.register("action", "log_help", LogHelpAction)

    group = arg_parser.add_argument_group("Logging options")
    group.add_argument(
        "-l", "--log-level", dest="log_levels",
        action="log_levels", metavar="LOGGER:LEVEL", default=[],
        help="Set log levels for individual loggers. See --help-logging for "
             "complete details.")

    group.add_argument(
        "-L", "--log-file", dest="log_files",
        action="log_files", metavar="LOGGER:FILE", default=[],
        help="Set log the output file for individual loggers. "
             " See --help-logging for complete details.")

    group.add_argument("--help-logging", action="log_help",
                       help=argparse.SUPPRESS)

Add logging option to an ArgumentParser .


def applyLoggingOpts(log_levels, log_files):
    """Apply logging options produced by LogLevelAction and LogFileAction.

    More often then not this function is not needed, the actions have already
    been taken during the parse, but it can be used in the case they need to be
    applied again (e.g. when command line opts take precedence but were
    overridded by a fileConfig, etc.).
    """
    for l, lvl in log_levels:
        l.setLevel(lvl)
    for l, hdl in log_files:
        for h in l.handlers:
            l.removeHandler(h)
        l.addHandler(hdl)

def applyLoggingOpts ( log_levels , log_files ) : for l , lvl in log_levels : l . setLevel ( lvl ) for l , hdl in log_files : for h in l . handlers : l . removeHandler ( h ) l . addHandler ( hdl )

Apply logging options produced by LogLevelAction and LogFileAction .


def verbose(self, msg, *args, **kwargs):
        """Log msg at 'verbose' level, debug < verbose < info"""
        self.log(logging.VERBOSE, msg, *args, **kwargs)

def verbose ( self , msg , * args , * * kwargs ) : self . log ( logging . VERBOSE , msg , * args , * * kwargs )

Log msg at verbose level debug < verbose < info


def _letter_map(word):
    """Creates a map of letter use in a word.

    Args:
        word: a string to create a letter map from

    Returns:
        a dictionary of {letter: integer count of letter in word}
    """

    lmap = {}
    for letter in word:
        try:
            lmap[letter] += 1
        except KeyError:
            lmap[letter] = 1
    return lmap

def _letter_map ( word ) : lmap = { } for letter in word : try : lmap [ letter ] += 1 except KeyError : lmap [ letter ] = 1 return lmap


def anagrams_in_word(word, sowpods=False, start="", end=""):
    """Finds anagrams in word.

    Args:
        word: the string to base our search off of
        sowpods: boolean to declare TWL or SOWPODS words file
        start: a string of starting characters to find anagrams based on
        end: a string of ending characters to find anagrams based on

    Yields:
        a tuple of (word, score) that can be made with the input_word
    """

    input_letters, blanks, questions = blank_tiles(word)

    for tile in start + end:
        input_letters.append(tile)

    for word in word_list(sowpods, start, end):
        lmap = _letter_map(input_letters)
        used_blanks = 0
        for letter in word:
            if letter in lmap:
                lmap[letter] -= 1
                if lmap[letter] < 0:
                    used_blanks += 1
                    if used_blanks > (blanks + questions):
                        break
            else:
                used_blanks += 1
                if used_blanks > (blanks + questions):
                    break
        else:
            yield (word, word_score(word, input_letters, questions))

def anagrams_in_word ( word , sowpods = False , start = "" , end = "" ) : input_letters , blanks , questions = blank_tiles ( word ) for tile in start + end : input_letters . append ( tile ) for word in word_list ( sowpods , start , end ) : lmap = _letter_map ( input_letters ) used_blanks = 0 for letter in word : if letter in lmap : lmap [ letter ] -= 1 if lmap [ letter ] < 0 : used_blanks += 1 if used_blanks > ( blanks + questions ) : break else : used_blanks += 1 if used_blanks > ( blanks + questions ) : break else : yield ( word , word_score ( word , input_letters , questions ) )


def asAMP(cls):
        """
        Returns the exception's name in an AMP Command friendly format.

        For example, given a class named ``ExampleExceptionClass``, returns
        ``"EXAMPLE_EXCEPTION_CLASS"``.
        """
        parts = groupByUpperCase(cls.__name__)
        return cls, "_".join(part.upper() for part in parts)

def asAMP ( cls ) : parts = groupByUpperCase ( cls . __name__ ) return cls , "_" . join ( part . upper ( ) for part in parts )

Returns the exception s name in an AMP Command friendly format .


def transform_timeseries_data(timeseries, start, end=None):
    """Transforms a Go Metrics API metric result into a list of
    values for a given window period.

    start and end are expected to be Unix timestamps in microseconds.
    """
    data = []
    include = False
    for metric, points in timeseries.items():
        for point in points:
            if point['x'] == start:
                include = True
            if include:
                data.append(point['y'])
            if end is not None and point['x'] == end:
                return data
    return data

def transform_timeseries_data ( timeseries , start , end = None ) : data = [ ] include = False for metric , points in timeseries . items ( ) : for point in points : if point [ 'x' ] == start : include = True if include : data . append ( point [ 'y' ] ) if end is not None and point [ 'x' ] == end : return data return data

Transforms a Go Metrics API metric result into a list of values for a given window period .


def get_last_value_from_timeseries(timeseries):
    """Gets the most recent non-zero value for a .last metric or zero
    for empty data."""
    if not timeseries:
        return 0
    for metric, points in timeseries.items():
        return next((p['y'] for p in reversed(points) if p['y'] > 0), 0)

def get_last_value_from_timeseries ( timeseries ) : if not timeseries : return 0 for metric , points in timeseries . items ( ) : return next ( ( p [ 'y' ] for p in reversed ( points ) if p [ 'y' ] > 0 ) , 0 )

Gets the most recent non - zero value for a . last metric or zero for empty data .


def validate_page_number(number):
    """Validate the given 1-based page number."""
    try:
        number = int(number)
    except (TypeError, ValueError):
        raise PageNotAnInteger('That page number is not an integer')
    if number < 1:
        raise EmptyPage('That page number is less than 1')
    return number

def
validate_page_number
(
number
)
:
try
:
number
=
int
(
number
)
except
(
TypeError
,
ValueError
)
:
raise
PageNotAnInteger
(
'That page number is not an integer'
)
if
number
<
1
:
raise
EmptyPage
(
'That page number is less than 1'
)
return
number

Validate the given 1 - based page number .


def get_page_of_iterator(iterator, page_size, page_number):
    """
    Get a page from an interator, handling invalid input from the page number
    by defaulting to the first page.
    """
    try:
        page_number = validate_page_number(page_number)
    except (PageNotAnInteger, EmptyPage):
        page_number = 1

    start = (page_number - 1) * page_size
    # End 1 more than we need, so that we can see if there's another page
    end = (page_number * page_size) + 1
    skipped_items = list(islice(iterator, start))
    items = list(islice(iterator, end))

    if len(items) == 0 and page_number != 1:
        items = skipped_items
        page_number = 1

    has_next = len(items) > page_size
    items = items[:page_size]

    return NoCountPage(items, page_number, page_size, has_next)

Get a page from an interator handling invalid input from the page number by defaulting to the first page .


def chmod(path, mode, recursive=True):
    """ alternative to os.
    """

    if recursive:
        cmd = 'chmod -R %s %s' % (mode, path)
    else:
        cmd = 'chmod %s %s' % (mode, path)

    return sh(cmd)

def
chmod
(
path
,
mode
,
recursive
=
True
)
:
if
recursive
:
cmd
=
'chmod -R %s %s'
%
(
mode
,
path
)
else
:
cmd
=
'chmod %s %s'
%
(
mode
,
path
)
return
sh
(
cmd
)


def make_internal_signing_service(config, entity_id):
    """
    Given configuration initiate an InternalSigningService instance

    :param config: The signing service configuration
    :param entity_id: The entity identifier
    :return: A InternalSigningService instance
    """

    _args = dict([(k, v) for k, v in config.items() if k in KJ_SPECS])
    _kj = init_key_jar(**_args)

    return InternalSigningService(entity_id, _kj)

def make_internal_signing_service ( config , entity_id ) : _args = dict ( [ ( k , v ) for k , v in config . items ( ) if k in KJ_SPECS ] ) _kj = init_key_jar ( * * _args ) return InternalSigningService ( entity_id , _kj )


def make_signing_service(config, entity_id):
    """
    Given configuration initiate a SigningService instance

    :param config: The signing service configuration
    :param entity_id: The entity identifier
    :return: A SigningService instance
    """

    _args = dict([(k, v) for k, v in config.items() if k in KJ_SPECS])
    _kj = init_key_jar(**_args)

    if config['type'] == 'internal':
        signer = InternalSigningService(entity_id, _kj)
    elif config['type'] == 'web':
        _kj.issuer_keys[config['iss']] = _kj.issuer_keys['']
        del _kj.issuer_keys['']
        signer = WebSigningServiceClient(config['iss'], config['url'],
                                         entity_id, _kj)
    else:
        raise ValueError('Unknown signer type: {}'.format(config['type']))

    return signer

def
make_signing_service
(
config
,
entity_id
)
:
_args
=
dict
(
[
(
k
,
v
)
for
k
,
v
in
config
.
items
(
)
if
k
in
KJ_SPECS
]
)
_kj
=
init_key_jar
(
*
*
_args
)
if
config
[
'type'
]
==
'internal'
:
signer
=
InternalSigningService
(
entity_id
,
_kj
)
elif
config
[
'type'
]
==
'web'
:
_kj
.
issuer_keys
[
config
[
'iss'
]
]
=
_kj
.
issuer_keys
[
''
]
del
_kj
.
issuer_keys
[
''
]
signer
=
WebSigningServiceClient
(
config
[
'iss'
]
,
config
[
'url'
]
,
entity_id
,
_kj
)
else
:
raise
ValueError
(
'Unknown signer type: {}'
.
format
(
config
[
'type'
]
)
)
return
signer


def sign(self, req, receiver='', iss='', lifetime=0, sign_alg='', aud=None):
        """
        Creates a signed JWT

        :param req: Original metadata statement as a
            :py:class:`MetadataStatement` instance
        :param receiver: The intended audience for the JWS
        :param iss: Issuer or the JWT
        :param lifetime: Lifetime of the signature
        :param sign_alg: Which signature algorithm to use
        :param aud: The audience, a list of receivers.
        :return: A signed JWT
        """
        if not sign_alg:
            for key_type, s_alg in [('RSA', 'RS256'), ('EC', 'ES256')]:
                if self.keyjar.get_signing_key(key_type=key_type):
                    sign_alg = s_alg
                    break

        if not sign_alg:
            raise NoSigningKeys('Could not find any signing keys')

        return self.pack(req=req, receiver=receiver, iss=iss, lifetime=lifetime,
                         sign=True, encrypt=False, sign_alg=sign_alg)

def
sign
(
self
,
req
,
receiver
=
''
,
iss
=
''
,
lifetime
=
0
,
sign_alg
=
''
,
aud
=
)
:
if
not
sign_alg
:
for
key_type
,
s_alg
in
[
(
'RSA'
,
'RS256'
)
,
(
'EC'
,
'ES256'
)
]
:
if
self
.
keyjar
.
get_signing_key
(
key_type
=
key_type
)
:
sign_alg
=
s_alg
break
if
not
sign_alg
:
raise
NoSigningKeys
(
'Could not find any signing keys'
)
return
self
.
pack
(
req
=
req
,
receiver
=
receiver
,
iss
=
iss
,
lifetime
=
lifetime
,
sign
=
True
,
encrypt
=
False
,
sign_alg
=
sign_alg
)


def create(self, req, **kwargs):
        """
        Uses POST to send a first metadata statement signing request to
        a signing service.

        :param req: The metadata statement that the entity wants signed
        :return: returns a dictionary with 'sms' and 'loc' as keys.
        """

        response = requests.post(self.url, json=req, **self.req_args())
        return self.parse_response(response)

def create ( self , req , * * kwargs ) : response = requests . post ( self . url , json = req , * * self . req_args ( ) ) return self . parse_response ( response )

Uses POST to send a first metadata statement signing request to a signing service .


def update_metadata_statement(self, location, req):
        """
        Uses PUT to update an earlier accepted and signed metadata statement.

        :param location: A URL to which the update request is sent
        :param req: The diff between what is registereed with the signing
            service and what it should be.
        :return: returns a dictionary with 'sms' and 'loc' as keys.
        """
        response = requests.put(location, json=req, **self.req_args())
        return self.parse_response(response)

def update_metadata_statement ( self , location , req ) : response = requests . put ( location , json = req , * * self . req_args ( ) ) return self . parse_response ( response )

Uses PUT to update an earlier accepted and signed metadata statement .


def update_signature(self, location):
        """
        Uses GET to get a newly signed metadata statement.

        :param location: A URL to which the request is sent
        :return: returns a dictionary with 'sms' and 'loc' as keys.
        """
        response = requests.get(location, **self.req_args())
        return self.parse_response(response)

def update_signature ( self , location ) : response = requests . get ( location , * * self . req_args ( ) ) return self . parse_response ( response )

Uses GET to get a newly signed metadata statement .


def _yield_bundle_contents(self, data):
        """Yield bundle contents from the given dict.

        Each item yielded will be either a string representing a file path
        or a bundle."""
        if isinstance(data, list):
            contents = data
        else:
            contents = data.get('contents', [])
            if isinstance(contents, six.string_types):
                contents = contents,
        for content in contents:
            if isinstance(content, dict):
                content = self._create_bundle(content)
            yield content

def _yield_bundle_contents ( self , data ) : if isinstance ( data , list ) : contents = data else : contents = data . get ( 'contents' , [ ] ) if isinstance ( contents , six . string_types ) : contents = contents , for content in contents : if isinstance ( content , dict ) : content = self . _create_bundle ( content ) yield content

Yield bundle contents from the given dict .


def _create_bundle(self, data):
        """Return a bundle initialised by the given dict."""
        kwargs = {}
        filters = None
        if isinstance(data, dict):
            kwargs.update(
                filters=data.get('filters', None),
                output=data.get('output', None),
                debug=data.get('debug', None),
                extra=data.get('extra', {}),
                config=data.get('config', {}),
                depends=data.get('depends', None))
        bundle = Bundle(*list(self._yield_bundle_contents(data)), **kwargs)
        return self._auto_filter_bundle(bundle)

def _create_bundle ( self , data ) : kwargs = { } filters = None if isinstance ( data , dict ) : kwargs . update ( filters = data . get ( 'filters' , None ) , output = data . get ( 'output' , None ) , debug = data . get ( 'debug' , None ) , extra = data . get ( 'extra' , { } ) , config = data . get ( 'config' , { } ) , depends = data . get ( 'depends' , None ) ) bundle = Bundle ( * list ( self . _yield_bundle_contents ( data ) ) , * * kwargs ) return self . _auto_filter_bundle ( bundle )

Return a bundle initialised by the given dict .


def urls_for(self, asset_type, *args, **kwargs):
        """Returns urls needed to include all assets of asset_type
        """
        return self.urls_for_depends(asset_type, *args, **kwargs) + \
               self.urls_for_self(asset_type, *args, **kwargs)

def urls_for ( self , asset_type , * args , * * kwargs ) : return self . urls_for_depends ( asset_type , * args , * * kwargs ) + self . urls_for_self ( asset_type , * args , * * kwargs )


def html_tags_for(self, asset_type, *args, **kwargs):
        """Return html tags for urls of asset_type
        """
        html = []
        for ref in self.depends:
            html.append(self._ref(ref).html_tags_for(asset_type, *args, **kwargs))
        if asset_type in self.typed_bundles:
            html.append(render_asset_html_tags(asset_type, self.urls_for_self(asset_type, *args, **kwargs)))
        return "\n".join(html)

def html_tags_for ( self , asset_type , * args , * * kwargs ) : html = [ ] for ref in self . depends : html . append ( self . _ref ( ref ) . html_tags_for ( asset_type , * args , * * kwargs ) ) if asset_type in self . typed_bundles : html . append ( render_asset_html_tags ( asset_type , self . urls_for_self ( asset_type , * args , * * kwargs ) ) ) return "\n" . join ( html )


def html_tags(self, *args, **kwargs):
        """Return all html tags for all asset_type
        """
        html = []
        for asset_type in list_asset_types():
            html.append(self.html_tags_for(asset_type.name, *args, **kwargs))
        return "\n".join(html)

def html_tags ( self , * args , * * kwargs ) : html = [ ] for asset_type in list_asset_types ( ) : html . append ( self . html_tags_for ( asset_type . name , * args , * * kwargs ) ) return "\n" . join ( html )


def protocolise(url):
    """
    Given a URL, check to see if there is an assocaited protocol.

    If not, set the protocol to HTTP and return the protocolised URL
    """
    # Use the regex to match http//localhost/something
    protore = re.compile(r'https?:{0,1}/{1,2}')
    parsed = urlparse.urlparse(url)
    if not parsed.scheme and not protore.search(url):
        url = 'http://{0}'.format(url)
    return url

Given a URL check to see if there is an assocaited protocol .


def find_links(url):
    """
    Find the href destinations of all links at  URL

    Arguments:
    - `url`:

    Return: list[str]
    Exceptions: None
    """
    url = protocolise(url)
    content = requests.get(url).content
    flike = StringIO(content)
    root = html.parse(flike).getroot()
    atags = root.cssselect('a')
    hrefs = [a.attrib['href'] for a in atags]
    # !!! This does the wrong thing for bbc.co.uk/index.html
    hrefs = [h if h.startswith('http') else '/'.join([url, h]) for h in hrefs ]
    return hrefs


def _connected(client):
    """
    Connected to AMP server, start listening locally, and give the AMP
    client a reference to the local listening factory.
    """
    log.msg("Connected to AMP server, starting to listen locally...")
    localFactory = multiplexing.ProxyingFactory(client, "hello")
    return listeningEndpoint.listen(localFactory)

Connected to AMP server start listening locally and give the AMP client a reference to the local listening factory .


def get_modules(self):
        """Get modules by project_abspath and packages_scan.

        Traverse all files under folder packages_scan which set by customer.
        And get all modules name.
        """
        if not self.project_abspath:
            raise TypeError("project_abspath can not be empty.")
        packages_abspath = self.get_package_abspath()
        for package_abspath in packages_abspath:
            self.get_module_name(package_abspath)

        return self._modules

def
get_modules
(
self
)
:
if
not
self
.
project_abspath
:
raise
TypeError
(
"project_abspath can not be empty."
)
packages_abspath
=
self
.
get_package_abspath
(
)
for
package_abspath
in
packages_abspath
:
self
.
get_module_name
(
package_abspath
)
return
self
.
_modules

Get modules by project_abspath and packages_scan .


def import_modules(self):
        """Import customer's service module."""
        modules = self.get_modules()
        log.info("import service modules: " + str(modules))
        try:
            for module in modules:
                __import__(module)
        except ImportError as error:
            raise ImportModulesError(error.msg)

def
import_modules
(
self
)
:
modules
=
self
.
get_modules
(
)
log
.
info
(
"import service modules: "
+
str
(
modules
)
)
try
:
for
module
in
modules
:
__import__
(
module
)
except
ImportError
as
error
:
raise
ImportModulesError
(
error
.
msg
)


def to_dates(param):
    """
    This function takes a date string in various formats
    and converts it to a normalized and validated date range. A list
    with two elements is returned, lower and upper date boundary.

    Valid inputs are, for example:
    2012              => Jan 1 20012 - Dec 31 2012 (whole year)
    201201            => Jan 1 2012  - Jan 31 2012 (whole month)
    2012101           => Jan 1 2012 - Jan 1 2012   (whole day)
    2011-2011         => same as "2011", which means whole year 2012
    2011-2012         => Jan 1 2011 - Dec 31 2012  (two years)
    201104-2012       => Apr 1 2011 - Dec 31 2012
    201104-201203     => Apr 1 2011 - March 31 2012
    20110408-2011     => Apr 8 2011 - Dec 31 2011
    20110408-201105   => Apr 8 2011 - May 31 2011
    20110408-20110507 => Apr 8 2011 - May 07 2011
    2011-             => Jan 1 2012 - Dec 31 9999 (unlimited)
    201104-           => Apr 1 2011 - Dec 31 9999 (unlimited)
    20110408-         => Apr 8 2011 - Dec 31 9999 (unlimited)
    -2011             Jan 1 0000 - Dez 31 2011
    -201104           Jan 1 0000 - Apr 30, 2011
    -20110408         Jan 1 0000 - Apr 8, 2011
    """
    pos = param.find('-')
    lower, upper = (None, None)
    if pos == -1:
        # no seperator given
        lower, upper = (param, param)
    else:
        lower, upper = param.split('-')
    ret = (expand_date_param(lower, 'lower'), expand_date_param(upper, 'upper'))
    return ret

def
to_dates
(
param
)
:
pos
=
param
.
find
(
'-'
)
lower
,
upper
=
(
,
)
if
pos
==
1
:
# no seperator given
lower
,
upper
=
(
param
,
param
)
else
:
lower
,
upper
=
param
.
split
(
'-'
)
ret
=
(
expand_date_param
(
lower
,
'lower'
)
,
expand_date_param
(
upper
,
'upper'
)
)
return
ret

This function takes a date string in various formats and converts it to a normalized and validated date range . A list with two elements is returned lower and upper date boundary .


def select_fields(doc, field_list):
        '''
        Take 'doc' and create a new doc using only keys from the 'fields' list.
        Supports referencing fields using dotted notation "a.b.c" so we can parse
        nested fields the way MongoDB does. The nested field class is a hack. It should
        be a sub-class of dict.
        '''

        if field_list is None or len(field_list) == 0:
            return doc

        newDoc = Nested_Dict({})
        oldDoc = Nested_Dict(doc)

        for i in field_list:
            if oldDoc.has_key(i):
                # print( "doc: %s" % doc )
                # print( "i: %s" %i )
                newDoc.set_value(i, oldDoc.get_value(i))
        return newDoc.dict_value()

def
select_fields
(
doc
,
field_list
)
:
if
field_list
is
or
len
(
field_list
)
==
0
:
return
doc
newDoc
=
Nested_Dict
(
{
}
)
oldDoc
=
Nested_Dict
(
doc
)
for
i
in
field_list
:
if
oldDoc
.
has_key
(
i
)
:
# print( "doc: %s" % doc )
# print( "i: %s" %i )
newDoc
.
set_value
(
i
,
oldDoc
.
get_value
(
i
)
)
return
newDoc
.
dict_value
(
)

Take doc and create a new doc using only keys from the fields list . Supports referencing fields using dotted notation a . b . c so we can parse nested fields the way MongoDB does . The nested field class is a hack . It should be a sub - class of dict .


def date_map(doc, datemap_list, time_format=None):
        '''
        For all the datetime fields in "datemap" find that key in doc and map the datetime object to
        a strftime string. This pprint and others will print out readable datetimes.
        '''
        if datemap_list:
            for i in datemap_list:
                if isinstance(i, datetime):
                    doc=CursorFormatter.date_map_field(doc, i, time_format=time_format)
        return doc

def date_map ( doc , datemap_list , time_format = None ) : if datemap_list : for i in datemap_list : if isinstance ( i , datetime ) : doc = CursorFormatter . date_map_field ( doc , i , time_format = time_format ) return doc

For all the datetime fields in datemap find that key in doc and map the datetime object to a strftime string . This pprint and others will print out readable datetimes .


def printCursor(self, fieldnames=None, datemap=None, time_format=None):
        '''
        Output a cursor to a filename or stdout if filename is "-".
        fmt defines whether we output CSV or JSON.
        '''

        if self._format == 'csv':
            count = self.printCSVCursor(fieldnames, datemap, time_format)
        else:
            count = self.printJSONCursor( fieldnames, datemap, time_format)

        return count

def printCursor ( self , fieldnames = None , datemap = None , time_format = None ) : if self . _format == 'csv' : count = self . printCSVCursor ( fieldnames , datemap , time_format ) else : count = self . printJSONCursor ( fieldnames , datemap , time_format ) return count

Output a cursor to a filename or stdout if filename is - . fmt defines whether we output CSV or JSON .


def output(self, fieldNames=None, datemap=None, time_format=None):
        '''
        Output all fields using the fieldNames list. for fields in the list datemap indicates the field must
        be date
        '''

        count = self.printCursor(self._cursor, fieldNames, datemap, time_format)

def output ( self , fieldNames = None , datemap = None , time_format = None ) : count = self . printCursor ( self . _cursor , fieldNames , datemap , time_format )

Output all fields using the fieldNames list . for fields in the list datemap indicates the field must be date


def get_tasks(do_tasks, dep_graph):
    """Given a list of tasks to perform and a dependency graph, return the tasks
    that must be performed, in the correct order"""

    #XXX: Is it important that if a task has "foo" before "bar" as a dep,
    #     that foo executes before bar? Why? ATM this may not happen.

    #Each task that the user has specified gets its own execution graph
    task_graphs = []

    for task in do_tasks:
        exgraph = DiGraph()
        exgraph.add_node(task)
        _get_deps(task, exgraph, dep_graph)

        task_graphs.append(exgraph)

    return flatten(reversed(topological_sort(g)) for g in task_graphs)

Given a list of tasks to perform and a dependency graph return the tasks that must be performed in the correct order


def add_default_deps(project):
    """Add or create the default departments for the given project

    :param project: the project that needs default departments
    :type project: :class:`muke.models.Project`
    :returns: None
    :rtype: None
    :raises: None
    """
    # create deps for project
    for name, short, order, af in DEFAULT_DEPARTMENTS:
        dep, created = Department.objects.get_or_create(name=name, short=short, ordervalue=order, assetflag=af)
        dep.projects.add(project)
        dep.full_clean()
        dep.save()

def
add_default_deps
(
project
)
:
# create deps for project
for
name
,
short
,
order
,
af
in
DEFAULT_DEPARTMENTS
:
dep
,
created
=
Department
.
objects
.
get_or_create
(
name
=
name
,
short
=
short
,
ordervalue
=
order
,
assetflag
=
af
)
dep
.
projects
.
add
(
project
)
dep
.
full_clean
(
)
dep
.
save
(
)


def add_default_atypes(project):
    """Add or create the default assettypes for the given project

    :param project: the project that needs default assettypes
    :type project: :class:`muke.models.Project`
    :returns: None
    :rtype: None
    :raises: None
    """
    # create assettypes for project
    for name, desc in DEFAULT_ASSETTYPES:
        at, created = Atype.objects.get_or_create(name=name, defaults={'description': desc})
        at.projects.add(project)
        at.full_clean()
        at.save()

def
add_default_atypes
(
project
)
:
# create assettypes for project
for
name
,
desc
in
DEFAULT_ASSETTYPES
:
at
,
created
=
Atype
.
objects
.
get_or_create
(
name
=
name
,
defaults
=
{
'description'
:
desc
}
)
at
.
projects
.
add
(
project
)
at
.
full_clean
(
)
at
.
save
(
)


def add_default_sequences(project):
    """Add or create the default sequences for the given project

    :param project: the project that needs default sequences
    :type project: :class:`muke.models.Project`
    :returns: None
    :rtype: None
    :raises: None
    """
    # create sequences for project
    seqs = [(GLOBAL_NAME, 'global sequence for project %s' % project.name),
            (RNDSEQ_NAME, 'research and development sequence for project %s' % project.name)]
    for name, desc in seqs:
        seq, created = Sequence.objects.get_or_create(name=name, project=project, defaults={'description': desc})


def add_userrnd_shot(project):
    """Add a rnd shot for every user in the project

    :param project: the project that needs its rnd shots updated
    :type project: :class:`muke.models.Project`
    :returns: None
    :rtype: None
    :raises: None
    """
    rndseq = project.sequence_set.get(name=RNDSEQ_NAME)
    users = [u for u in project.users.all()]
    for user in users:
        shot, created = Shot.objects.get_or_create(name=user.username,
                                                   project=project,
                                                   sequence=rndseq,
                                                   defaults={'description': 'rnd shot for user %s' % user.username})
        for t in shot.tasks.all():
            t.users.add(user)
            t.full_clean()
            t.save()

def
add_userrnd_shot
(
project
)
:
rndseq
=
project
.
sequence_set
.
get
(
name
=
RNDSEQ_NAME
)
users
=
[
u
for
u
in
project
.
users
.
all
(
)
]
for
user
in
users
:
shot
,
created
=
Shot
.
objects
.
get_or_create
(
name
=
user
.
username
,
project
=
project
,
sequence
=
rndseq
,
defaults
=
{
'description'
:
'rnd shot for user %s'
%
user
.
username
}
)
for
t
in
shot
.
tasks
.
all
(
)
:
t
.
users
.
add
(
user
)
t
.
full_clean
(
)
t
.
save
(
)


def prj_post_save_handler(sender, **kwargs):
    """ Post save receiver for when a Project is saved.

    Creates a rnd shot for every user.

    On creations does:

       1. create all default departments
       2. create all default assettypes
       3. create all default sequences

    :param sender: the project class
    :type sender: :class:`muke.models.Project`
    :returns:  None
    :raises: None

    """
    prj = kwargs['instance']
    if not kwargs['created']:
        add_userrnd_shot(prj)
        return

    add_default_deps(prj)
    add_default_atypes(prj)
    add_default_sequences(prj)

def prj_post_save_handler ( sender , * * kwargs ) : prj = kwargs [ 'instance' ] if not kwargs [ 'created' ] : add_userrnd_shot ( prj ) return add_default_deps ( prj ) add_default_atypes ( prj ) add_default_sequences ( prj )

Post save receiver for when a Project is saved .


def seq_post_save_handler(sender, **kwargs):
    """ Post save receiver for when a sequence is saved.

    creates a global shot.

    :param sender: the sequence class
    :type sender: :class:`muke.models.Sequence`
    :returns:  None
    :raises: None

    """
    if not kwargs['created']:
        return
    seq = kwargs['instance']
    if seq.name == RNDSEQ_NAME:
        return

    prj = seq.project
    name = GLOBAL_NAME
    desc = "Global shot for sequence %s" % seq.name
    Shot.objects.create(name=name, project=prj, sequence=seq, description=desc)

def
seq_post_save_handler
(
sender
,
*
*
kwargs
)
:
if
not
kwargs
[
'created'
]
:
return
seq
=
kwargs
[
'instance'
]
if
seq
.
name
==
RNDSEQ_NAME
:
return
prj
=
seq
.
project
name
=
GLOBAL_NAME
desc
=
"Global shot for sequence %s"
%
seq
.
name
Shot
.
objects
.
create
(
name
=
name
,
project
=
prj
,
sequence
=
seq
,
description
=
desc
)

Post save receiver for when a sequence is saved .


def create_all_tasks(element):
    """Create all tasks for the element

    :param element: The shot or asset that needs tasks
    :type element: :class:`muke.models.Shot` | :class:`muke.models.Asset`
    :returns: None
    :rtype: None
    :raises: None
    """
    prj = element.project
    if isinstance(element, Asset):
        flag=True
    else:
        flag=False
    deps = prj.department_set.filter(assetflag=flag)
    for d in deps:
        t = Task(project=prj, department=d, element=element)
        t.full_clean()
        t.save()

def create_all_tasks ( element ) : prj = element . project if isinstance ( element , Asset ) : flag = True else : flag = False deps = prj . department_set . filter ( assetflag = flag ) for d in deps : t = Task ( project = prj , department = d , element = element ) t . full_clean ( ) t . save ( )


def pre_connect(self, peer):
        """
        Ensures that we have an open connection to the given peer.

        Returns the peer id. This should be equal to the given one, but
        it might not if the given peer was, say, the IP and the peer
        actually identifies itself with a host name. The returned peer
        is the real one that should be used. This can be handy if we aren't
        100% sure of the peer's identity.
        """
        if peer in self._connections:
            return defer.succeed(peer)
        else:
            d = self._connect(peer, exact_peer=False)
            def connected(p):
                return p.peer
            d.addCallback(connected)
            return d

def pre_connect ( self , peer ) : if peer in self . _connections : return defer . succeed ( peer ) else : d = self . _connect ( peer , exact_peer = False ) def connected ( p ) : return p . peer d . addCallback ( connected ) return d

Ensures that we have an open connection to the given peer . Returns the peer id . This should be equal to the given one but it might not if the given peer was say the IP and the peer actually identifies itself with a host name . The returned peer is the real one that should be used . This can be handy if we aren t 100% sure of the peer s identity .


def send(self, peer, typename, data):
        """
        Sends a packet to a peer.
        """

        def attempt_to_send(_):
            if peer not in self._connections:
                d = self._connect(peer)
                d.addCallback(attempt_to_send)
                return d
            else:
                conn = self._connections[peer][0]
                conn.send_packet(typename, data)
                return defer.succeed(None)

        d = attempt_to_send(None)

        self._ongoing_sends.add(d)

        def send_completed(result):
            if d in self._ongoing_sends:
                self._ongoing_sends.remove(d)
            return result

        d.addBoth(send_completed)
        return d

def send ( self , peer , typename , data ) : def attempt_to_send ( _ ) : if peer not in self . _connections : d = self . _connect ( peer ) d . addCallback ( attempt_to_send ) return d else : conn = self . _connections [ peer ] [ 0 ] conn . send_packet ( typename , data ) return defer . succeed ( None ) d = attempt_to_send ( None ) self . _ongoing_sends . add ( d ) def send_completed ( result ) : if d in self . _ongoing_sends : self . _ongoing_sends . remove ( d ) return result d . addBoth ( send_completed ) return d


def get_config_value(self, section, key, return_type: type):
        """Read customer's config value by section and key.

        :param section: config file's section. i.e [default]
        :param key: config file's key under section. i.e packages_scan
        :param return_type: return value type, str | int | bool.
        """
        try:
            value = self.method_mapping[return_type](section, key)
        except NoSectionError as e:
            raise ConfigError(e.message)
        except NoOptionError as e:
            raise ConfigError(e.message)
        return value

def get_config_value ( self , section , key , return_type : type ) : try : value = self . method_mapping [ return_type ] ( section , key ) except NoSectionError as e : raise ConfigError ( e . message ) except NoOptionError as e : raise ConfigError ( e . message ) return value

Read customer s config value by section and key .


def nova(*arg):
    """
    Nova annotation for adding function to process nova notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Nova, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            nova_customer_process_wildcard[event_type_pattern] = func
        else:
            nova_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Nova annotation for adding function to process nova notification .


def cinder(*arg):
    """
    Cinder annotation for adding function to process cinder notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Cinder, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            cinder_customer_process_wildcard[event_type_pattern] = func
        else:
            cinder_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Cinder annotation for adding function to process cinder notification .


def neutron(*arg):
    """
    Neutron annotation for adding function to process neutron notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Neutron, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            neutron_customer_process_wildcard[event_type_pattern] = func
        else:
            neutron_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Neutron annotation for adding function to process neutron notification .


def glance(*arg):
    """
    Glance annotation for adding function to process glance notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Glance, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            glance_customer_process_wildcard[event_type_pattern] = func
        else:
            glance_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Glance annotation for adding function to process glance notification .


def swift(*arg):
    """
    Swift annotation for adding function to process swift notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Swift, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            swift_customer_process_wildcard[event_type_pattern] = func
        else:
            swift_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Swift annotation for adding function to process swift notification .


def keystone(*arg):
    """
    Swift annotation for adding function to process keystone notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Keystone, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            keystone_customer_process_wildcard[event_type_pattern] = func
        else:
            keystone_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Swift annotation for adding function to process keystone notification .


def heat(*arg):
    """
    Heat annotation for adding function to process heat notification.

    if event_type include wildcard, will put {pattern: function} into process_wildcard dict
    else will put {event_type: function} into process dict

    :param arg: event_type of notification
    """
    check_event_type(Openstack.Heat, *arg)
    event_type = arg[0]

    def decorator(func):
        if event_type.find("*") != -1:
            event_type_pattern = pre_compile(event_type)
            heat_customer_process_wildcard[event_type_pattern] = func
        else:
            heat_customer_process[event_type] = func
        log.info("add function {0} to process event_type:{1}".format(func.__name__, event_type))

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            func(*args, **kwargs)

        return wrapper

    return decorator

Heat annotation for adding function to process heat notification .


def addFactory(self, identifier, factory):
        """Adds a factory.

        After calling this method, remote clients will be able to
        connect to it.

        This will call ``factory.doStart``.

        """
        factory.doStart()
        self._factories[identifier] = factory

def addFactory ( self , identifier , factory ) : factory . doStart ( ) self . _factories [ identifier ] = factory


def removeFactory(self, identifier):
        """Removes a factory.

        After calling this method, remote clients will no longer be
        able to connect to it.

        This will call the factory's ``doStop`` method.

        """
        factory = self._factories.pop(identifier)
        factory.doStop()
        return factory

def removeFactory ( self , identifier ) : factory = self . _factories . pop ( identifier ) factory . doStop ( ) return factory


def connect(self, factory):
        """Attempts to connect using a given factory.

        This will find the requested factory and use it to build a
        protocol as if the AMP protocol's peer was making the
        connection. It will create a transport for the protocol and
        connect it immediately. It will then store the protocol under
        a unique identifier, and return that identifier.

        """
        try:
            factory = self._factories[factory]
        except KeyError:
            raise NoSuchFactory()

        remote = self.getProtocol()
        addr = remote.transport.getPeer()
        proto = factory.buildProtocol(addr)
        if proto is None:
            raise ConnectionRefused()

        identifier = uuid4().hex
        transport = MultiplexedTransport(identifier, remote)
        proto.makeConnection(transport)

        self._protocols[identifier] = proto
        return {"connection": identifier}

def connect ( self , factory ) : try : factory = self . _factories [ factory ] except KeyError : raise NoSuchFactory ( ) remote = self . getProtocol ( ) addr = remote . transport . getPeer ( ) proto = factory . buildProtocol ( addr ) if proto is None : raise ConnectionRefused ( ) identifier = uuid4 ( ) . hex transport = MultiplexedTransport ( identifier , remote ) proto . makeConnection ( transport ) self . _protocols [ identifier ] = proto return { "connection" : identifier }

Attempts to connect using a given factory .


def receiveData(self, connection, data):
        """
        Receives some data for the given protocol.
        """
        try:
            protocol = self._protocols[connection]
        except KeyError:
            raise NoSuchConnection()

        protocol.dataReceived(data)
        return {}

def receiveData ( self , connection , data ) : try : protocol = self . _protocols [ connection ] except KeyError : raise NoSuchConnection ( ) protocol . dataReceived ( data ) return { }

Receives some data for the given protocol .


def disconnect(self, connection):
        """
        Disconnects the given protocol.
        """
        proto = self._protocols.pop(connection)
        proto.transport = None
        return {}

def disconnect ( self , connection ) : proto = self . _protocols . pop ( connection ) proto . transport = None return { }


def _callRemote(self, command, **kwargs):
        """Shorthand for ``callRemote``.

        This uses the factory's connection to the AMP peer.

        """
        return self.factory.remote.callRemote(command, **kwargs)

def _callRemote ( self , command , * * kwargs ) : return self . factory . remote . callRemote ( command , * * kwargs )


def connectionMade(self):
        """Create a multiplexed stream connection.

        Connect to the AMP server's multiplexed factory using the
        identifier (defined by this class' factory). When done, stores
        the connection reference and causes buffered data to be sent.

        """
        log.msg("Creating multiplexed AMP connection...")
        remoteFactoryIdentifier = self.factory.remoteFactoryIdentifier
        d = self._callRemote(Connect, factory=remoteFactoryIdentifier)
        d.addCallback(self._multiplexedConnectionMade)

Create a multiplexed stream connection .


def _multiplexedConnectionMade(self, response):
        """Stores a reference to the connection, registers this protocol on
        the factory as one related to a multiplexed AMP connection,
        and sends currently buffered data. Gets rid of the buffer
        afterwards.

        """
        self.connection = conn = response["connection"]
        self.factory.protocols[conn] = self

        log.msg("Multiplexed AMP connection ({!r}) made!".format(conn))

        data, self._buffer = self._buffer.getvalue(), None
        if data:
            log.msg("Sending {} bytes of buffered data...".format(len(data)))
            self._sendData(data)
        else:
            log.msg("No buffered data to send!")

Stores a reference to the connection registers this protocol on the factory as one related to a multiplexed AMP connection and sends currently buffered data . Gets rid of the buffer afterwards .


def dataReceived(self, data):
        """Received some data from the local side.

        If we have set up the multiplexed connection, sends the data
        over the multiplexed connection. Otherwise, buffers.

        """
        log.msg("{} bytes of data received locally".format(len(data)))
        if self.connection is None:
            # we haven't finished connecting yet
            log.msg("Connection not made yet, buffering...")
            self._buffer.write(data)
        else:
            log.msg("Sending data...")
            self._sendData(data)

def
dataReceived
(
self
,
data
)
:
log
.
msg
(
"{} bytes of data received locally"
.
format
(
len
(
data
)
)
)
if
self
.
connection
is
:
# we haven't finished connecting yet
log
.
msg
(
"Connection not made yet, buffering..."
)
self
.
_buffer
.
write
(
data
)
else
:
log
.
msg
(
"Sending data..."
)
self
.
_sendData
(
data
)

Received some data from the local side .