Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/tags/cherrypy-3.0.0/cherrypy/__init__.py

Revision 1546 (checked in by dowski, 3 years ago)

Preparing for the 3.0.0 release.

  • Property svn:eol-style set to native
Line 
1 """Global module that all modules developing with CherryPy should import."""
2
3 __version__ = '3.0.0'
4
5 from urlparse import urljoin as _urljoin
6
7 from cherrypy._cperror import HTTPError, HTTPRedirect, InternalRedirect, NotFound, CherryPyException
8 from cherrypy._cperror import TimeoutError
9
10 from cherrypy import _cpdispatch as dispatch
11 from cherrypy import _cprequest
12 from cherrypy import _cpengine
13 engine = _cpengine.Engine()
14
15 from cherrypy import _cptools
16 tools = _cptools.default_toolbox
17 Tool = _cptools.Tool
18
19 from cherrypy import _cptree
20 tree = _cptree.Tree()
21 from cherrypy._cptree import Application
22 from cherrypy import _cpwsgi as wsgi
23 from cherrypy import _cpserver
24 server = _cpserver.Server()
25
26 def quickstart(root, script_name="", config=None):
27     """Mount the given root, start the engine and builtin server, then block."""
28     if config:
29         _global_conf_alias.update(config)
30     tree.mount(root, script_name, config)
31     server.quickstart()
32     engine.start()
33
34 try:
35     from threading import local as _local
36 except ImportError:
37     from cherrypy._cpthreadinglocal import local as _local
38
39 # Create a threadlocal object to hold the request, response, and other
40 # objects. In this way, we can easily dump those objects when we stop/start
41 # a new HTTP conversation, yet still refer to them as module-level globals
42 # in a thread-safe way.
43 _serving = _local()
44
45
46 class _ThreadLocalProxy(object):
47    
48     __slots__ = ['__attrname__', '_default_child', '__dict__']
49    
50     def __init__(self, attrname, default):
51         self.__attrname__ = attrname
52         self._default_child = default
53    
54     def _get_child(self):
55         try:
56             return getattr(_serving, self.__attrname__)
57         except AttributeError:
58             # Bind dummy instances of default objects to help introspection.
59             return self._default_child
60    
61     def __getattr__(self, name):
62         return getattr(self._get_child(), name)
63    
64     def __setattr__(self, name, value):
65         if name in ("__attrname__", "_default_child"):
66             object.__setattr__(self, name, value)
67         else:
68             setattr(self._get_child(), name, value)
69    
70     def __delattr__(self, name):
71         delattr(self._get_child(), name)
72    
73     def _get_dict(self):
74         childobject = self._get_child()
75         d = childobject.__class__.__dict__.copy()
76         d.update(childobject.__dict__)
77         return d
78     __dict__ = property(_get_dict)
79    
80     def __getitem__(self, key):
81         return self._get_child()[key]
82    
83     def __setitem__(self, key, value):
84         self._get_child()[key] = value
85    
86     def __delitem__(self, key):
87         del self._get_child()[key]
88
89
90 # Create request and response object (the same objects will be used
91 #   throughout the entire life of the webserver, but will redirect
92 #   to the "_serving" object)
93 from cherrypy.lib import http as _http
94 request = _ThreadLocalProxy('request',
95                             _cprequest.Request(_http.Host("localhost", 80),
96                                                _http.Host("localhost", 1111)))
97 response = _ThreadLocalProxy('response', _cprequest.Response())
98
99 # Create thread_data object as a thread-specific all-purpose storage
100 thread_data = _local()
101
102
103 from cherrypy import _cplogging
104
105 class _GlobalLogManager(_cplogging.LogManager):
106    
107     def __call__(self, *args, **kwargs):
108         try:
109             log = request.app.log
110         except AttributeError:
111             log = self
112         return log.error(*args, **kwargs)
113    
114     def access(self):
115         try:
116             return request.app.log.access()
117         except AttributeError:
118             return _cplogging.LogManager.access(self)
119
120
121 log = _GlobalLogManager()
122 # Set a default screen handler on the global log.
123 log.screen = True
124 log.error_file = ''
125 # Using an access file makes CP about 10% slower. Leave off by default.
126 log.access_file = ''
127
128
129 #                       Helper functions for CP apps                       #
130
131
132 def expose(func=None, alias=None):
133     """Expose the function, optionally providing an alias or set of aliases."""
134    
135     def expose_(func):
136         func.exposed = True
137         if alias is not None:
138             if isinstance(alias, basestring):
139                 parents[alias.replace(".", "_")] = func
140             else:
141                 for a in alias:
142                     parents[a.replace(".", "_")] = func
143         return func
144    
145     import sys, types
146     parents = sys._getframe(1).f_locals
147     if isinstance(func, (types.FunctionType, types.MethodType)):
148         # expose is being called directly, before the method has been bound
149         return expose_(func)
150     else:
151         if alias is None:
152             # expose is being called as a decorator "@expose"
153             func.exposed = True
154             return func
155         else:
156             # expose is returning a decorator "@expose(alias=...)"
157             return expose_
158
159 def url(path="", qs="", script_name=None, base=None, relative=False):
160     """Create an absolute URL for the given path.
161     
162     If 'path' starts with a slash ('/'), this will return
163         (base + script_name + path + qs).
164     If it does not start with a slash, this returns
165         (base + script_name [+ request.path_info] + path + qs).
166     
167     If script_name is None, cherrypy.request will be used
168     to find a script_name, if available.
169     
170     If base is None, cherrypy.request.base will be used (if available).
171     Note that you can use cherrypy.tools.proxy to change this.
172     
173     Finally, note that this function can be used to obtain an absolute URL
174     for the current request path (minus the querystring) by passing no args.
175     If you call url(qs=cherrypy.request.query_string), you should get the
176     original browser URL (assuming no Internal redirections).
177     
178     If relative is False (the default), the output will be an absolute URL
179     (usually including the scheme, host, vhost, and script_name).
180     If relative is True, the output will instead be a URL that is relative
181     to the current request path, perhaps including '..' atoms.
182     """
183     if qs:
184         qs = '?' + qs
185    
186     if request.app:
187         if not path.startswith("/"):
188             # Append/remove trailing slash from path_info as needed
189             # (this is to support mistyped URL's without redirecting;
190             # if you want to redirect, use tools.trailing_slash).
191             pi = request.path_info
192             if request.is_index is True:
193                 if not pi.endswith('/'):
194                     pi = pi + '/'
195             elif request.is_index is False:
196                 if pi.endswith('/') and pi != '/':
197                     pi = pi[:-1]
198            
199             if path == "":
200                 path = pi
201             else:
202                 path = _urljoin(pi, path)
203        
204         if script_name is None:
205             script_name = request.app.script_name
206         if base is None:
207             base = request.base
208        
209         newurl = base + script_name + path + qs
210     else:
211         # No request.app (we're being called outside a request).
212         # We'll have to guess the base from server.* attributes.
213         # This will produce very different results from the above
214         # if you're using vhosts or tools.proxy.
215         if base is None:
216             f = server.socket_file
217             if f:
218                 base = f
219             else:
220                 host = server.socket_host
221                 if not host:
222                     # The empty string signifies INADDR_ANY.
223                     # Look up the host name, which should be
224                     # the safest thing to spit out in a URL.
225                     import socket
226                     host = socket.gethostname()
227                 port = server.socket_port
228                 if server.ssl_certificate:
229                     scheme = "https"
230                     if port != 443:
231                         host += ":%s" % port
232                 else:
233                     scheme = "http"
234                     if port != 80:
235                         host += ":%s" % port
236                 base = "%s://%s" % (scheme, host)
237         path = (script_name or "") + path
238         newurl = base + path + qs
239    
240     if './' in newurl:
241         # Normalize the URL by removing ./ and ../
242         atoms = []
243         for atom in newurl.split('/'):
244             if atom == '.':
245                 pass
246             elif atom == '..':
247                 atoms.pop()
248             else:
249                 atoms.append(atom)
250         newurl = '/'.join(atoms)
251    
252     if relative:
253         old = url().split('/')[:-1]
254         new = newurl.split('/')
255         while old and new:
256             a, b = old[0], new[0]
257             if a != b:
258                 break
259             old.pop(0)
260             new.pop(0)
261         new = (['..'] * len(old)) + new
262         newurl = '/'.join(new)
263    
264     return newurl
265
266
267 # import _cpconfig last so it can reference other top-level objects
268 from cherrypy import _cpconfig
269 # Use _global_conf_alias so quickstart can use 'config' as an arg
270 # without shadowing cherrypy.config.
271 config = _global_conf_alias = _cpconfig.Config()
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets