easymode.utils

Contains utils for:

Matching first item in a list that matches some predicate. Mutex XML parser/generator that handles unknown entities. Controlling recursion depth

easymode.utils.recursion_depth(*args, **kwds)

A context manager used to guard recursion depth for some function. Multiple functions can be kept separately because it will be counted per key.

Any exceptions raise in the recursive function will reset the counter, because the stack will be unwinded.

usage:

with recursion_depth('some_function_name') as recursion_level:
    if recursion_level > getattr(settings, 'RECURSION_LIMIT', sys.getrecursionlimit() / 10):
        raise Exception("Too deep")

    # do some recursive dangerous things.
Parameters:key – The key under which the recursion depth is kept.
easymode.utils.first_match(predicate, list)

returns the first value of predicate applied to list, which does not return None

>>> 
>>> def return_if_even(x): 
...     if x % 2 is 0:
...         return x
...     return None
>>> 
>>> first_match(return_if_even, [1, 3, 4, 7])
4
>>> first_match(return_if_even, [1, 3, 5, 7])
>>>
Parameters:
  • predicate – a function that returns None or a value.
  • list – A list of items that can serve as input to predicate.
Return type:

whatever predicate returns instead of None. (or None).

class easymode.utils.mutex(max_wait=None, lockfile=None)

A semaphore Context Manager that uses a temporary file for locking. Only one thread or process can get a lock on the file at once.

it can be used to mark a block of code as being executed exclusively by some thread. see mutex.

usage:

from __future__ import with_statement
from easymode.utils import mutex

with mutex:
    print "hi only one thread will be executing this block of code at a time."

Mutex raises an easymode.utils.SemaphoreException when it has to wait to long to obtain a lock or when it can not determine how long it was waiting.

Parameters:
  • max_wait – The maximum amount of seconds the process should wait to obtain the semaphore.
  • lockfile – The path and name of the pid file used to create the semaphore.
exception easymode.utils.SemaphoreException

An exception that get thrown when an error occurs in the mutex semphore context

easymode.utils.bases_walker(cls)

Loop through all bases of cls

>>> str = u'hai'
>>> for base in bases_walker(unicode):
...     isinstance(str, base)
True
True
Parameters:cls – The class in which we want to loop through the base classes.
easymode.utils.url_add_params(url, **kwargs)

Add parameters to an url

>>> url_add_params('http://example.com/', a=1, b=3)
'http://example.com/?a=1&b=3'
>>> url_add_params('http://example.com/?c=8', a=1, b=3)
'http://example.com/?c=8&a=1&b=3'
>>> url_add_params('http://example.com/#/irock', a=1, b=3)
'http://example.com/?a=1&b=3#/irock'
>>> url_add_params('http://example.com/?id=10#/irock', a=1, b=3)
'http://example.com/?id=10&a=1&b=3#/irock'

easymode.utils.xmlutils

Contains classes and functions for dealing with html entities.

You need this as soon as you are doing anything with rich text fields and want to use easymode.tree.xml.decorators.toxml().

easymode.utils.xmlutils.unescape_all(string)

Resolve all html entities to their corresponding unicode character

class easymode.utils.xmlutils.XmlScanner(*args, **kwargs)

This class is an xml parser that will not throw errors when unknown entities are found.

It can be used as follows:

parser = sax.make_parser(["easymode.utils.xmlutils"])

All entities that can not be resolved will be skipped. This will trigger skippedEntity on the contentHandler.

A good contenthandler for this scanner is XmlPrinter because it will turn these entities into their unicode characters.

class easymode.utils.xmlutils.XmlPrinter(out=None, encoding='iso-8859-1')

XmlPrinter can be used as a contenthandler for the XmlScanner.

It will convert all skippedEntities to their unicode characters and copy these to the output stream.

You can use it as a simple xml generator, to create xml:

stream = StringIO.StringIO()
xml = XmlPrinter(stream, settings.DEFAULT_CHARSET)

def _render_page(page):
    xml.startElement('title', {})
    xml.characters(page.title)
    xml.endElement('title')
    xml.startElement('template', {})
    xml.characters(page.template)
    xml.endElement('template')

for child in Page.children.all():
    xml.startElement('page', {})
    _render_page(child)
    xml.endElement('page')
easymode.utils.xmlutils.create_parser(*args, **kwargs)

Because this function is defined, you can create an XmlScanner like this:

from xml import sax

parser = sax.make_parser(["easymode.utils.xmlutils"])

easymode.utils.languagecode

Lots of utility functions that can be used when implementing a multi lingual django app.

easymode.utils.languagecode.fix_language_code(url, current_language)

Fixes the language code as follows:

If there is only one language used in the site, it strips the language code. If there are more languages used, it will make sure that the url has the current language as a prefix.

>>> # multiple languages defined
>>> settings.LANGUAGES = (('en-us','English'),('de','German'),('nl-be','Belgium dutch'),('fr-be','Belgium french'),)
>>> settings.USE_SHORT_LANGUAGE_CODES = False
>>> activate('en-us')
>>> fix_language_code('/de/example.html', 'en-us')
'/en-us/example.html'
>>> settings.USE_SHORT_LANGUAGE_CODES = True
>>> fix_language_code('/de/example.html', 'en-us')
'/en/example.html'
>>> fix_language_code('/en/example.html', 'en-us')
'/example.html'
>>> # only one language defined
>>> settings.LANGUAGES = (('en-us', 'English'), )
>>> fix_language_code('/en-us/example.html', 'en-us')
'/example.html'
Parameters:
  • url – The (absolute) url to be fixed eg. ‘/hi/how/is/it’.
  • current_language – A language code defined in settings.LANGUAGES.
Return type:

The fixed url.

easymode.utils.languagecode.get_all_language_codes()

Returns all language codes defined in settings.LANGUAGES and also the settings.MSGID_LANGUAGE if defined.

>>> from django.conf import settings
>>> settings.MSGID_LANGUAGE = 'en-us'
>>> settings.LANGUAGES = (('en','English'),('de','German'),('nl-be','Belgium dutch'),('fr-be','Belgium french'),)
>>> sorted( get_language_codes() )
['en-us', 'en','de', 'nl-be','fr-be']
Return type:A list of language codes.
easymode.utils.languagecode.get_language_code_from_shorthand(short_locale)

Returns the real language_code based on the shorthand.

>>> settings.LANGUAGES = (('en-us','English'),('de','German'),('nl-be','Belgium dutch'),('fr-be','Belgium french'),)
>>> get_language_code_from_shorthand('en')
'en-us'
Parameters:short_locale – The short version of a language code.
Return type:The long version of the language code.
easymode.utils.languagecode.get_language_codes()

Retrieves all the language codes defined in settings.LANGUAGES.

>>> settings.LANGUAGES = (('en','English'),('de','German'),('nl-be','Belgium dutch'),('fr-be','Belgium french'),)
>>> sorted( get_language_codes() )
['de', 'en', 'fr-be', 'nl-be']
Return type:A list of language codes.
easymode.utils.languagecode.get_language_codes_as_disjunction()

return a pattern that matches any language defined in settings.LANGUAGES

>>> from django.conf import settings
>>> settings.USE_SHORT_LANGUAGE_CODES = False
>>> settings.LANGUAGES = (('en-us','English'),('de','German'),('nl-be','Belgium dutch'),('fr-be','Belgium french'),)
>>> get_language_codes_as_disjunction()
'de|en-us|nl-be|fr-be'

usage:

languages = get_language_codes_as_disjunction()
urlpatterns = patterns('',
    url(r'^(%{languages})/admin/' % locals(), include(admin.site.urls), name="language-admin"),
)
easymode.utils.languagecode.get_real_fieldname(field, lang)

Depending on the language a field can have a different name.

If you want to do a query, using a localized field, you have to use the name this function returns, not the default name.

>>> get_real_fieldname('name', 'en-us')
'name_en_us'

Usage:

def index(request):
    published_in_language = get_real_fieldname('published', request.LANGUAGE_CODE)
    qs = SomeModel.objects.filter(**{published_in_language:True})
    return render_to_response('index.html', {'queryset':qs})
Parameters:
  • field – The name of a field in an internationalised model.
  • lang – The language for which you want to know the real name.
Return type:

The actual name of the field in the lang.

easymode.utils.languagecode.get_short_language_codes()

Retrieves the short versions of the language codes defined in settings.LANGUAGES.

>>> from django.conf import settings
>>> settings.LANGUAGES = (('en','English'),('de','German'),('nl-be','Belgium dutch'),('fr-be','Belgium french'),)
>>> sorted( get_short_language_codes() )
['de', 'en', 'fr', 'nl']
Return type:A list of short versions of the language codes.
easymode.utils.languagecode.get_shorthand_from_language_code(locale)

Returns the shorthand, based on the language code.

If USE_SHORT_LANGUAGE_CODES is true it will return a ahorthand, if it is False, it will not modify the code at all.

>>> USE_SHORT_LANGUAGE_CODES = True
>>> get_shorthand_from_language_code('en-us')
'en'
>>> USE_SHORT_LANGUAGE_CODES = False
>>> get_shorthand_from_language_code('en-us')
'en-us'
Parameters:locale – The language code as a unicode string.
Return type:The short version of the language code (when appropriate).
easymode.utils.languagecode.localize_fieldnames(fields, internationalized_fields)

Given a list of fields and a list of field names that are internationalized, will return a list with all internationalized fields properly localized.

>>> from django.utils.translation import activate
>>> activate('en-us')
>>> localize_fieldnames(['name', 'title', 'url'], ['title'])
['name', 'title_en_us', 'url']
Parameters:
  • fields – A list af field names.
  • internationalized_fields – A list of fields names, these fields are internationalized.
Return type:

A list with the actual field names that are used in the current language.

easymode.utils.languagecode.strip_language_code(url)

Strip the language code from the beginning of string

>>> strip_language_code('http://example.com/en/example.html')
'http://example.com/example.html'
Parameters:url – An url.
Return type:The url but the language code is removed.

easymode.utils.polibext

easymode.utils.standin

easymode.utils.standin.standin_for(obj, **attrs)

Returns an object that can be used as a standin for the original object.

The standin object will have extra attrs, which you can define passed as keyword arguments.

Use standin like this:

>>> a = u'I am E.T.'
>>> b = standin_for(a, origin='outerspace', package='easymode.utils.standin')
>>> b
u'I am E.T.'
>>> b == a
True
>>> b.origin
'outerspace'
>>> b.package
'easymode.utils.standin'
>>> isinstance(b, unicode)
True
>>> type(b)
<class 'easymode.utils.standin.unicodeStandInWithOriginAndPackageAttributes'>
>>> import pickle
>>> b_pickle = pickle.dumps(b, pickle.HIGHEST_PROTOCOL)
>>> c = pickle.loads(b_pickle)
>>> b == c
True
>>> c
u'I am E.T.'
>>> c.origin
'outerspace'
>>> c.package
'easymode.utils.standin'

Some types are not supported by standin_for. This is because these types are often used in statements like:

a = True
if a is True:
    print 'hi'

The is keyword checks for equal memory adress, and in case of a standin that can never be True. Also, since it is impossible to extend bool and NoneType you can never get:

isinstance(standin, bool)
isinstance(standin, NoneType)

To work with anything else but the real thing. This is why bool and NoneType instances are returned unmodified:

>>> a = False
>>> b = standin_for(a, crazy=True)
>>> b
False
>>> b.crazy
Traceback (most recent call last):
    ...
AttributeError: 'bool' object has no attribute 'crazy'
Parameters:
  • obj – An instance of some class
  • **attrs

    Attributes that will be added to the standin for obj

Return type:

A new object that can be used where the original was used. However it has extra attributes.

easymode.utils.template

easymode.utils.template.find_template_path(name)

Same as django.template.loader.find_template(), but it only returns the path to the template file.

Table Of Contents

Previous topic

easymode.xslt

Next topic

easymode.admin.utils