~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/support/werkzeug/useragents.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20080622211713-inlv5k4eifxckelr
ImportĀ upstreamĀ versionĀ 1.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
"""
3
 
    werkzeug.useragents
4
 
    ~~~~~~~~~~~~~~~~~~~
5
 
 
6
 
    This module provides a helper to inspect user agent strings.  This module
7
 
    is far from complete but should work for most of the currently available
8
 
    browsers.
9
 
 
10
 
 
11
 
    :copyright: (c) 2009 by the Werkzeug Team, see AUTHORS for more details.
12
 
    :license: BSD, see LICENSE for more details.
13
 
"""
14
 
import re
15
 
 
16
 
 
17
 
class UserAgentParser(object):
18
 
    """A simple user agent parser.  Used by the `UserAgent`."""
19
 
 
20
 
    platforms = (
21
 
        ('iphone', 'iphone'),
22
 
        (r'darwin|mac|os\s*x', 'macos'),
23
 
        ('win', 'windows'),
24
 
        (r'android', 'android'),
25
 
        (r'x11|lin(\b|ux)?', 'linux'),
26
 
        ('(sun|i86)os', 'solaris'),
27
 
        (r'nintendo\s+wii', 'wii'),
28
 
        ('irix', 'irix'),
29
 
        ('hp-?ux', 'hpux'),
30
 
        ('aix', 'aix'),
31
 
        ('sco|unix_sv', 'sco'),
32
 
        ('bsd', 'bsd'),
33
 
        ('amiga', 'amiga')
34
 
    )
35
 
    browsers = (
36
 
        ('googlebot', 'google'),
37
 
        ('msnbot', 'msn'),
38
 
        ('yahoo', 'yahoo'),
39
 
        ('ask jeeves', 'ask'),
40
 
        (r'aol|america\s+online\s+browser', 'aol'),
41
 
        ('opera', 'opera'),
42
 
        ('chrome', 'chrome'),
43
 
        ('firefox|firebird|phoenix|iceweasel', 'firefox'),
44
 
        ('galeon', 'galeon'),
45
 
        ('safari', 'safari'),
46
 
        ('webkit', 'webkit'),
47
 
        ('camino', 'camino'),
48
 
        ('konqueror', 'konqueror'),
49
 
        ('k-meleon', 'kmeleon'),
50
 
        ('netscape', 'netscape'),
51
 
        (r'msie|microsoft\s+internet\s+explorer', 'msie'),
52
 
        ('lynx', 'lynx'),
53
 
        ('links', 'links'),
54
 
        ('seamonkey|mozilla', 'seamonkey')
55
 
    )
56
 
 
57
 
    _browser_version_re = r'(?:%s)[/\sa-z(]*(\d+[.\da-z]+)?(?i)'
58
 
    _language_re = re.compile(
59
 
        r'(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|'
60
 
        r'(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)'
61
 
    )
62
 
 
63
 
    def __init__(self):
64
 
        self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platforms]
65
 
        self.browsers = [(b, re.compile(self._browser_version_re % a))
66
 
                         for a, b in self.browsers]
67
 
 
68
 
    def __call__(self, user_agent):
69
 
        for platform, regex in self.platforms:
70
 
            match = regex.search(user_agent)
71
 
            if match is not None:
72
 
                break
73
 
        else:
74
 
            platform = None
75
 
        for browser, regex in self.browsers:
76
 
            match = regex.search(user_agent)
77
 
            if match is not None:
78
 
                version = match.group(1)
79
 
                break
80
 
        else:
81
 
            browser = version = None
82
 
        match = self._language_re.search(user_agent)
83
 
        if match is not None:
84
 
            language = match.group(1) or match.group(2)
85
 
        else:
86
 
            language = None
87
 
        return platform, browser, version, language
88
 
 
89
 
 
90
 
class UserAgent(object):
91
 
    """Represents a user agent.  Pass it a WSGI environment or a user agent
92
 
    string and you can inspect some of the details from the user agent
93
 
    string via the attributes.  The following attributes exist:
94
 
 
95
 
    .. attribute:: string
96
 
 
97
 
       the raw user agent string
98
 
 
99
 
    .. attribute:: platform
100
 
 
101
 
       the browser platform.  The following platforms are currently
102
 
       recognized:
103
 
 
104
 
       -   `aix`
105
 
       -   `amiga`
106
 
       -   `android`
107
 
       -   `bsd`
108
 
       -   `hpux`
109
 
       -   `iphone`
110
 
       -   `irix`
111
 
       -   `linux`
112
 
       -   `macos`
113
 
       -   `sco`
114
 
       -   `solaris`
115
 
       -   `wii`
116
 
       -   `windows`
117
 
 
118
 
    .. attribute:: browser
119
 
 
120
 
        the name of the browser.  The following browsers are currently
121
 
        recognized:
122
 
 
123
 
        -   `aol` *
124
 
        -   `ask` *
125
 
        -   `camino`
126
 
        -   `chrome`
127
 
        -   `firefox`
128
 
        -   `galeon`
129
 
        -   `google` *
130
 
        -   `kmeleon`
131
 
        -   `konqueror`
132
 
        -   `links`
133
 
        -   `lynx`
134
 
        -   `msie`
135
 
        -   `msn`
136
 
        -   `netscape`
137
 
        -   `opera`
138
 
        -   `safari`
139
 
        -   `seamonkey`
140
 
        -   `webkit`
141
 
        -   `yahoo` *
142
 
 
143
 
        (Browsers maked with a star (``*``) are crawlers.)
144
 
 
145
 
    .. attribute:: version
146
 
 
147
 
        the version of the browser
148
 
 
149
 
    .. attribute:: language
150
 
 
151
 
        the language of the browser
152
 
    """
153
 
    _parser = UserAgentParser()
154
 
 
155
 
    def __init__(self, environ_or_string):
156
 
        if isinstance(environ_or_string, dict):
157
 
            environ_or_string = environ_or_string.get('HTTP_USER_AGENT', '')
158
 
        self.string = environ_or_string
159
 
        self.platform, self.browser, self.version, self.language = \
160
 
            self._parser(environ_or_string)
161
 
 
162
 
    def to_header(self):
163
 
        return self.string
164
 
 
165
 
    def __str__(self):
166
 
        return self.string
167
 
 
168
 
    def __nonzero__(self):
169
 
        return bool(self.browser)
170
 
 
171
 
    def __repr__(self):
172
 
        return '<%s %r/%s>' % (
173
 
            self.__class__.__name__,
174
 
            self.browser,
175
 
            self.version
176
 
        )
177
 
 
178
 
 
179
 
# conceptionally this belongs in this module but because we want to lazily
180
 
# load the user agent module (which happens in wrappers.py) we have to import
181
 
# it afterwards.  The class itself has the module set to this module so
182
 
# pickle, inspect and similar modules treat the object as if it was really
183
 
# implemented here.
184
 
from werkzeug.wrappers import UserAgentMixin