view MoinMoin/support/werkzeug/ @ 5801:8de563c487be

upgrade werkzeug to 0.8.1, document current bundled version and current minimum requirement (0.6, for py 2.7 compatibility)
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Thu, 01 Dec 2011 01:34:45 +0100
parents bd3f5ccf6fb6
children 9f12f41504fc
line wrap: on
line source
# -*- coding: utf-8 -*-

    This module provides a helper to inspect user agent strings.  This module
    is far from complete but should work for most of the currently available

    :copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
import re

class UserAgentParser(object):
    """A simple user agent parser.  Used by the `UserAgent`."""

    platforms = (
        ('iphone|ios', 'iphone'),
        (r'darwin|mac|os\s*x', 'macos'),
        ('win', 'windows'),
        (r'android', 'android'),
        (r'x11|lin(\b|ux)?', 'linux'),
        ('(sun|i86)os', 'solaris'),
        (r'nintendo\s+wii', 'wii'),
        ('irix', 'irix'),
        ('hp-?ux', 'hpux'),
        ('aix', 'aix'),
        ('sco|unix_sv', 'sco'),
        ('bsd', 'bsd'),
        ('amiga', 'amiga')
    browsers = (
        ('googlebot', 'google'),
        ('msnbot', 'msn'),
        ('yahoo', 'yahoo'),
        ('ask jeeves', 'ask'),
        (r'aol|america\s+online\s+browser', 'aol'),
        ('opera', 'opera'),
        ('chrome', 'chrome'),
        ('firefox|firebird|phoenix|iceweasel', 'firefox'),
        ('galeon', 'galeon'),
        ('safari', 'safari'),
        ('webkit', 'webkit'),
        ('camino', 'camino'),
        ('konqueror', 'konqueror'),
        ('k-meleon', 'kmeleon'),
        ('netscape', 'netscape'),
        (r'msie|microsoft\s+internet\s+explorer', 'msie'),
        ('lynx', 'lynx'),
        ('links', 'links'),
        ('seamonkey|mozilla', 'seamonkey')

    _browser_version_re = r'(?:%s)[/\sa-z(]*(\d+[.\da-z]+)?(?i)'
    _language_re = re.compile(

    def __init__(self):
        self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platforms]
        self.browsers = [(b, re.compile(self._browser_version_re % a))
                         for a, b in self.browsers]

    def __call__(self, user_agent):
        for platform, regex in self.platforms:
            match =
            if match is not None:
            platform = None
        for browser, regex in self.browsers:
            match =
            if match is not None:
                version =
            browser = version = None
        match =
        if match is not None:
            language = or
            language = None
        return platform, browser, version, language

class UserAgent(object):
    """Represents a user agent.  Pass it a WSGI environment or a user agent
    string and you can inspect some of the details from the user agent
    string via the attributes.  The following attributes exist:

    .. attribute:: string

       the raw user agent string

    .. attribute:: platform

       the browser platform.  The following platforms are currently

       -   `aix`
       -   `amiga`
       -   `android`
       -   `bsd`
       -   `hpux`
       -   `iphone`
       -   `irix`
       -   `linux`
       -   `macos`
       -   `sco`
       -   `solaris`
       -   `wii`
       -   `windows`

    .. attribute:: browser

        the name of the browser.  The following browsers are currently

        -   `aol` *
        -   `ask` *
        -   `camino`
        -   `chrome`
        -   `firefox`
        -   `galeon`
        -   `google` *
        -   `kmeleon`
        -   `konqueror`
        -   `links`
        -   `lynx`
        -   `msie`
        -   `msn`
        -   `netscape`
        -   `opera`
        -   `safari`
        -   `seamonkey`
        -   `webkit`
        -   `yahoo` *

        (Browsers maked with a star (``*``) are crawlers.)

    .. attribute:: version

        the version of the browser

    .. attribute:: language

        the language of the browser

    _parser = UserAgentParser()

    def __init__(self, environ_or_string):
        if isinstance(environ_or_string, dict):
            environ_or_string = environ_or_string.get('HTTP_USER_AGENT', '')
        self.string = environ_or_string
        self.platform, self.browser, self.version, self.language = \

    def to_header(self):
        return self.string

    def __str__(self):
        return self.string

    def __nonzero__(self):
        return bool(self.browser)

    def __repr__(self):
        return '<%s %r/%s>' % (

# conceptionally this belongs in this module but because we want to lazily
# load the user agent module (which happens in we have to import
# it afterwards.  The class itself has the module set to this module so
# pickle, inspect and similar modules treat the object as if it was really
# implemented here.
from werkzeug.wrappers import UserAgentMixin