def _parse_locale(identifier, sep='_'):
    """
    Took from Babel,
    Parse a locale identifier into a tuple of the form::

      ``(language, territory, script, variant)``

    >>> parse_locale('zh_CN')
    ('zh', 'CN', None, None)
    >>> parse_locale('zh_Hans_CN')
    ('zh', 'CN', 'Hans', None)

    The default component separator is "_", but a different separator can be
    specified using the `sep` parameter:

    :see: `IETF RFC 4646 <http://www.ietf.org/rfc/rfc4646.txt>`_
    """
    if '.' in identifier:
        identifier = identifier.split('.', 1)[0]
    if '@' in identifier:
        identifier = identifier.split('@', 1)[0]
    parts = identifier.split(sep)
    lang = parts.pop(0).lower()
    if not lang.isalpha():
        raise ValueError('expected only letters, got %r' % lang)
    script = territory = variant = None
    if parts:
        if len(parts[0]) == 4 and parts[0].isalpha():
            script = parts.pop(0).title()
    if parts:
        if len(parts[0]) == 2 and parts[0].isalpha():
            territory = parts.pop(0).upper()
        elif len(parts[0]) == 3 and parts[0].isdigit():
            territory = parts.pop(0)
    if parts:
        if len(parts[0]) == 4 and parts[0][0].isdigit() or len(parts[0]
            ) >= 5 and parts[0][0].isalpha():
            variant = parts.pop()
    if parts:
        raise ValueError('%r is not a valid locale identifier' % identifier)
    return lang, territory, script, variant
