def utilisation(self):
        """Getter for various Utilisation variables"""
        if self._utilisation is None:
            api = "SYNO.Core.System.Utilization"
            url = "%s/entry.cgi?api=%s&version=1&method=get" % (
                self.base_url,
                api)
            self._utilisation = SynoUtilization(self._get_url(url))
        return self._utilisation


def storage(self):
        """Getter for various Storage variables"""
        if self._storage is None:
            api = "SYNO.Storage.CGI.Storage"
            url = "%s/entry.cgi?api=%s&version=1&method=load_info" % (
                self.base_url,
                api)
            self._storage = SynoStorage(self._get_url(url))
        return self._storage


def for_request(request, body=None):
        """Creates the context for a specific request."""
        tenant, jwt_data = Tenant.objects.for_request(request, body)
        webhook_sender_id = jwt_data.get('sub')
        sender_data = None

        if body and 'item' in body:
            if 'sender' in body['item']:
                sender_data = body['item']['sender']
            elif 'message' in body['item'] and 'from' in body['item']['message']:
                sender_data = body['item']['message']['from']

        if sender_data is None:
            if webhook_sender_id is None:
                raise BadTenantError('Cannot identify sender in tenant')
            sender_data = {'id': webhook_sender_id}

        return Context(
            tenant=tenant,
            sender=HipchatUser(
                id=sender_data.get('id'),
                name=sender_data.get('name'),
                mention_name=sender_data.get('mention_name'),
            ),
            signed_request=request.GET.get('signed_request'),
            context=jwt_data.get('context') or {},
        )

def
for_request
(
request
,
body
=
)
:
tenant
,
jwt_data
=
Tenant
.
objects
.
for_request
(
request
,
body
)
webhook_sender_id
=
jwt_data
.
get
(
'sub'
)
sender_data
=
if
body
and
'item'
in
body
:
if
'sender'
in
body
[
'item'
]
:
sender_data
=
body
[
'item'
]
[
'sender'
]
elif
'message'
in
body
[
'item'
]
and
'from'
in
body
[
'item'
]
[
'message'
]
:
sender_data
=
body
[
'item'
]
[
'message'
]
[
'from'
]
if
sender_data
is
:
if
webhook_sender_id
is
:
raise
BadTenantError
(
'Cannot identify sender in tenant'
)
sender_data
=
{
'id'
:
webhook_sender_id
}
return
Context
(
tenant
=
tenant
,
sender
=
HipchatUser
(
id
=
sender_data
.
get
(
'id'
)
,
name
=
sender_data
.
get
(
'name'
)
,
mention_name
=
sender_data
.
get
(
'mention_name'
)
,
)
,
signed_request
=
request
.
GET
.
get
(
'signed_request'
)
,
context
=
jwt_data
.
get
(
'context'
)
or
{
}
,
)

Creates the context for a specific request .


def tenant_token(self):
        """The cached token of the current tenant."""
        rv = getattr(self, '_tenant_token', None)
        if rv is None:
            rv = self._tenant_token = self.tenant.get_token()
        return rv

def tenant_token ( self ) : rv = getattr ( self , '_tenant_token' , None ) if rv is None : rv = self . _tenant_token = self . tenant . get_token ( ) return rv

The cached token of the current tenant .


def build_attrs(self, extra_attrs=None, **kwargs):
        "Helper function for building an attribute dictionary."
        self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs)
        return self.attrs

Helper function for building an attribute dictionary .


def with_apps(*apps):
    """
    Class decorator that makes sure the passed apps are present in
    INSTALLED_APPS.
    """
    apps_set = set(settings.INSTALLED_APPS)
    apps_set.update(apps)
    return override_settings(INSTALLED_APPS=list(apps_set))

def with_apps ( * apps ) : apps_set = set ( settings . INSTALLED_APPS ) apps_set . update ( apps ) return override_settings ( INSTALLED_APPS = list ( apps_set ) )

Class decorator that makes sure the passed apps are present in INSTALLED_APPS .


def without_apps(*apps):
    """
    Class decorator that makes sure the passed apps are not present in
    INSTALLED_APPS.
    """
    apps_list = [a for a in settings.INSTALLED_APPS if a not in apps]
    return override_settings(INSTALLED_APPS=apps_list)

def without_apps ( * apps ) : apps_list = [ a for a in settings . INSTALLED_APPS if a not in apps ] return override_settings ( INSTALLED_APPS = apps_list )

Class decorator that makes sure the passed apps are not present in INSTALLED_APPS .


def get_global_settings(self):
        """
        Return a dictionary of all global_settings values.
        """
        return dict((key, getattr(global_settings, key)) for key in dir(global_settings)
                    if key.isupper())

def get_global_settings ( self ) : return dict ( ( key , getattr ( global_settings , key ) ) for key in dir ( global_settings ) if key . isupper ( ) )

Return a dictionary of all global_settings values .


def do_GET(self):
		"""
		Handle the retrieval of the code
		"""
		parsed_url = urlparse(self.path)

		if parsed_url[2] == "/" + SERVER_REDIRECT_PATH:  # 2 = Path
			parsed_query = parse_qs(parsed_url[4])  # 4 = Query

			if "code" not in parsed_query:
				self.send_response(200)
				self.send_header("Content-Type", "text/plain")
				self.end_headers()

				self.wfile.write("No code found, try again!".encode("utf-8"))
				return

			self.server.response_code = parsed_query["code"][0]

			self.send_response(200)
			self.send_header("Content-Type", "text/plain")
			self.end_headers()

			self.wfile.write(
				"Thank you for using OAuth2Util. The authorization was successful, "
				"you can now close this window.".encode("utf-8"))
		elif parsed_url[2] == "/" + SERVER_LINK_PATH: # 2 = Path
			self.send_response(200)
			self.send_header("Content-Type", "text/html")
			self.end_headers()

			self.wfile.write("Hey there!
Click here to claim your prize."
				.format(self.server.authorize_url).encode("utf-8"))
		else:
			self.send_response(404)
			self.send_header("Content-Type", "text/plain")
			self.end_headers()
			self.wfile.write("404 not found".encode("utf-8"))


def _get_value(self, key, func=None, split_val=None, as_boolean=False,
		exception_default=None):
		"""
		Helper method to get a value from the config
		"""
		try:
			if as_boolean:
				return self.config.getboolean(key[0], key[1])
			value = self.config.get(key[0], key[1])
			if split_val is not None:
				value = value.split(split_val)
			if func is not None:
				return func(value)
			return value
		except (KeyError, configparser.NoSectionError, configparser.NoOptionError) as e:
			if exception_default is not None:
				return exception_default
			raise KeyError(e)

def _get_value ( self , key , func = None , split_val = None , as_boolean = False , exception_default = None ) : try : if as_boolean : return self . config . getboolean ( key [ 0 ] , key [ 1 ] ) value = self . config . get ( key [ 0 ] , key [ 1 ] ) if split_val is not None : value = value . split ( split_val ) if func is not None : return func ( value ) return value except ( KeyError , configparser . NoSectionError , configparser . NoOptionError ) as e : if exception_default is not None : return exception_default raise KeyError ( e )


def _change_value(self, key, value):
		"""
		Change the value of the given key in the given file to the given value
		"""
		if not self.config.has_section(key[0]):
			self.config.add_section(key[0])

		self.config.set(key[0], key[1], str(value))

		with open(self.configfile, "w") as f:
			self.config.write(f)

def _change_value ( self , key , value ) : if not self . config . has_section ( key [ 0 ] ) : self . config . add_section ( key [ 0 ] ) self . config . set ( key [ 0 ] , key [ 1 ] , str ( value ) ) with open ( self . configfile , "w" ) as f : self . config . write ( f )


def _migrate_config(self, oldname=DEFAULT_CONFIG, newname=DEFAULT_CONFIG):
		"""
		Migrates the old config file format to the new one
		"""
		self._log("Your OAuth2Util config file is in an old format and needs "
				"to be changed. I tried as best as I could to migrate it.", logging.WARNING)

		with open(oldname, "r") as old:
			with open(newname, "w") as new:
				new.write("[app]\n")
				new.write(old.read())


def _start_webserver(self, authorize_url=None):
		"""
		Start the webserver that will receive the code
		"""
		server_address = (SERVER_URL, SERVER_PORT)
		self.server = HTTPServer(server_address, OAuth2UtilRequestHandler)
		self.server.response_code = None
		self.server.authorize_url = authorize_url
		t = Thread(target=self.server.serve_forever)
		t.daemon = True
		t.start()

def _start_webserver ( self , authorize_url = None ) : server_address = ( SERVER_URL , SERVER_PORT ) self . server = HTTPServer ( server_address , OAuth2UtilRequestHandler ) self . server . response_code = None self . server . authorize_url = authorize_url t = Thread ( target = self . server . serve_forever ) t . daemon = True t . start ( )


def _wait_for_response(self):
		"""
		Wait until the user accepted or rejected the request
		"""
		while not self.server.response_code:
			time.sleep(2)
		time.sleep(5)
		self.server.shutdown()

def _wait_for_response ( self ) : while not self . server . response_code : time . sleep ( 2 ) time . sleep ( 5 ) self . server . shutdown ( )


def _get_new_access_information(self):
		"""
		Request new access information from reddit using the built in webserver
		"""
		if not self.r.has_oauth_app_info:
			self._log('Cannot obtain authorize url from PRAW. Please check your configuration.', logging.ERROR)
			raise AttributeError('Reddit Session invalid, please check your designated config file.')
		url = self.r.get_authorize_url('UsingOAuth2Util',
						self._get_value(CONFIGKEY_SCOPE, set, split_val=','),
						self._get_value(CONFIGKEY_REFRESHABLE, as_boolean=True))

		self._start_webserver(url)
		if not self._get_value(CONFIGKEY_SERVER_MODE, as_boolean=True):
			webbrowser.open(url)
		else:
			print("Webserver is waiting for you :D. Please open {0}:{1}/{2} "
					"in your browser"
				.format(SERVER_URL, SERVER_PORT, SERVER_LINK_PATH))
		self._wait_for_response()

		try:
			access_information = self.r.get_access_information(
				self.server.response_code)
		except praw.errors.OAuthException:
			self._log("Can not authenticate, maybe the app infos (e.g. secret) are wrong.", logging.ERROR)
			raise

		self._change_value(CONFIGKEY_TOKEN, access_information["access_token"])
		self._change_value(CONFIGKEY_REFRESH_TOKEN, access_information["refresh_token"])
		self._change_value(CONFIGKEY_VALID_UNTIL, time.time() + TOKEN_VALID_DURATION)


def _check_token_present(self):
		"""
		Check whether the tokens are set and request new ones if not
		"""
		try:
			self._get_value(CONFIGKEY_TOKEN)
			self._get_value(CONFIGKEY_REFRESH_TOKEN)
			self._get_value(CONFIGKEY_REFRESHABLE)
		except KeyError:
			self._log("Request new Token (CTP)")
			self._get_new_access_information()

def
_check_token_present
(
self
)
:
try
:
self
.
_get_value
(
CONFIGKEY_TOKEN
)
self
.
_get_value
(
CONFIGKEY_REFRESH_TOKEN
)
self
.
_get_value
(
CONFIGKEY_REFRESHABLE
)
except
KeyError
:
self
.
_log
(
"Request new Token (CTP)"
)
self
.
_get_new_access_information
(
)


def set_access_credentials(self, _retry=0):
		"""
		Set the token on the Reddit Object again
		"""
		if _retry >= 5:
			raise ConnectionAbortedError('Reddit is not accessible right now, cannot refresh OAuth2 tokens.')

		self._check_token_present()

		try:
			self.r.set_access_credentials(self._get_value(CONFIGKEY_SCOPE, set, split_val=","),
										  self._get_value(CONFIGKEY_TOKEN),
										  self._get_value(CONFIGKEY_REFRESH_TOKEN))
		except (praw.errors.OAuthInvalidToken, praw.errors.HTTPException) as e:
			# todo check e status code
			# self._log('Retrying in 5s.')
			# time.sleep(5)
			# self.set_access_credentials(_retry=_retry + 1)

			self._log("Request new Token (SAC)")
			self._get_new_access_information()


def refresh(self, force=False, _retry=0):
		"""
		Check if the token is still valid and requests a new if it is not
		valid anymore

		Call this method before a call to praw
		if there might have passed more than one hour

		force: if true, a new token will be retrieved no matter what
		"""
		if _retry >= 5:
			raise ConnectionAbortedError('Reddit is not accessible right now, cannot refresh OAuth2 tokens.')
		self._check_token_present()

		# We check whether another instance already refreshed the token
		if time.time() > self._get_value(CONFIGKEY_VALID_UNTIL, float, exception_default=0) - REFRESH_MARGIN:
			self.config.read(self.configfile)

			if time.time() < self._get_value(CONFIGKEY_VALID_UNTIL, float, exception_default=0) - REFRESH_MARGIN:
				self._log("Found new token")
				self.set_access_credentials()

		if force or time.time() > self._get_value(CONFIGKEY_VALID_UNTIL, float, exception_default=0) - REFRESH_MARGIN:
			self._log("Refresh Token")
			try:
				new_token = self.r.refresh_access_information(self._get_value(CONFIGKEY_REFRESH_TOKEN))
				self._change_value(CONFIGKEY_TOKEN, new_token["access_token"])
				self._change_value(CONFIGKEY_VALID_UNTIL, time.time() + TOKEN_VALID_DURATION)
				self.set_access_credentials()
			except (praw.errors.OAuthInvalidToken, praw.errors.HTTPException) as e:
				# todo check e status code
				# self._log('Retrying in 5s.')
				# time.sleep(5)
				# self.refresh(_retry=_retry + 1)

				self._log("Request new Token (REF)")
				self._get_new_access_information()


def create_manifest_table(dynamodb_client, table_name):
    """Create DynamoDB table for run manifests

    Arguments:
    dynamodb_client - boto3 DynamoDB client (not service)
    table_name - string representing existing table name
    """
    try:
        dynamodb_client.create_table(
            AttributeDefinitions=[
                {
                    'AttributeName': DYNAMODB_RUNID_ATTRIBUTE,
                    'AttributeType': 'S'
                },
            ],
            TableName=table_name,
            KeySchema=[
                {
                    'AttributeName': DYNAMODB_RUNID_ATTRIBUTE,
                    'KeyType': 'HASH'
                },
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 5,
                'WriteCapacityUnits': 5
            }
        )
        dynamodb_client.get_waiter('table_exists').wait(TableName=table_name)
    except ClientError as e:
        # Table already exists
        if e.response['Error']['Code'] == 'ResourceInUseException':
            pass
        else:
            raise e

def create_manifest_table ( dynamodb_client , table_name ) : try : dynamodb_client . create_table ( AttributeDefinitions = [ { 'AttributeName' : DYNAMODB_RUNID_ATTRIBUTE , 'AttributeType' : 'S' } , ] , TableName = table_name , KeySchema = [ { 'AttributeName' : DYNAMODB_RUNID_ATTRIBUTE , 'KeyType' : 'HASH' } , ] , ProvisionedThroughput = { 'ReadCapacityUnits' : 5 , 'WriteCapacityUnits' : 5 } ) dynamodb_client . get_waiter ( 'table_exists' ) . wait ( TableName = table_name ) except ClientError as e : if e . response [ 'Error' ] [ 'Code' ] == 'ResourceInUseException' : pass else : raise e


def split_full_path(path):
    """Return pair of bucket without protocol and path

    Arguments:
    path - valid S3 path, such as s3://somebucket/events

    >>> split_full_path('s3://mybucket/path-to-events')
    ('mybucket', 'path-to-events/')
    >>> split_full_path('s3://mybucket')
    ('mybucket', None)
    >>> split_full_path('s3n://snowplow-bucket/some/prefix/')
    ('snowplow-bucket', 'some/prefix/')
    """
    if path.startswith('s3://'):
        path = path[5:]
    elif path.startswith('s3n://'):
        path = path[6:]
    elif path.startswith('s3a://'):
        path = path[6:]
    else:
        raise ValueError("S3 path should start with s3://, s3n:// or "
                         "s3a:// prefix")
    parts = path.split('/')
    bucket = parts[0]
    path = '/'.join(parts[1:])
    return bucket, normalize_prefix(path)


def is_glacier(s3_client, bucket, prefix):
    """Check if prefix is archived in Glacier, by checking storage class of
    first object inside that prefix

    Arguments:
    s3_client - boto3 S3 client (not service)
    bucket - valid extracted bucket (without protocol and prefix)
             example: sowplow-events-data
    prefix - valid S3 prefix (usually, run_id)
             example: snowplow-archive/enriched/archive/
    """
    response = s3_client.list_objects_v2(Bucket=bucket,
                                         Prefix=prefix,
                                         MaxKeys=3)  # 3 to not fetch _SUCCESS

    for key in response['Contents']:
        if key.get('StorageClass', 'STANDARD') == 'GLACIER':
            return True
    return False

def is_glacier ( s3_client , bucket , prefix ) : response = s3_client . list_objects_v2 ( Bucket = bucket , Prefix = prefix , MaxKeys = 3 ) for key in response [ 'Contents' ] : if key . get ( 'StorageClass' , 'STANDARD' ) == 'GLACIER' : return True return False

Check if prefix is archived in Glacier by checking storage class of first object inside that prefix


def extract_run_id(key):
    """Extract date part from run id

    Arguments:
    key - full key name, such as shredded-archive/run=2012-12-11-01-31-33/
          (trailing slash is required)

    >>> extract_run_id('shredded-archive/run=2012-12-11-01-11-33/')
    'shredded-archive/run=2012-12-11-01-11-33/'
    >>> extract_run_id('shredded-archive/run=2012-12-11-01-11-33')
    >>> extract_run_id('shredded-archive/run=2012-13-11-01-11-33/')
    """
    filename = key.split('/')[-2]  # -1 element is empty string
    run_id = filename.lstrip('run=')
    try:
        datetime.strptime(run_id, '%Y-%m-%d-%H-%M-%S')
        return key
    except ValueError:
        return None

def extract_run_id ( key ) : filename = key . split ( '/' ) [ - 2 ] run_id = filename . lstrip ( 'run=' ) try : datetime . strptime ( run_id , '%Y-%m-%d-%H-%M-%S' ) return key except ValueError : return None


def clean_dict(dict):
    """Remove all keys with Nones as values

    >>> clean_dict({'key': None})
    {}
    >>> clean_dict({'empty_s': ''})
    {'empty_s': ''}
    """
    if sys.version_info[0] < 3:
        return {k: v for k, v in dict.iteritems() if v is not None}
    else:
        return {k: v for k, v in dict.items() if v is not None}

def clean_dict ( dict ) : if sys . version_info [ 0 ] < 3 : return { k : v for k , v in dict . iteritems ( ) if v is not None } else : return { k : v for k , v in dict . items ( ) if v is not None }


def add_to_manifest(dynamodb_client, table_name, run_id):
    """Add run_id into DynamoDB manifest table

    Arguments:
    dynamodb_client - boto3 DynamoDB client (not service)
    table_name - string representing existing table name
    run_id - string representing run_id to store
    """
    dynamodb_client.put_item(
        TableName=table_name,
        Item={
            DYNAMODB_RUNID_ATTRIBUTE: {
                'S': run_id
            }
        }
    )

def add_to_manifest ( dynamodb_client , table_name , run_id ) : dynamodb_client . put_item ( TableName = table_name , Item = { DYNAMODB_RUNID_ATTRIBUTE : { 'S' : run_id } } )


def is_in_manifest(dynamodb_client, table_name, run_id):
    """Check if run_id is stored in DynamoDB table.
    Return True if run_id is stored or False otherwise.

    Arguments:
    dynamodb_client - boto3 DynamoDB client (not service)
    table_name - string representing existing table name
    run_id - string representing run_id to store
    """
    response = dynamodb_client.get_item(
        TableName=table_name,
        Key={
            DYNAMODB_RUNID_ATTRIBUTE: {
                'S': run_id
            }
        }
    )
    return response.get('Item') is not None

def is_in_manifest ( dynamodb_client , table_name , run_id ) : response = dynamodb_client . get_item ( TableName = table_name , Key = { DYNAMODB_RUNID_ATTRIBUTE : { 'S' : run_id } } ) return response . get ( 'Item' ) is not None

Check if run_id is stored in DynamoDB table . Return True if run_id is stored or False otherwise .


def extract_schema(uri):
    """
    Extracts Schema information from Iglu URI

    >>> extract_schema("iglu:com.acme-corporation_underscore/event_name-dash/jsonschema/1-10-1")['vendor']
    'com.acme-corporation_underscore'
    """
    match = re.match(SCHEMA_URI_REGEX, uri)
    if match:
        return {
            'vendor': match.group(1),
            'name': match.group(2),
            'format': match.group(3),
            'version': match.group(4)

        }
    else:
        raise SnowplowEventTransformationException([
            "Schema {} does not conform to regular expression {}".format(uri, SCHEMA_URI)
        ])


def fix_schema(prefix, schema):
    """
    Create an Elasticsearch field name from a schema string
    """
    schema_dict = extract_schema(schema)
    snake_case_organization = schema_dict['vendor'].replace('.', '_').lower()
    snake_case_name = re.sub('([^A-Z_])([A-Z])', '\g<1>_\g<2>', schema_dict['name']).lower()
    model = schema_dict['version'].split('-')[0]
    return "{}_{}_{}_{}".format(prefix, snake_case_organization, snake_case_name, model)

def fix_schema ( prefix , schema ) : schema_dict = extract_schema ( schema ) snake_case_organization = schema_dict [ 'vendor' ] . replace ( '.' , '_' ) . lower ( ) snake_case_name = re . sub ( '([^A-Z_])([A-Z])' , '\g<1>_\g<2>' , schema_dict [ 'name' ] ) . lower ( ) model = schema_dict [ 'version' ] . split ( '-' ) [ 0 ] return "{}_{}_{}_{}" . format ( prefix , snake_case_organization , snake_case_name , model )


def parse_contexts(contexts):
    """
    Convert a contexts JSON to an Elasticsearch-compatible list of key-value pairs
    For example, the JSON

    {
      "data": [
        {
          "data": {
            "unique": true
          },
          "schema": "iglu:com.acme/unduplicated/jsonschema/1-0-0"
        },
        {
          "data": {
            "value": 1
          },
          "schema": "iglu:com.acme/duplicated/jsonschema/1-0-0"
        },
        {
          "data": {
            "value": 2
          },
          "schema": "iglu:com.acme/duplicated/jsonschema/1-0-0"
        }
      ],
      "schema": "iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0"
    }

    would become

    [
      ("context_com_acme_duplicated_1", [{"value": 1}, {"value": 2}]),
      ("context_com_acme_unduplicated_1", [{"unique": true}])
    ]
    """
    my_json = json.loads(contexts)
    data = my_json['data']
    distinct_contexts = {}
    for context in data:
        schema = fix_schema("contexts", context['schema'])
        inner_data = context['data']
        if schema not in distinct_contexts:
            distinct_contexts[schema] = [inner_data]
        else:
            distinct_contexts[schema].append(inner_data)
    output = []
    for key in distinct_contexts:
        output.append((key, distinct_contexts[key]))
    return output

def parse_contexts ( contexts ) : my_json = json . loads ( contexts ) data = my_json [ 'data' ] distinct_contexts = { } for context in data : schema = fix_schema ( "contexts" , context [ 'schema' ] ) inner_data = context [ 'data' ] if schema not in distinct_contexts : distinct_contexts [ schema ] = [ inner_data ] else : distinct_contexts [ schema ] . append ( inner_data ) output = [ ] for key in distinct_contexts : output . append ( ( key , distinct_contexts [ key ] ) ) return output

Convert a contexts JSON to an Elasticsearch - compatible list of key - value pairs For example the JSON


def parse_unstruct(unstruct):
    """
    Convert an unstructured event JSON to a list containing one Elasticsearch-compatible key-value pair
    For example, the JSON

    {
      "data": {
        "data": {
          "key": "value"
        },
        "schema": "iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1"
      },
      "schema": "iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0"
    }

    would become

    [
      (
        "unstruct_com_snowplowanalytics_snowplow_link_click_1", {
          "key": "value"
        }
      )
    ]
    """
    my_json = json.loads(unstruct)
    data = my_json['data']
    schema = data['schema']
    if 'data' in data:
        inner_data = data['data']
    else:
        raise SnowplowEventTransformationException(["Could not extract inner data field from unstructured event"])
    fixed_schema = fix_schema("unstruct_event", schema)
    return [(fixed_schema, inner_data)]

Convert an unstructured event JSON to a list containing one Elasticsearch - compatible key - value pair For example the JSON


def transform(line, known_fields=ENRICHED_EVENT_FIELD_TYPES, add_geolocation_data=True):
    """
    Convert a Snowplow enriched event TSV into a JSON
    """
    return jsonify_good_event(line.split('\t'), known_fields, add_geolocation_data)

def transform ( line , known_fields = ENRICHED_EVENT_FIELD_TYPES , add_geolocation_data = True ) : return jsonify_good_event ( line . split ( '\t' ) , known_fields , add_geolocation_data )


def jsonify_good_event(event, known_fields=ENRICHED_EVENT_FIELD_TYPES, add_geolocation_data=True):
    """
    Convert a Snowplow enriched event in the form of an array of fields into a JSON
    """
    if len(event) != len(known_fields):
        raise SnowplowEventTransformationException(
            ["Expected {} fields, received {} fields.".format(len(known_fields), len(event))]
        )
    else:
        output = {}
        errors = []
        if add_geolocation_data and event[LATITUDE_INDEX] != '' and event[LONGITUDE_INDEX] != '':
            output['geo_location'] = event[LATITUDE_INDEX] + ',' + event[LONGITUDE_INDEX]
        for i in range(len(event)):
            key = known_fields[i][0]
            if event[i] != '':
                try:
                    kvpairs = known_fields[i][1](key, event[i])
                    for kvpair in kvpairs:
                        output[kvpair[0]] = kvpair[1]
                except SnowplowEventTransformationException as sete:
                    errors += sete.error_messages
                except Exception as e:
                    errors += ["Unexpected exception parsing field with key {} and value {}: {}".format(
                        known_fields[i][0],
                        event[i],
                        repr(e)
                    )]
        if errors:
            raise SnowplowEventTransformationException(errors)
        else:
            return output


def get_used_template(response):
    """
    Get the template used in a TemplateResponse.
    This returns a tuple of "active choice, all choices"
    """
    if not hasattr(response, 'template_name'):
        return None, None

    template = response.template_name
    if template is None:
        return None, None

    if isinstance(template, (list, tuple)):
        # See which template name was really used.
        if len(template) == 1:
            return template[0], None
        else:
            used_name = _get_used_template_name(template)
            return used_name, template
    elif isinstance(template, six.string_types):
        # Single string
        return template, None
    else:
        # Template object.
        filename = _get_template_filename(template)
        template_name = '<template object from {0}>'.format(filename) if filename else '<template object>'
        return template_name, None

def
get_used_template
(
response
)
:
if
not
hasattr
(
response
,
'template_name'
)
:
return
,
template
=
response
.
template_name
if
template
is
:
return
,
if
isinstance
(
template
,
(
list
,
tuple
)
)
:
if
len
(
template
)
==
1
:
return
template
[
0
]
,
else
:
used_name
=
_get_used_template_name
(
template
)
return
used_name
,
template
elif
isinstance
(
template
,
six
.
string_types
)
:
return
template
,
else
:
filename
=
_get_template_filename
(
template
)
template_name
=
'<template object from {0}>'
.
format
(
filename
)
if
filename
else
'<template object>'
return
template_name
,

Get the template used in a TemplateResponse . This returns a tuple of active choice all choices


def print_context(self, context):
        """
        Print the entire template context
        """
        text = [CONTEXT_TITLE]
        for i, context_scope in enumerate(context):
            dump1 = linebreaksbr(pformat_django_context_html(context_scope))
            dump2 = pformat_dict_summary_html(context_scope)

            # Collapse long objects by default (e.g. request, LANGUAGES and sql_queries)
            if len(context_scope) <= 3 and dump1.count('<br />') > 20:
                (dump1, dump2) = (dump2, dump1)

            text.append(CONTEXT_BLOCK.format(
                style=PRE_STYLE,
                num=i,
                dump1=dump1,
                dump2=dump2
            ))
        return u''.join(text)

def
print_context
(
self
,
context
)
:
text
=
[
CONTEXT_TITLE
]
for
i
,
context_scope
in
enumerate
(
context
)
:
dump1
=
linebreaksbr
(
pformat_django_context_html
(
context_scope
)
)
dump2
=
pformat_dict_summary_html
(
context_scope
)
if
len
(
context_scope
)
<=
3
and
dump1
.
count
(
'<br />'
)
>
20
:
(
dump1
,
dump2
)
=
(
dump2
,
dump1
)
text
.
append
(
CONTEXT_BLOCK
.
format
(
style
=
PRE_STYLE
,
num
=
i
,
dump1
=
dump1
,
dump2
=
dump2
)
)
return
u''
.
join
(
text
)


def print_variables(self, context):
        """
        Print a set of variables
        """
        text = []
        for name, expr in self.variables:
            # Some extended resolving, to handle unknown variables
            data = ''
            try:
                if isinstance(expr.var, Variable):
                    data = expr.var.resolve(context)
                else:
                    data = expr.resolve(context)  # could return TEMPLATE_STRING_IF_INVALID
            except VariableDoesNotExist as e:
                # Failed to resolve, display exception inline
                keys = []
                for scope in context:
                    keys += scope.keys()
                keys = sorted(set(keys))  # Remove duplicates, e.g. csrf_token
                return ERROR_TYPE_BLOCK.format(style=PRE_ALERT_STYLE, error=escape(u"Variable '{0}' not found!  Available context variables are:\n\n{1}".format(expr, u', '.join(keys))))
            else:
                # Regular format
                textdata = linebreaksbr(pformat_django_context_html(data))

            # At top level, prefix class name if it's a longer result
            if isinstance(data, SHORT_NAME_TYPES):
                text.append(BASIC_TYPE_BLOCK.format(style=PRE_STYLE, name=name, value=textdata))
            else:
                text.append(OBJECT_TYPE_BLOCK.format(style=PRE_STYLE, name=name, type=data.__class__.__name__, value=textdata))
        return u''.join(text)


def pformat_sql_html(sql):
    """
    Highlight common SQL words in a string.
    """
    sql = escape(sql)
    sql = RE_SQL_NL.sub(u'
\n\\1', sql)
    sql = RE_SQL.sub(u'\\1', sql)
    return sql

def pformat_sql_html ( sql ) : sql = escape ( sql ) sql = RE_SQL_NL . sub ( u'
\n\\1' , sql ) sql = RE_SQL . sub ( u'\\1' , sql ) return sql

Highlight common SQL words in a string .


def pformat_django_context_html(object):
    """
    Dump a variable to a HTML string with sensible output for template context fields.
    It filters out all fields which are not usable in a template context.
    """
    if isinstance(object, QuerySet):
        text = ''
        lineno = 0
        for item in object.all()[:21]:
            lineno += 1
            if lineno >= 21:
                text += u'   (remaining items truncated...)'
                break
            text += u'   {0}\n'.format(escape(repr(item)))
        return text
    elif isinstance(object, Manager):
        return mark_safe(u'    (use <kbd>.all</kbd> to read it)')
    elif isinstance(object, six.string_types):
        return escape(repr(object))
    elif isinstance(object, Promise):
        # lazy() object
        return escape(_format_lazy(object))
    elif isinstance(object, dict):
        # This can also be a ContextDict
        return _format_dict(object)
    elif isinstance(object, list):
        return _format_list(object)
    elif hasattr(object, '__dict__'):
        return _format_object(object)
    else:
        # Use regular pprint as fallback.
        text = DebugPrettyPrinter(width=200).pformat(object)
        return _style_text(text)

def
pformat_django_context_html
(
object
)
:
if
isinstance
(
object
,
QuerySet
)
:
text
=
''
lineno
=
0
for
item
in
object
.
all
(
)
[
:
21
]
:
lineno
+=
1
if
lineno
>=
21
:
text
+=
u'   (remaining items truncated...)'
break
text
+=
u'   {0}\n'
.
format
(
escape
(
repr
(
item
)
)
)
return
text
elif
isinstance
(
object
,
Manager
)
:
return
mark_safe
(
u'    (use <kbd>.all</kbd> to read it)'
)
elif
isinstance
(
object
,
six
.
string_types
)
:
return
escape
(
repr
(
object
)
)
elif
isinstance
(
object
,
Promise
)
:
return
escape
(
_format_lazy
(
object
)
)
elif
isinstance
(
object
,
dict
)
:
return
_format_dict
(
object
)
elif
isinstance
(
object
,
list
)
:
return
_format_list
(
object
)
elif
hasattr
(
object
,
'__dict__'
)
:
return
_format_object
(
object
)
else
:
text
=
DebugPrettyPrinter
(
width
=
200
)
.
pformat
(
object
)
return
_style_text
(
text
)

Dump a variable to a HTML string with sensible output for template context fields . It filters out all fields which are not usable in a template context .


def pformat_dict_summary_html(dict):
    """
    Briefly print the dictionary keys.
    """
    if not dict:
        return '   {}'

    html = []
    for key, value in sorted(six.iteritems(dict)):
        if not isinstance(value, DICT_EXPANDED_TYPES):
            value = '...'

        html.append(_format_dict_item(key, value))

    return mark_safe(u'<br/>'.join(html))

def
pformat_dict_summary_html
(
dict
)
:
if
not
dict
:
return
'   {}'
html
=
[
]
for
key
,
value
in
sorted
(
six
.
iteritems
(
dict
)
)
:
if
not
isinstance
(
value
,
DICT_EXPANDED_TYPES
)
:
value
=
'...'
html
.
append
(
_format_dict_item
(
key
,
value
)
)
return
mark_safe
(
u'<br/>'
.
join
(
html
)
)


def _style_text(text):
    """
    Apply some HTML highlighting to the contents.
    This can't be done in the
    """
    # Escape text and apply some formatting.
    # To have really good highlighting, pprint would have to be re-implemented.
    text = escape(text)
    text = text.replace(' <iterator object>', " <<var>this object can be used in a 'for' loop</var>>")
    text = text.replace(' <dynamic item>', ' <<var>this object may have extra field names</var>>')
    text = text.replace(' <dynamic attribute>', ' <<var>this object may have extra field names</var>>')
    text = RE_PROXY.sub('\g<1><<var>proxy object</var>>', text)
    text = RE_FUNCTION.sub('\g<1><<var>object method</var>>', text)
    text = RE_GENERATOR.sub("\g<1><<var>generator, use 'for' to traverse it</var>>", text)
    text = RE_OBJECT_ADDRESS.sub('\g<1><<var>\g<2> object</var>>', text)
    text = RE_MANAGER.sub('\g<1><<var>manager, use .all to traverse it</var>>', text)
    text = RE_CLASS_REPR.sub('\g<1><<var>\g<2> class</var>>', text)

    # Since Django's WSGIRequest does a pprint like format for it's __repr__, make that styling consistent
    text = RE_REQUEST_FIELDNAME.sub('\g<1>:\n   \g<2>: ', text)
    text = RE_REQUEST_CLEANUP1.sub('\g<1>', text)
    text = RE_REQUEST_CLEANUP2.sub(')', text)

    return mark_safe(text)

" <small><<var>this object can be used in a 'for' loop</var>></small>"

' <small><<var>this object may have extra field names</var>></small>'

"\g<1><small><<var>generator, use 'for' to traverse it</var>></small>"

Apply some HTML highlighting to the contents . This can t be done in the


def format(self, object, context, maxlevels, level):
        """
        Format an item in the result.
        Could be a dictionary key, value, etc..
        """
        try:
            return PrettyPrinter.format(self, object, context, maxlevels, level)
        except HANDLED_EXCEPTIONS as e:
            return _format_exception(e), True, False

def format ( self , object , context , maxlevels , level ) : try : return PrettyPrinter . format ( self , object , context , maxlevels , level ) except HANDLED_EXCEPTIONS as e : return _format_exception ( e ) , True , False

Format an item in the result . Could be a dictionary key value etc ..


def _format(self, object, stream, indent, allowance, context, level):
        """
        Recursive part of the formatting
        """
        try:
            PrettyPrinter._format(self, object, stream, indent, allowance, context, level)
        except Exception as e:
            stream.write(_format_exception(e))

def _format ( self , object , stream , indent , allowance , context , level ) : try : PrettyPrinter . _format ( self , object , stream , indent , allowance , context , level ) except Exception as e : stream . write ( _format_exception ( e ) )


def get_token(s, pos, brackets_are_chars=True, environments=True, **parse_flags):
    """
    Parse the next token in the stream.

    Returns a `LatexToken`. Raises `LatexWalkerEndOfStream` if end of stream reached.

    .. deprecated:: 1.0
       Please use :py:meth:`LatexWalker.get_token()` instead.
    """
    return LatexWalker(s, **parse_flags).get_token(pos=pos,
                                                   brackets_are_chars=brackets_are_chars,
                                                   environments=environments)

def get_token ( s , pos , brackets_are_chars = True , environments = True , ** parse_flags ) : return LatexWalker ( s , ** parse_flags ) . get_token ( pos = pos , brackets_are_chars = brackets_are_chars , environments = environments )


def get_latex_nodes(s, pos=0, stop_upon_closing_brace=None, stop_upon_end_environment=None,
                    stop_upon_closing_mathmode=None, **parse_flags):
    """
    Parses latex content `s`.

    Returns a tuple `(nodelist, pos, len)` where nodelist is a list of `LatexNode` 's.

    If `stop_upon_closing_brace` is given, then `len` includes the closing brace, but the
    closing brace is not included in any of the nodes in the `nodelist`.

    .. deprecated:: 1.0
       Please use :py:meth:`LatexWalker.get_latex_nodes()` instead.
    """

    return LatexWalker(s, **parse_flags).get_latex_nodes(stop_upon_closing_brace=stop_upon_closing_brace,
                                                         stop_upon_end_environment=stop_upon_end_environment,
                                                         stop_upon_closing_mathmode=stop_upon_closing_mathmode)

def get_latex_nodes ( s , pos = 0 , stop_upon_closing_brace = None , stop_upon_end_environment = None , stop_upon_closing_mathmode = None , ** parse_flags ) : return LatexWalker ( s , ** parse_flags ) . get_latex_nodes ( stop_upon_closing_brace = stop_upon_closing_brace , stop_upon_end_environment = stop_upon_end_environment , stop_upon_closing_mathmode = stop_upon_closing_mathmode )


def latex2text(content, tolerant_parsing=False, keep_inline_math=False, keep_comments=False):
    """
    Extracts text from `content` meant for database indexing. `content` is
    some LaTeX code.

    .. deprecated:: 1.0
       Please use :py:class:`LatexNodes2Text` instead.
    """

    (nodelist, tpos, tlen) = latexwalker.get_latex_nodes(content, keep_inline_math=keep_inline_math,
                                                         tolerant_parsing=tolerant_parsing)

    return latexnodes2text(nodelist, keep_inline_math=keep_inline_math, keep_comments=keep_comments)

def latex2text ( content , tolerant_parsing = False , keep_inline_math = False , keep_comments = False ) : ( nodelist , tpos , tlen ) = latexwalker . get_latex_nodes ( content , keep_inline_math = keep_inline_math , tolerant_parsing = tolerant_parsing ) return latexnodes2text ( nodelist , keep_inline_math = keep_inline_math , keep_comments = keep_comments )

Extracts text from content meant for database indexing . content is some LaTeX code .


def set_tex_input_directory(self, tex_input_directory, latex_walker_init_args=None, strict_input=True):
        """
        Set where to look for input files when encountering the ``\\input`` or
        ``\\include`` macro.

        Alternatively, you may also override :py:meth:`read_input_file()` to
        implement a custom file lookup mechanism.

        The argument `tex_input_directory` is the directory relative to which to
        search for input files.

        If `strict_input` is set to `True`, then we always check that the
        referenced file lies within the subtree of `tex_input_directory`,
        prohibiting for instance hacks with '..' in filenames or using symbolic
        links to refer to files out of the directory tree.

        The argument `latex_walker_init_args` allows you to specify the parse
        flags passed to the constructor of
        :py:class:`pylatexenc.latexwalker.LatexWalker` when parsing the input
        file.
        """
        self.tex_input_directory = tex_input_directory
        self.latex_walker_init_args = latex_walker_init_args if latex_walker_init_args else {}
        self.strict_input = strict_input

        if tex_input_directory:
            self.macro_dict['input'] = MacroDef('input', lambda n: self._callback_input(n))
            self.macro_dict['include'] = MacroDef('include', lambda n: self._callback_input(n))
        else:
            self.macro_dict['input'] = MacroDef('input', discard=True)
            self.macro_dict['include'] = MacroDef('include', discard=True)

def set_tex_input_directory ( self , tex_input_directory , latex_walker_init_args = None , strict_input = True ) : self . tex_input_directory = tex_input_directory self . latex_walker_init_args = latex_walker_init_args if latex_walker_init_args else { } self . strict_input = strict_input if tex_input_directory : self . macro_dict [ 'input' ] = MacroDef ( 'input' , lambda n : self . _callback_input ( n ) ) self . macro_dict [ 'include' ] = MacroDef ( 'include' , lambda n : self . _callback_input ( n ) ) else : self . macro_dict [ 'input' ] = MacroDef ( 'input' , discard = True ) self . macro_dict [ 'include' ] = MacroDef ( 'include' , discard = True )

Set where to look for input files when encountering the \\ input or \\ include macro .


def read_input_file(self, fn):
        """
        This method may be overridden to implement a custom lookup mechanism when
        encountering ``\\input`` or ``\\include`` directives.

        The default implementation looks for a file of the given name relative
        to the directory set by :py:meth:`set_tex_input_directory()`.  If
        `strict_input=True` was set, we ensure strictly that the file resides in
        a subtree of the reference input directory (after canonicalizing the
        paths and resolving all symlinks).

        You may override this method to obtain the input data in however way you
        see fit.  (In that case, a call to `set_tex_input_directory()` may not
        be needed as that function simply sets properties which are used by the
        default implementation of `read_input_file()`.)

        This function accepts the referred filename as argument (the argument to
        the ``\\input`` macro), and should return a string with the file
        contents (or generate a warning or raise an error).
        """
        fnfull = os.path.realpath(os.path.join(self.tex_input_directory, fn))
        if self.strict_input:
            # make sure that the input file is strictly within dirfull, and didn't escape with
            # '../..' tricks or via symlinks.
            dirfull = os.path.realpath(self.tex_input_directory)
            if not fnfull.startswith(dirfull):
                logger.warning(
                    "Can't access path '%s' leading outside of mandated directory [strict input mode]",
                    fn
                )
                return ''

        if not os.path.exists(fnfull) and os.path.exists(fnfull + '.tex'):
            fnfull = fnfull + '.tex'
        if not os.path.exists(fnfull) and os.path.exists(fnfull + '.latex'):
            fnfull = fnfull + '.latex'
        if not os.path.isfile(fnfull):
            logger.warning(u"Error, file doesn't exist: '%s'", fn)
            return ''

        logger.debug("Reading input file %r", fnfull)

        try:
            with open(fnfull) as f:
                return f.read()
        except IOError as e:
            logger.warning(u"Error, can't access '%s': %s", fn, e)
            return ''

This method may be overridden to implement a custom lookup mechanism when encountering \\ input or \\ include directives .


def latex_to_text(self, latex, **parse_flags):
        """
        Parses the given `latex` code and returns its textual representation.

        The `parse_flags` are the flags to give on to the
        :py:class:`pylatexenc.latexwalker.LatexWalker` constructor.
        """
        return self.nodelist_to_text(latexwalker.LatexWalker(latex, **parse_flags).get_latex_nodes()[0])

def latex_to_text ( self , latex , ** parse_flags ) : return self . nodelist_to_text ( latexwalker . LatexWalker ( latex , ** parse_flags ) . get_latex_nodes ( ) [ 0 ] )

Parses the given latex code and returns its textual representation .


def utf8tolatex(s, non_ascii_only=False, brackets=True, substitute_bad_chars=False, fail_bad_chars=False):
    u"""
    Encode a UTF-8 string to a LaTeX snippet.

    If `non_ascii_only` is set to `True`, then usual (ascii) characters such as ``#``,
    ``{``, ``}`` etc. will not be escaped.  If set to `False` (the default), they are
    escaped to their respective LaTeX escape sequences.

    If `brackets` is set to `True` (the default), then LaTeX macros are enclosed in
    brackets.  For example, ``sant\N{LATIN SMALL LETTER E WITH ACUTE}`` is replaced by
    ``sant{\\'e}`` if `brackets=True` and by ``sant\\'e`` if `brackets=False`.

    .. warning::
        Using `brackets=False` might give you an invalid LaTeX string, so avoid
        it! (for instance, ``ma\N{LATIN SMALL LETTER I WITH CIRCUMFLEX}tre`` will be
        replaced incorrectly by ``ma\\^\\itre`` resulting in an unknown macro ``\\itre``).

    If `substitute_bad_chars=True`, then any non-ascii character for which no LaTeX escape
    sequence is known is replaced by a question mark in boldface. Otherwise (by default),
    the character is left as it is.

    If `fail_bad_chars=True`, then a `ValueError` is raised if we cannot find a
    character substitution for any non-ascii character.

    .. versionchanged:: 1.3

        Added `fail_bad_chars` switch
    """

    s = unicode(s) # make sure s is unicode
    s = unicodedata.normalize('NFC', s)

    if not s:
        return ""

    result = u""
    for ch in s:
        #log.longdebug("Encoding char %r", ch)
        if (non_ascii_only and ord(ch) < 127):
            result += ch
        else:
            lch = utf82latex.get(ord(ch), None)
            if (lch is not None):
                # add brackets if needed, i.e. if we have a substituting macro.
                # note: in condition, beware, that lch might be of zero length.
                result += (  '{'+lch+'}' if brackets and lch[0:1] == '\\' else
                             lch  )
            elif ((ord(ch) >= 32 and ord(ch) <= 127) or
                  (ch in "\n\r\t")):
                # ordinary printable ascii char, just add it
                result += ch
            else:
                # non-ascii char
                msg = u"Character cannot be encoded into LaTeX: U+%04X - `%s'" % (ord(ch), ch)
                if fail_bad_chars:
                    raise ValueError(msg)

                log.warning(msg)
                if substitute_bad_chars:
                    result += r'{\bfseries ?}'
                else:
                    # keep unescaped char
                    result += ch

    return result

u Encode a UTF - 8 string to a LaTeX snippet .


def _unascii(s):
    """Unpack `\\uNNNN` escapes in 's' and encode the result as UTF-8

    This method takes the output of the JSONEncoder and expands any \\uNNNN
    escapes it finds (except for \\u0000 to \\u001F, which are converted to
    \\xNN escapes).

    For performance, it assumes that the input is valid JSON, and performs few
    sanity checks.
    """

    # make the fast path fast: if there are no matches in the string, the
    # whole thing is ascii. On python 2, that means we're done. On python 3,
    # we have to turn it into a bytes, which is quickest with encode('utf-8')
    m = _U_ESCAPE.search(s)
    if not m:
        return s if PY2 else s.encode('utf-8')

    # appending to a string (or a bytes) is slooow, so we accumulate sections
    # of string result in 'chunks', and join them all together later.
    # (It doesn't seem to make much difference whether we accumulate
    # utf8-encoded bytes, or strings which we utf-8 encode after rejoining)
    #
    chunks = []

    # 'pos' tracks the index in 's' that we have processed into 'chunks' so
    # far.
    pos = 0

    while m:
        start = m.start()
        end = m.end()

        g = m.group(1)

        if g is None:
            # escaped backslash: pass it through along with anything before the
            # match
            chunks.append(s[pos:end])
        else:
            # \uNNNN, but we have to watch out for surrogate pairs.
            #
            # On python 2, str.encode("utf-8") will decode utf-16 surrogates
            # before re-encoding, so it's fine for us to pass the surrogates
            # through. (Indeed we must, to deal with UCS-2 python builds, per
            # https://github.com/matrix-org/python-canonicaljson/issues/12).
            #
            # On python 3, str.encode("utf-8") complains about surrogates, so
            # we have to unpack them.
            c = int(g, 16)

            if c < 0x20:
                # leave as a \uNNNN escape
                chunks.append(s[pos:end])
            else:
                if PY3:   # pragma nocover
                    if c & 0xfc00 == 0xd800 and s[end:end + 2] == '\\u':
                        esc2 = s[end + 2:end + 6]
                        c2 = int(esc2, 16)
                        if c2 & 0xfc00 == 0xdc00:
                            c = 0x10000 + (((c - 0xd800) << 10) |
                                           (c2 - 0xdc00))
                            end += 6

                chunks.append(s[pos:start])
                chunks.append(unichr(c))

        pos = end
        m = _U_ESCAPE.search(s, pos)

    # pass through anything after the last match
    chunks.append(s[pos:])

    return (''.join(chunks)).encode("utf-8")

def _unascii ( s ) : m = _U_ESCAPE . search ( s ) if not m : return s if PY2 else s . encode ( 'utf-8' ) chunks = [ ] pos = 0 while m : start = m . start ( ) end = m . end ( ) g = m . group ( 1 ) if g is None : chunks . append ( s [ pos : end ] ) else : c = int ( g , 16 ) if c < 0x20 : chunks . append ( s [ pos : end ] ) else : if PY3 : if c & 0xfc00 == 0xd800 and s [ end : end + 2 ] == '\\u' : esc2 = s [ end + 2 : end + 6 ] c2 = int ( esc2 , 16 ) if c2 & 0xfc00 == 0xdc00 : c = 0x10000 + ( ( ( c - 0xd800 ) << 10 ) | ( c2 - 0xdc00 ) ) end += 6 chunks . append ( s [ pos : start ] ) chunks . append ( unichr ( c ) ) pos = end m = _U_ESCAPE . search ( s , pos ) chunks . append ( s [ pos : ] ) return ( '' . join ( chunks ) ) . encode ( "utf-8" )

Unpack \\ uNNNN escapes in s and encode the result as UTF - 8


def get_organisation_information(self, query_params=None):
        '''
        Get information fot this organisation. Returns a dictionary of values.
        '''
        return self.fetch_json(
            uri_path=self.base_uri,
            query_params=query_params or {}
        )

def get_organisation_information ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri , query_params = query_params or { } )

Get information fot this organisation . Returns a dictionary of values .


def get_boards(self, **query_params):
        '''
        Get all the boards for this organisation. Returns a list of Board s.

        Returns:
            list(Board): The boards attached to this organisation
        '''
        boards = self.get_boards_json(self.base_uri, query_params=query_params)

        boards_list = []
        for board_json in boards:
            boards_list.append(self.create_board(board_json))

        return boards_list

def get_boards ( self , ** query_params ) : boards = self . get_boards_json ( self . base_uri , query_params = query_params ) boards_list = [ ] for board_json in boards : boards_list . append ( self . create_board ( board_json ) ) return boards_list

Get all the boards for this organisation . Returns a list of Board s .


def get_members(self, **query_params):
        '''
        Get all members attached to this organisation. Returns a list of
        Member objects

        Returns:
            list(Member): The members attached to this organisation
        '''
        members = self.get_members_json(self.base_uri,
                                        query_params=query_params)

        members_list = []
        for member_json in members:
            members_list.append(self.create_member(member_json))

        return members_list

def get_members ( self , ** query_params ) : members = self . get_members_json ( self . base_uri , query_params = query_params ) members_list = [ ] for member_json in members : members_list . append ( self . create_member ( member_json ) ) return members_list

Get all members attached to this organisation . Returns a list of Member objects


def update_organisation(self, query_params=None):
        '''
        Update this organisations information. Returns a new organisation
        object.
        '''
        organisation_json = self.fetch_json(
            uri_path=self.base_uri,
            http_method='PUT',
            query_params=query_params or {}
        )

        return self.create_organisation(organisation_json)

def update_organisation ( self , query_params = None ) : organisation_json = self . fetch_json ( uri_path = self . base_uri , http_method = 'PUT' , query_params = query_params or { } ) return self . create_organisation ( organisation_json )

Update this organisations information . Returns a new organisation object .


def remove_member(self, member_id):
        '''
        Remove a member from the organisation.Returns JSON of all members if
        successful or raises an Unauthorised exception if not.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/members/%s' % member_id,
            http_method='DELETE'
        )

def remove_member ( self , member_id ) : return self . fetch_json ( uri_path = self . base_uri + '/members/%s' % member_id , http_method = 'DELETE' )

Remove a member from the organisation . Returns JSON of all members if successful or raises an Unauthorised exception if not .


def add_member_by_id(self, member_id, membership_type='normal'):
        '''
        Add a member to the board using the id. Membership type can be
        normal or admin. Returns JSON of all members if successful or raises an
        Unauthorised exception if not.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/members/%s' % member_id,
            http_method='PUT',
            query_params={
                'type': membership_type
            }
        )

def add_member_by_id ( self , member_id , membership_type = 'normal' ) : return self . fetch_json ( uri_path = self . base_uri + '/members/%s' % member_id , http_method = 'PUT' , query_params = { 'type' : membership_type } )

Add a member to the board using the id . Membership type can be normal or admin . Returns JSON of all members if successful or raises an Unauthorised exception if not .


def add_member(self, email, fullname, membership_type='normal'):
        '''
        Add a member to the board. Membership type can be normal or admin.
        Returns JSON of all members if successful or raises an Unauthorised
        exception if not.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/members',
            http_method='PUT',
            query_params={
                'email': email,
                'fullName': fullname,
                'type': membership_type
            }
        )

def add_member ( self , email , fullname , membership_type = 'normal' ) : return self . fetch_json ( uri_path = self . base_uri + '/members' , http_method = 'PUT' , query_params = { 'email' : email , 'fullName' : fullname , 'type' : membership_type } )

Add a member to the board . Membership type can be normal or admin . Returns JSON of all members if successful or raises an Unauthorised exception if not .


def get_list_information(self, query_params=None):
        '''
        Get information for this list. Returns a dictionary of values.
        '''
        return self.fetch_json(
            uri_path=self.base_uri,
            query_params=query_params or {}
        )

def get_list_information ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri , query_params = query_params or { } )

Get information for this list . Returns a dictionary of values .


def add_card(self, query_params=None):
        '''
        Create a card for this list. Returns a Card object.
        '''
        card_json = self.fetch_json(
            uri_path=self.base_uri + '/cards',
            http_method='POST',
            query_params=query_params or {}
        )

        return self.create_card(card_json)

def add_card ( self , query_params = None ) : card_json = self . fetch_json ( uri_path = self . base_uri + '/cards' , http_method = 'POST' , query_params = query_params or { } ) return self . create_card ( card_json )

Create a card for this list . Returns a Card object .


def get_label_information(self, query_params=None):
        '''
        Get all information for this Label. Returns a dictionary of values.
        '''
        return self.fetch_json(
            uri_path=self.base_uri,
            query_params=query_params or {}
        )

def get_label_information ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri , query_params = query_params or { } )

Get all information for this Label . Returns a dictionary of values .


def get_items(self, query_params=None):
        '''
        Get all the items for this label. Returns a list of dictionaries.
        Each dictionary has the values for an item.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/checkItems',
            query_params=query_params or {}
        )

def get_items ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri + '/checkItems' , query_params = query_params or { } )

Get all the items for this label . Returns a list of dictionaries . Each dictionary has the values for an item .


def _update_label_name(self, name):
        '''
        Update the current label's name. Returns a new Label object.
        '''
        label_json = self.fetch_json(
            uri_path=self.base_uri,
            http_method='PUT',
            query_params={'name': name}
        )

        return self.create_label(label_json)

def _update_label_name ( self , name ) : label_json = self . fetch_json ( uri_path = self . base_uri , http_method = 'PUT' , query_params = { 'name' : name } ) return self . create_label ( label_json )

Update the current label s name . Returns a new Label object .


def _update_label_dict(self, query_params={}):
        '''
        Update the current label. Returns a new Label object.
        '''
        label_json = self.fetch_json(
            uri_path=self.base_uri,
            http_method='PUT',
            query_params=query_params
        )

        return self.create_label(label_json)

def _update_label_dict ( self , query_params = { } ) : label_json = self . fetch_json ( uri_path = self . base_uri , http_method = 'PUT' , query_params = query_params ) return self . create_label ( label_json )

Update the current label . Returns a new Label object .


def get_authorisation_url(self, application_name, token_expire='1day'):
        '''
        Returns a URL that needs to be opened in a browser to retrieve an
        access token.
        '''
        query_params = {
            'name': application_name,
            'expiration': token_expire,
            'response_type': 'token',
            'scope': 'read,write'
        }

        authorisation_url = self.build_uri(
            path='/authorize',
            query_params=self.add_authorisation(query_params)
        )

        print('Please go to the following URL and get the user authorisation '
              'token:\n', authorisation_url)
        return authorisation_url

Returns a URL that needs to be opened in a browser to retrieve an access token .


def get_card_information(self, query_params=None):
        '''
        Get information for this card. Returns a dictionary of values.
        '''
        return self.fetch_json(
            uri_path=self.base_uri,
            query_params=query_params or {}
        )

def get_card_information ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri , query_params = query_params or { } )

Get information for this card . Returns a dictionary of values .


def get_board(self, **query_params):
        '''
        Get board information for this card. Returns a Board object.

        Returns:
            Board: The board this card is attached to
        '''
        board_json = self.get_board_json(self.base_uri,
                                         query_params=query_params)
        return self.create_board(board_json)

def get_board ( self , ** query_params ) : board_json = self . get_board_json ( self . base_uri , query_params = query_params ) return self . create_board ( board_json )

Get board information for this card . Returns a Board object .


def get_list(self, **query_params):
        '''
        Get list information for this card. Returns a List object.

        Returns:
            List: The list this card is attached to
        '''
        list_json = self.get_list_json(self.base_uri,
                                       query_params=query_params)
        return self.create_list(list_json)

def get_list ( self , ** query_params ) : list_json = self . get_list_json ( self . base_uri , query_params = query_params ) return self . create_list ( list_json )

Get list information for this card . Returns a List object .


def get_checklists(self, **query_params):
        '''
        Get the checklists for this card. Returns a list of Checklist objects.

        Returns:
            list(Checklist): The checklists attached to this card
        '''
        checklists = self.get_checklist_json(self.base_uri,
                                             query_params=query_params)

        checklists_list = []
        for checklist_json in checklists:
            checklists_list.append(self.create_checklist(checklist_json))

        return checklists_list

def get_checklists ( self , ** query_params ) : checklists = self . get_checklist_json ( self . base_uri , query_params = query_params ) checklists_list = [ ] for checklist_json in checklists : checklists_list . append ( self . create_checklist ( checklist_json ) ) return checklists_list

Get the checklists for this card . Returns a list of Checklist objects .


def add_comment(self, comment_text):
        '''
        Adds a comment to this card by the current user.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/actions/comments',
            http_method='POST',
            query_params={'text': comment_text}
        )

def add_comment ( self , comment_text ) : return self . fetch_json ( uri_path = self . base_uri + '/actions/comments' , http_method = 'POST' , query_params = { 'text' : comment_text } )

Adds a comment to this card by the current user .


def add_attachment(self, filename, open_file):
        '''
        Adds an attachment to this card.
        '''
        fields = {
            'api_key': self.client.api_key,
            'token': self.client.user_auth_token
        }

        content_type, body = self.encode_multipart_formdata(
            fields=fields,
            filename=filename,
            file_values=open_file
        )

        return self.fetch_json(
            uri_path=self.base_uri + '/attachments',
            http_method='POST',
            body=body,
            headers={'Content-Type': content_type},
        )

def add_attachment ( self , filename , open_file ) : fields = { 'api_key' : self . client . api_key , 'token' : self . client . user_auth_token } content_type , body = self . encode_multipart_formdata ( fields = fields , filename = filename , file_values = open_file ) return self . fetch_json ( uri_path = self . base_uri + '/attachments' , http_method = 'POST' , body = body , headers = { 'Content-Type' : content_type } , )


def add_checklist(self, query_params=None):
        '''
        Add a checklist to this card. Returns a Checklist object.
        '''
        checklist_json = self.fetch_json(
            uri_path=self.base_uri + '/checklists',
            http_method='POST',
            query_params=query_params or {}
        )

        return self.create_checklist(checklist_json)

def add_checklist ( self , query_params = None ) : checklist_json = self . fetch_json ( uri_path = self . base_uri + '/checklists' , http_method = 'POST' , query_params = query_params or { } ) return self . create_checklist ( checklist_json )

Add a checklist to this card . Returns a Checklist object .


def _add_label_from_dict(self, query_params=None):
        '''
        Add a label to this card, from a dictionary.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/labels',
            http_method='POST',
            query_params=query_params or {}
        )

def _add_label_from_dict ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri + '/labels' , http_method = 'POST' , query_params = query_params or { } )

Add a label to this card from a dictionary .


def _add_label_from_class(self, label=None):
        '''
        Add an existing label to this card.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/idLabels',
            http_method='POST',
            query_params={'value': label.id}
        )

def _add_label_from_class ( self , label = None ) : return self . fetch_json ( uri_path = self . base_uri + '/idLabels' , http_method = 'POST' , query_params = { 'value' : label . id } )


def add_member(self, member_id):
        '''
        Add a member to this card. Returns a list of Member objects.
        '''
        members = self.fetch_json(
            uri_path=self.base_uri + '/idMembers',
            http_method='POST',
            query_params={'value': member_id}
        )

        members_list = []
        for member_json in members:
            members_list.append(self.create_member(member_json))

        return members_list

def add_member ( self , member_id ) : members = self . fetch_json ( uri_path = self . base_uri + '/idMembers' , http_method = 'POST' , query_params = { 'value' : member_id } ) members_list = [ ] for member_json in members : members_list . append ( self . create_member ( member_json ) ) return members_list

Add a member to this card . Returns a list of Member objects .


def get_member_information(self, query_params=None):
        '''
        Get Information for a member. Returns a dictionary of values.

        Returns:
            dict
        '''
        return self.fetch_json(
            uri_path=self.base_uri,
            query_params=query_params or {}
        )

def get_member_information ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri , query_params = query_params or { } )

Get Information for a member . Returns a dictionary of values .


def get_cards(self, **query_params):
        '''
        Get all cards this member is attached to. Return a list of Card
        objects.

        Returns:
            list(Card): Return all cards this member is attached to
        '''
        cards = self.get_cards_json(self.base_uri, query_params=query_params)

        cards_list = []
        for card_json in cards:
            cards_list.append(self.create_card(card_json))

        return cards_list

def get_cards ( self , ** query_params ) : cards = self . get_cards_json ( self . base_uri , query_params = query_params ) cards_list = [ ] for card_json in cards : cards_list . append ( self . create_card ( card_json ) ) return cards_list

Get all cards this member is attached to . Return a list of Card objects .


def get_organisations(self, **query_params):
        '''
        Get all organisations this member is attached to. Return a list of
        Organisation objects.

        Returns:
            list(Organisation): Return all organisations this member is
            attached to
        '''
        organisations = self.get_organisations_json(self.base_uri,
                                                    query_params=query_params)

        organisations_list = []
        for organisation_json in organisations:
            organisations_list.append(
                self.create_organisation(organisation_json))

        return organisations_list

def get_organisations ( self , ** query_params ) : organisations = self . get_organisations_json ( self . base_uri , query_params = query_params ) organisations_list = [ ] for organisation_json in organisations : organisations_list . append ( self . create_organisation ( organisation_json ) ) return organisations_list

Get all organisations this member is attached to . Return a list of Organisation objects .


def create_new_board(self, query_params=None):
        '''
        Create a new board. name is required in query_params. Returns a Board
        object.

        Returns:
            Board: Returns the created board
        '''
        board_json = self.fetch_json(
            uri_path='/boards',
            http_method='POST',
            query_params=query_params or {}
        )
        return self.create_board(board_json)

def create_new_board ( self , query_params = None ) : board_json = self . fetch_json ( uri_path = '/boards' , http_method = 'POST' , query_params = query_params or { } ) return self . create_board ( board_json )

Create a new board . name is required in query_params . Returns a Board object .


def singledispatchmethod(method):
    '''
    Enable singledispatch for class methods.

    See http://stackoverflow.com/a/24602374/274318
    '''
    dispatcher = singledispatch(method)
    def wrapper(*args, **kw):
        return dispatcher.dispatch(args[1].__class__)(*args, **kw)
    wrapper.register = dispatcher.register
    update_wrapper(wrapper, dispatcher)
    return wrapper

def singledispatchmethod ( method ) : dispatcher = singledispatch ( method ) def wrapper ( * args , ** kw ) : return dispatcher . dispatch ( args [ 1 ] . __class__ ) ( * args , ** kw ) wrapper . register = dispatcher . register update_wrapper ( wrapper , dispatcher ) return wrapper

Enable singledispatch for class methods .


def get_board_information(self, query_params=None):
        '''
        Get all information for this board. Returns a dictionary of values.
        '''
        return self.fetch_json(
            uri_path='/boards/' + self.id,
            query_params=query_params or {}
        )

def get_board_information ( self , query_params = None ) : return self . fetch_json ( uri_path = '/boards/' + self . id , query_params = query_params or { } )

Get all information for this board . Returns a dictionary of values .


def get_lists(self, **query_params):
        '''
        Get the lists attached to this board. Returns a list of List objects.

        Returns:
            list(List): The lists attached to this board
        '''
        lists = self.get_lists_json(self.base_uri, query_params=query_params)

        lists_list = []
        for list_json in lists:
            lists_list.append(self.create_list(list_json))

        return lists_list

def get_lists ( self , ** query_params ) : lists = self . get_lists_json ( self . base_uri , query_params = query_params ) lists_list = [ ] for list_json in lists : lists_list . append ( self . create_list ( list_json ) ) return lists_list

Get the lists attached to this board . Returns a list of List objects .


def get_labels(self, **query_params):
        '''
        Get the labels attached to this board. Returns a label of Label
        objects.

        Returns:
            list(Label): The labels attached to this board
        '''
        labels = self.get_labels_json(self.base_uri, query_params=query_params)

        labels_list = []
        for label_json in labels:
            labels_list.append(self.create_label(label_json))

        return labels_list

def get_labels ( self , ** query_params ) : labels = self . get_labels_json ( self . base_uri , query_params = query_params ) labels_list = [ ] for label_json in labels : labels_list . append ( self . create_label ( label_json ) ) return labels_list

Get the labels attached to this board . Returns a label of Label objects .


def get_card(self, card_id, **query_params):
        '''
        Get a Card for a given card id. Returns a Card object.

        Returns:
            Card: The card with the given card_id
        '''
        card_json = self.fetch_json(
            uri_path=self.base_uri + '/cards/' + card_id
        )

        return self.create_card(card_json)

def get_card ( self , card_id , ** query_params ) : card_json = self . fetch_json ( uri_path = self . base_uri + '/cards/' + card_id ) return self . create_card ( card_json )

Get a Card for a given card id . Returns a Card object .


def get_checklists( self ):
        """
        Get the checklists for this board. Returns a list of Checklist objects.
        """
        checklists = self.getChecklistsJson( self.base_uri )

        checklists_list = []
        for checklist_json in checklists:
            checklists_list.append( self.createChecklist( checklist_json ) )

        return checklists_list

def get_checklists ( self ) : checklists = self . getChecklistsJson ( self . base_uri ) checklists_list = [ ] for checklist_json in checklists : checklists_list . append ( self . createChecklist ( checklist_json ) ) return checklists_list

Get the checklists for this board . Returns a list of Checklist objects .


def get_organisation(self, **query_params):
        '''
        Get the Organisation for this board. Returns Organisation object.

        Returns:
            list(Organisation): The organisation attached to this board
        '''
        organisation_json = self.get_organisations_json(
            self.base_uri, query_params=query_params)

        return self.create_organisation(organisation_json)

def get_organisation ( self , ** query_params ) : organisation_json = self . get_organisations_json ( self . base_uri , query_params = query_params ) return self . create_organisation ( organisation_json )

Get the Organisation for this board . Returns Organisation object .


def update_board(self, query_params=None):
        '''
        Update this board's information. Returns a new board.
        '''
        board_json = self.fetch_json(
            uri_path=self.base_uri,
            http_method='PUT',
            query_params=query_params or {}
        )

        return self.create_board(board_json)

def update_board ( self , query_params = None ) : board_json = self . fetch_json ( uri_path = self . base_uri , http_method = 'PUT' , query_params = query_params or { } ) return self . create_board ( board_json )

Update this board s information . Returns a new board .


def add_list(self, query_params=None):
        '''
        Create a list for a board. Returns a new List object.
        '''
        list_json = self.fetch_json(
            uri_path=self.base_uri + '/lists',
            http_method='POST',
            query_params=query_params or {}
        )

        return self.create_list(list_json)

def add_list ( self , query_params = None ) : list_json = self . fetch_json ( uri_path = self . base_uri + '/lists' , http_method = 'POST' , query_params = query_params or { } ) return self . create_list ( list_json )

Create a list for a board . Returns a new List object .


def add_label(self, query_params=None):
        '''
        Create a label for a board. Returns a new Label object.
        '''
        list_json = self.fetch_json(
            uri_path=self.base_uri + '/labels',
            http_method='POST',
            query_params=query_params or {}
        )

        return self.create_label(list_json)

def add_label ( self , query_params = None ) : list_json = self . fetch_json ( uri_path = self . base_uri + '/labels' , http_method = 'POST' , query_params = query_params or { } ) return self . create_label ( list_json )

Create a label for a board . Returns a new Label object .


def get_checklist_information(self, query_params=None):
        '''
        Get all information for this Checklist. Returns a dictionary of values.
        '''
        # We don't use trelloobject.TrelloObject.get_checklist_json, because
        # that is meant to return lists of checklists.
        return self.fetch_json(
            uri_path=self.base_uri,
            query_params=query_params or {}
        )

def get_checklist_information ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri , query_params = query_params or { } )

Get all information for this Checklist . Returns a dictionary of values .


def get_card(self):
        '''
        Get card this checklist is on.
        '''
        card_id = self.get_checklist_information().get('idCard', None)
        if card_id:
            return self.client.get_card(card_id)

def get_card ( self ) : card_id = self . get_checklist_information ( ) . get ( 'idCard' , None ) if card_id : return self . client . get_card ( card_id )


def get_item_objects(self, query_params=None):
        """
        Get the items for this checklist. Returns a list of ChecklistItem objects.
        """
        card = self.get_card()
        checklistitems_list = []
        for checklistitem_json in self.get_items(query_params):
            checklistitems_list.append(self.create_checklist_item(card.id, self.id, checklistitem_json))

        return checklistitems_list

def get_item_objects ( self , query_params = None ) : card = self . get_card ( ) checklistitems_list = [ ] for checklistitem_json in self . get_items ( query_params ) : checklistitems_list . append ( self . create_checklist_item ( card . id , self . id , checklistitem_json ) ) return checklistitems_list

Get the items for this checklist . Returns a list of ChecklistItem objects .


def update_checklist(self, name):
        '''
        Update the current checklist. Returns a new Checklist object.
        '''
        checklist_json = self.fetch_json(
            uri_path=self.base_uri,
            http_method='PUT',
            query_params={'name': name}
        )

        return self.create_checklist(checklist_json)

def update_checklist ( self , name ) : checklist_json = self . fetch_json ( uri_path = self . base_uri , http_method = 'PUT' , query_params = { 'name' : name } ) return self . create_checklist ( checklist_json )

Update the current checklist . Returns a new Checklist object .


def add_item(self, query_params=None):
        '''
        Add an item to this checklist. Returns a dictionary of values of new
        item.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/checkItems',
            http_method='POST',
            query_params=query_params or {}
        )

def add_item ( self , query_params = None ) : return self . fetch_json ( uri_path = self . base_uri + '/checkItems' , http_method = 'POST' , query_params = query_params or { } )

Add an item to this checklist . Returns a dictionary of values of new item .


def remove_item(self, item_id):
        '''
        Deletes an item from this checklist.
        '''
        return self.fetch_json(
            uri_path=self.base_uri + '/checkItems/' + item_id,
            http_method='DELETE'
        )

def remove_item ( self , item_id ) : return self . fetch_json ( uri_path = self . base_uri + '/checkItems/' + item_id , http_method = 'DELETE' )


def update_name( self, name ):
        """
        Rename the current checklist item. Returns a new ChecklistItem object.
        """
        checklistitem_json = self.fetch_json(
            uri_path = self.base_uri + '/name',
            http_method = 'PUT',
            query_params = {'value': name}
        )

        return self.create_checklist_item(self.idCard, self.idChecklist, checklistitem_json)

def update_name ( self , name ) : checklistitem_json = self . fetch_json ( uri_path = self . base_uri + '/name' , http_method = 'PUT' , query_params = { 'value' : name } ) return self . create_checklist_item ( self . idCard , self . idChecklist , checklistitem_json )

Rename the current checklist item . Returns a new ChecklistItem object .


def update_state(self, state):
        """
        Set the state of the current checklist item. Returns a new ChecklistItem object.
        """
        checklistitem_json = self.fetch_json(
            uri_path = self.base_uri + '/state',
            http_method = 'PUT',
            query_params = {'value': 'complete' if state else 'incomplete'}
        )

        return self.create_checklist_item(self.idCard, self.idChecklist, checklistitem_json)

def update_state ( self , state ) : checklistitem_json = self . fetch_json ( uri_path = self . base_uri + '/state' , http_method = 'PUT' , query_params = { 'value' : 'complete' if state else 'incomplete' } ) return self . create_checklist_item ( self . idCard , self . idChecklist , checklistitem_json )

Set the state of the current checklist item . Returns a new ChecklistItem object .


def add_authorisation(self, query_params):
        '''
        Adds the API key and user auth token to the query parameters
        '''
        query_params['key'] = self.api_key

        if self.user_auth_token:
            query_params['token'] = self.user_auth_token

        return query_params

def add_authorisation ( self , query_params ) : query_params [ 'key' ] = self . api_key if self . user_auth_token : query_params [ 'token' ] = self . user_auth_token return query_params


def check_errors(self, uri, response):
        '''
        Check HTTP reponse for known errors
        '''
        if response.status == 401:
            raise trolly.Unauthorised(uri, response)

        if response.status != 200:
            raise trolly.ResourceUnavailable(uri, response)

def check_errors ( self , uri , response ) : if response . status == 401 : raise trolly . Unauthorised ( uri , response ) if response . status != 200 : raise trolly . ResourceUnavailable ( uri , response )


def build_uri(self, path, query_params):
        '''
        Build the URI for the API call.
        '''
        url = 'https://api.trello.com/1' + self.clean_path(path)
        url += '?' + urlencode(query_params)

        return url

def build_uri ( self , path , query_params ) : url = 'https://api.trello.com/1' + self . clean_path ( path ) url += '?' + urlencode ( query_params ) return url


def fetch_json(self, uri_path, http_method='GET', query_params=None,
                   body=None, headers=None):
        '''
        Make a call to Trello API and capture JSON response. Raises an error
        when it fails.

        Returns:
            dict: Dictionary with the JSON data
        '''
        query_params = query_params or {}
        headers = headers or {}

        query_params = self.add_authorisation(query_params)
        uri = self.build_uri(uri_path, query_params)

        allowed_methods = ("POST", "PUT", "DELETE")
        if http_method in allowed_methods and 'Content-Type' not in headers:
            headers['Content-Type'] = 'application/json'

        headers['Accept'] = 'application/json'
        response, content = self.client.request(
            uri=uri,
            method=http_method,
            body=body,
            headers=headers
        )

        self.check_errors(uri, response)

        return json.loads(content.decode('utf-8'))

def fetch_json ( self , uri_path , http_method = 'GET' , query_params = None , body = None , headers = None ) : query_params = query_params or { } headers = headers or { } query_params = self . add_authorisation ( query_params ) uri = self . build_uri ( uri_path , query_params ) allowed_methods = ( "POST" , "PUT" , "DELETE" ) if http_method in allowed_methods and 'Content-Type' not in headers : headers [ 'Content-Type' ] = 'application/json' headers [ 'Accept' ] = 'application/json' response , content = self . client . request ( uri = uri , method = http_method , body = body , headers = headers ) self . check_errors ( uri , response ) return json . loads ( content . decode ( 'utf-8' ) )

Make a call to Trello API and capture JSON response . Raises an error when it fails .


def create_organisation(self, organisation_json):
        '''
        Create an Organisation object from a JSON object

        Returns:
            Organisation: The organisation from the given `organisation_json`.
        '''
        return trolly.organisation.Organisation(
            trello_client=self,
            organisation_id=organisation_json['id'],
            name=organisation_json['name'],
            data=organisation_json,
        )

def create_organisation ( self , organisation_json ) : return trolly . organisation . Organisation ( trello_client = self , organisation_id = organisation_json [ 'id' ] , name = organisation_json [ 'name' ] , data = organisation_json , )


def create_board(self, board_json):
        '''
        Create Board object from a JSON object

        Returns:
            Board: The board from the given `board_json`.
        '''
        return trolly.board.Board(
            trello_client=self,
            board_id=board_json['id'],
            name=board_json['name'],
            data=board_json,
        )

def create_board ( self , board_json ) : return trolly . board . Board ( trello_client = self , board_id = board_json [ 'id' ] , name = board_json [ 'name' ] , data = board_json , )


def create_label(self, label_json):
        '''
        Create Label object from JSON object

        Returns:
            Label: The label from the given `label_json`.
        '''
        return trolly.label.Label(
            trello_client=self,
            label_id=label_json['id'],
            name=label_json['name'],
            data=label_json,
        )

def create_label ( self , label_json ) : return trolly . label . Label ( trello_client = self , label_id = label_json [ 'id' ] , name = label_json [ 'name' ] , data = label_json , )


def create_list(self, list_json):
        '''
        Create List object from JSON object

        Returns:
            List: The list from the given `list_json`.
        '''
        return trolly.list.List(
            trello_client=self,
            list_id=list_json['id'],
            name=list_json['name'],
            data=list_json,
        )

def create_list ( self , list_json ) : return trolly . list . List ( trello_client = self , list_id = list_json [ 'id' ] , name = list_json [ 'name' ] , data = list_json , )


def create_card(self, card_json):
        '''
        Create a Card object from JSON object

        Returns:
            Card: The card from the given `card_json`.
        '''
        return trolly.card.Card(
            trello_client=self,
            card_id=card_json['id'],
            name=card_json['name'],
            data=card_json,
        )

def create_card ( self , card_json ) : return trolly . card . Card ( trello_client = self , card_id = card_json [ 'id' ] , name = card_json [ 'name' ] , data = card_json , )


def create_checklist(self, checklist_json):
        '''
        Create a Checklist object from JSON object

        Returns:
            Checklist: The checklist from the given `checklist_json`.
        '''
        return trolly.checklist.Checklist(
            trello_client=self,
            checklist_id=checklist_json['id'],
            name=checklist_json['name'],
            data=checklist_json,
        )

def create_checklist ( self , checklist_json ) : return trolly . checklist . Checklist ( trello_client = self , checklist_id = checklist_json [ 'id' ] , name = checklist_json [ 'name' ] , data = checklist_json , )


def create_member(self, member_json):
        '''
        Create a Member object from JSON object

        Returns:
            Member: The member from the given `member_json`.
        '''
        return trolly.member.Member(
            trello_client=self,
            member_id=member_json['id'],
            name=member_json['fullName'],
            data=member_json,
        )

def create_member ( self , member_json ) : return trolly . member . Member ( trello_client = self , member_id = member_json [ 'id' ] , name = member_json [ 'fullName' ] , data = member_json , )


def get_organisation(self, id, name=None):
        '''
        Get an organisation

        Returns:
            Organisation: The organisation with the given `id`
        '''
        return self.create_organisation(dict(id=id, name=name))

def get_organisation ( self , id , name = None ) : return self . create_organisation ( dict ( id = id , name = name ) )


def get_board(self, id, name=None):
        '''
        Get a board

        Returns:
            Board: The board with the given `id`
        '''
        return self.create_board(dict(id=id, name=name))

def get_board ( self , id , name = None ) : return self . create_board ( dict ( id = id , name = name ) )


def get_list(self, id, name=None):
        '''
        Get a list

        Returns:
            List: The list with the given `id`
        '''
        return self.create_list(dict(id=id, name=name))

def get_list ( self , id , name = None ) : return self . create_list ( dict ( id = id , name = name ) )


def get_card(self, id, name=None):
        '''
        Get a card

        Returns:
            Card: The card with the given `id`
        '''
        return self.create_card(dict(id=id, name=name))

def get_card ( self , id , name = None ) : return self . create_card ( dict ( id = id , name = name ) )


def get_checklist(self, id, name=None):
        '''
        Get a checklist

        Returns:
            Checklist: The checklist with the given `id`
        '''
        return self.create_checklist(dict(id=id, name=name))

def get_checklist ( self , id , name = None ) : return self . create_checklist ( dict ( id = id , name = name ) )


def get_member(self, id='me', name=None):
        '''
        Get a member or your current member if `id` wasn't given.

        Returns:
            Member: The member with the given `id`, defaults to the
            logged in member.
        '''
        return self.create_member(dict(id=id, fullName=name))

def get_member ( self , id = 'me' , name = None ) : return self . create_member ( dict ( id = id , fullName = name ) )

Get a member or your current member if id wasn t given .


def domain_from_url(url):
    """
    Get root domain from url.
    Will prune away query strings, url paths, protocol prefix and sub-domains
    Exceptions will be raised on invalid urls
    """
    ext = tldextract.extract(url)
    if not ext.suffix:
        raise InvalidURLException()
    new_url = ext.domain + "." + ext.suffix
    return new_url

def domain_from_url ( url ) : ext = tldextract . extract ( url ) if not ext . suffix : raise InvalidURLException ( ) new_url = ext . domain + "." + ext . suffix return new_url

Get root domain from url . Will prune away query strings url paths protocol prefix and sub - domains Exceptions will be raised on invalid urls


def to_raw_text_markupless(text, keep_whitespace=False, normalize_ascii=True):
    """
    A generator to convert raw text segments, without xml to a
    list of words without any markup.
    Additionally dates are replaced by `7777` for normalization.

    Arguments
    ---------
        text: str, input text to tokenize, strip of markup.
        keep_whitespace : bool, should the output retain the
            whitespace of the input (so that char offsets in the
            output correspond to those in the input).

    Returns
    -------
        generator<list<list<str>>>, a generator for sentences, with
            within each sentence a list of the words separated.
    """
    return sent_tokenize(
        remove_dates(_remove_urls(text)),
        keep_whitespace,
        normalize_ascii
    )

def to_raw_text_markupless ( text , keep_whitespace = False , normalize_ascii = True ) : return sent_tokenize ( remove_dates ( _remove_urls ( text ) ) , keep_whitespace , normalize_ascii )

A generator to convert raw text segments without xml to a list of words without any markup . Additionally dates are replaced by 7777 for normalization .


def to_raw_text(text, keep_whitespace=False, normalize_ascii=True):
    """
    A generator to convert raw text segments, with xml, and other
    non-textual content to a list of words without any markup.
    Additionally dates are replaced by `7777` for normalization.

    Arguments
    ---------
       text: str, input text to tokenize, strip of markup.
       keep_whitespace : bool, should the output retain the
          whitespace of the input (so that char offsets in the
          output correspond to those in the input).

    Returns
    -------
        generator<list<list<str>>>, a generator for sentences, with
            within each sentence a list of the words separated.
    """
    out = text
    out = _remove_urls(text)
    out = _remove_mvar(out)
    out = _remove_squiggly_bracket(out)
    out = _remove_table(out)
    out = _remove_brackets(out)
    out = remove_remaining_double_brackets(out)
    out = remove_markup(out)
    out = remove_wikipedia_link.sub(anchor_replacer, out)
    out = remove_bullets_nbsps.sub(empty_space, out)
    out = remove_dates(out)
    out = remove_math_sections(out)
    out = remove_html(out)
    out = sent_tokenize(out, keep_whitespace, normalize_ascii)
    return out

def to_raw_text ( text , keep_whitespace = False , normalize_ascii = True ) : out = text out = _remove_urls ( text ) out = _remove_mvar ( out ) out = _remove_squiggly_bracket ( out ) out = _remove_table ( out ) out = _remove_brackets ( out ) out = remove_remaining_double_brackets ( out ) out = remove_markup ( out ) out = remove_wikipedia_link . sub ( anchor_replacer , out ) out = remove_bullets_nbsps . sub ( empty_space , out ) out = remove_dates ( out ) out = remove_math_sections ( out ) out = remove_html ( out ) out = sent_tokenize ( out , keep_whitespace , normalize_ascii ) return out

A generator to convert raw text segments with xml and other non - textual content to a list of words without any markup . Additionally dates are replaced by 7777 for normalization .


def to_raw_text_pairings(text, keep_whitespace=False, normalize_ascii=True):
    """
    A generator to convert raw text segments, with xml, and other
    non-textual content to a list of words without any markup.
    Additionally dates are replaced by `7777` for normalization,
    along with wikipedia anchors kept.

    Arguments
    ---------
       text: str, input text to tokenize, strip of markup.
       keep_whitespace : bool, should the output retain the
          whitespace of the input (so that char offsets in the
          output correspond to those in the input).

    Returns
    -------
        generator<list<list<str>>>, a generator for sentences, with
            within each sentence a list of the words separated.
    """
    out = text
    out = _remove_mvar(out)
    out = _remove_squiggly_bracket(out)
    out = _remove_table(out)
    out = remove_markup(out)
    out = remove_wikipedia_link.sub(anchor_replacer, out)
    out = remove_bullets_nbsps.sub(empty_space, out)
    out = remove_math_sections(out)
    out = remove_html(out)
    for sentence in sent_tokenize(out, keep_whitespace, normalize_ascii):
        yield sentence

def to_raw_text_pairings ( text , keep_whitespace = False , normalize_ascii = True ) : out = text out = _remove_mvar ( out ) out = _remove_squiggly_bracket ( out ) out = _remove_table ( out ) out = remove_markup ( out ) out = remove_wikipedia_link . sub ( anchor_replacer , out ) out = remove_bullets_nbsps . sub ( empty_space , out ) out = remove_math_sections ( out ) out = remove_html ( out ) for sentence in sent_tokenize ( out , keep_whitespace , normalize_ascii ) : yield sentence

A generator to convert raw text segments with xml and other non - textual content to a list of words without any markup . Additionally dates are replaced by 7777 for normalization along with wikipedia anchors kept .


def set_password(self, service, username, password):
        """Write the password in the file.
        """
        assoc = self._generate_assoc(service, username)
        # encrypt the password
        password_encrypted = self.encrypt(password.encode('utf-8'), assoc)
        # encode with base64 and add line break to untangle config file
        password_base64 = '\n' + encodebytes(password_encrypted).decode()

        self._write_config_value(service, username, password_base64)

def set_password ( self , service , username , password ) : assoc = self . _generate_assoc ( service , username ) password_encrypted = self . encrypt ( password . encode ( 'utf-8' ) , assoc ) password_base64 = '\n' + encodebytes ( password_encrypted ) . decode ( ) self . _write_config_value ( service , username , password_base64 )


def split_with_locations(text, locations):
    """
    Use an integer list to split the string
    contained in `text`.

    Arguments:
    ----------
        text : str, same length as locations.
        locations : list<int>, contains values
            'SHOULD_SPLIT', 'UNDECIDED', and
            'SHOULD_NOT_SPLIT'. Will create
            strings between each 'SHOULD_SPLIT'
            locations.
    Returns:
    --------
        Generator<str> : the substrings of text
            corresponding to the slices given
            in locations.
    """
    start = 0
    for pos, decision in enumerate(locations):
        if decision == SHOULD_SPLIT:
            if start != pos:
                yield text[start:pos]
            start = pos
    if start != len(text):
        yield text[start:]

def split_with_locations ( text , locations ) : start = 0 for pos , decision in enumerate ( locations ) : if decision == SHOULD_SPLIT : if start != pos : yield text [ start : pos ] start = pos if start != len ( text ) : yield text [ start : ]

Use an integer list to split the string contained in text .