sphinx-compatible docstrings
This commit is contained in:
@@ -2,9 +2,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
This file is part of the web2py Web Framework
|
||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
| This file is part of the web2py Web Framework
|
||||
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
HTTP statuses helpers
|
||||
--------------------------------------------
|
||||
"""
|
||||
|
||||
import re
|
||||
@@ -58,6 +61,18 @@ defined_status = {
|
||||
regex_status = re.compile('^\d{3} [0-9A-Z ]+$')
|
||||
|
||||
class HTTP(Exception):
|
||||
"""Raises an HTTP response
|
||||
|
||||
Args:
|
||||
status: usually an integer. If it's a well known status code, the ERROR
|
||||
message will be automatically added. A string can also be passed
|
||||
as `510 Foo Bar` and in that case the status code and the error
|
||||
message will be parsed accordingly
|
||||
body: what to return as body. If left as is, will return the error code
|
||||
and the status message in the body itself
|
||||
cookies: pass cookies along (usually not needed)
|
||||
headers: pass headers as usual dict mapping
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -136,6 +151,14 @@ class HTTP(Exception):
|
||||
|
||||
|
||||
def redirect(location='', how=303, client_side=False):
|
||||
"""Raises a redirect (303)
|
||||
|
||||
Args:
|
||||
location: the url where to redirect
|
||||
how: what HTTP status code to use when redirecting
|
||||
client_side: if set to True, it triggers a reload of the entire page
|
||||
when the fragment has been loaded as a component
|
||||
"""
|
||||
if location:
|
||||
from gluon import current
|
||||
loc = location.replace('\r', '%0D').replace('\n', '%0A')
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
This file is part of the web2py Web Framework
|
||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
| This file is part of the web2py Web Framework
|
||||
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
| Plural subsystem is created by Vladyslav Kozlovskyy (Ukraine) <dbdevelop@gmail.com>
|
||||
|
||||
Plural subsystem is created by Vladyslav Kozlovskyy (Ukraine)
|
||||
<dbdevelop@gmail.com>
|
||||
Translation system
|
||||
--------------------------------------------
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -165,7 +166,7 @@ def read_dict_aux(filename):
|
||||
|
||||
|
||||
def read_dict(filename):
|
||||
""" return dictionary with translation messages
|
||||
""" Returns dictionary with translation messages
|
||||
"""
|
||||
return getcfs('lang:' + filename, filename,
|
||||
lambda: read_dict_aux(filename))
|
||||
@@ -173,8 +174,8 @@ def read_dict(filename):
|
||||
|
||||
def read_possible_plural_rules():
|
||||
"""
|
||||
create list of all possible plural rules files
|
||||
result is cached in PLURAL_RULES dictionary to increase speed
|
||||
Creates list of all possible plural rules files
|
||||
The result is cached in PLURAL_RULES dictionary to increase speed
|
||||
"""
|
||||
plurals = {}
|
||||
try:
|
||||
@@ -328,7 +329,7 @@ def write_dict(filename, contents):
|
||||
|
||||
class lazyT(object):
|
||||
"""
|
||||
never to be called explicitly, returned by
|
||||
Never to be called explicitly, returned by
|
||||
translator.__call__() or translator.M()
|
||||
"""
|
||||
m = s = T = f = t = None
|
||||
@@ -428,22 +429,22 @@ copy_reg.pickle(lazyT, pickle_lazyT)
|
||||
|
||||
class translator(object):
|
||||
"""
|
||||
this class is instantiated by gluon.compileapp.build_environment
|
||||
This class is instantiated by gluon.compileapp.build_environment
|
||||
as the T object
|
||||
::
|
||||
|
||||
Example:
|
||||
|
||||
T.force(None) # turns off translation
|
||||
T.force('fr, it') # forces web2py to translate using fr.py or it.py
|
||||
|
||||
T(\"Hello World\") # translates \"Hello World\" using the selected file
|
||||
T("Hello World") # translates "Hello World" using the selected file
|
||||
|
||||
notice 1: there is no need to force since, by default, T uses
|
||||
http_accept_language to determine a translation file.
|
||||
notice 2:
|
||||
en and en-en are considered different languages!
|
||||
notice 3:
|
||||
if language xx-yy is not found force() probes other similar
|
||||
languages using such algorithm:
|
||||
xx-yy.py -> xx.py -> xx-yy*.py -> xx*.py
|
||||
Note:
|
||||
- there is no need to force since, by default, T uses
|
||||
http_accept_language to determine a translation file.
|
||||
- en and en-en are considered different languages!
|
||||
- if language xx-yy is not found force() probes other similar languages
|
||||
using such algorithm: `xx-yy.py -> xx.py -> xx-yy*.py -> xx*.py`
|
||||
"""
|
||||
|
||||
def __init__(self, langpath, http_accept_language):
|
||||
@@ -473,25 +474,26 @@ class translator(object):
|
||||
self.otherTs = {}
|
||||
self.filter = markmin
|
||||
self.ftag = 'markmin'
|
||||
|
||||
self.ns = None
|
||||
|
||||
def get_possible_languages_info(self, lang=None):
|
||||
"""
|
||||
return info for selected language or dictionary with all
|
||||
possible languages info from APP/languages/*.py
|
||||
args:
|
||||
*lang* (str): language
|
||||
returns:
|
||||
if *lang* is defined:
|
||||
return tuple(langcode, langname, langfile_mtime,
|
||||
pluraldict_fname, pluraldict_mtime,
|
||||
prules_langcode, nplurals,
|
||||
get_plural_id, construct_plural_form)
|
||||
or None
|
||||
Returns info for selected language or dictionary with all
|
||||
possible languages info from `APP/languages/*.py`
|
||||
It Returns:
|
||||
|
||||
- a tuple containing::
|
||||
|
||||
langcode, langname, langfile_mtime,
|
||||
pluraldict_fname, pluraldict_mtime,
|
||||
prules_langcode, nplurals,
|
||||
get_plural_id, construct_plural_form
|
||||
|
||||
or None
|
||||
|
||||
- if *lang* is NOT defined a dictionary with all possible
|
||||
languages::
|
||||
|
||||
if *lang* is NOT defined:
|
||||
returns dictionary with all possible languages:
|
||||
{ langcode(from filename):
|
||||
( langcode, # language code from !langcode!
|
||||
langname,
|
||||
@@ -504,6 +506,10 @@ class translator(object):
|
||||
get_plural_id, # get_plural_id() for current language
|
||||
construct_plural_form) # construct_plural_form() for current language
|
||||
}
|
||||
|
||||
Args:
|
||||
lang (str): language
|
||||
|
||||
"""
|
||||
info = read_possible_languages(self.langpath)
|
||||
if lang:
|
||||
@@ -511,19 +517,18 @@ class translator(object):
|
||||
return info
|
||||
|
||||
def get_possible_languages(self):
|
||||
""" get list of all possible languages for current applications """
|
||||
""" Gets list of all possible languages for current application """
|
||||
return list(set(self.current_languages +
|
||||
[lang for lang in read_possible_languages(self.langpath).iterkeys()
|
||||
if lang != 'default']))
|
||||
|
||||
def set_current_languages(self, *languages):
|
||||
"""
|
||||
set current AKA "default" languages
|
||||
setting one of this languages makes force() function
|
||||
turn translation off to use default language
|
||||
Sets current AKA "default" languages
|
||||
Setting one of this languages makes the force() function to turn
|
||||
translation off
|
||||
"""
|
||||
if len(languages) == 1 and isinstance(
|
||||
languages[0], (tuple, list)):
|
||||
if len(languages) == 1 and isinstance(languages[0], (tuple, list)):
|
||||
languages = languages[0]
|
||||
if not languages or languages[0] is None:
|
||||
# set default language from default.py/DEFAULT_LANGUAGE
|
||||
@@ -543,17 +548,19 @@ class translator(object):
|
||||
self.force(self.http_accept_language)
|
||||
|
||||
def plural(self, word, n):
|
||||
""" get plural form of word for number *n*
|
||||
NOTE: *word" MUST be defined in current language
|
||||
(T.accepted_language)
|
||||
""" Gets plural form of word for number *n*
|
||||
invoked from T()/T.M() in `%%{}` tag
|
||||
|
||||
invoked from T()/T.M() in %%{} tag
|
||||
args:
|
||||
word (str): word in singular
|
||||
n (numeric): number plural form created for
|
||||
Args:
|
||||
word (str): word in singular
|
||||
n (numeric): number plural form created for
|
||||
|
||||
Returns:
|
||||
word (str): word in appropriate singular/plural form
|
||||
|
||||
Note:
|
||||
"word" MUST be defined in current language (T.accepted_language)
|
||||
|
||||
returns:
|
||||
(str): word in appropriate singular/plural form
|
||||
"""
|
||||
if int(n) == 1:
|
||||
return word
|
||||
@@ -582,11 +589,10 @@ class translator(object):
|
||||
|
||||
def force(self, *languages):
|
||||
"""
|
||||
|
||||
select language(s) for translation
|
||||
Selects language(s) for translation
|
||||
|
||||
if a list of languages is passed as a parameter,
|
||||
first language from this list that matches the ones
|
||||
the first language from this list that matches the ones
|
||||
from the possible_languages dictionary will be
|
||||
selected
|
||||
|
||||
@@ -691,11 +697,11 @@ class translator(object):
|
||||
self.ns = ns
|
||||
otherT = self.__get_otherT__(language, ns)
|
||||
return otherT(message, symbols, lazy=lazy)
|
||||
|
||||
|
||||
def __get_otherT__(self, language=None, namespace=None):
|
||||
if not language and not namespace:
|
||||
raise Exception('Incorrect parameters')
|
||||
|
||||
|
||||
if namespace:
|
||||
if language:
|
||||
index = '%s/%s' % (namespace, language)
|
||||
@@ -742,7 +748,7 @@ class translator(object):
|
||||
def M(self, message, symbols={}, language=None,
|
||||
lazy=None, filter=None, ftag=None, ns=None):
|
||||
"""
|
||||
get cached translated markmin-message with inserted parametes
|
||||
Gets cached translated markmin-message with inserted parametes
|
||||
if lazy==True lazyT object is returned
|
||||
"""
|
||||
if lazy is None:
|
||||
@@ -760,16 +766,16 @@ class translator(object):
|
||||
|
||||
def get_t(self, message, prefix=''):
|
||||
"""
|
||||
user ## to add a comment into a translation string
|
||||
Use ## to add a comment into a translation string
|
||||
the comment can be useful do discriminate different possible
|
||||
translations for the same string (for example different locations)
|
||||
translations for the same string (for example different locations)::
|
||||
|
||||
T(' hello world ') -> ' hello world '
|
||||
T(' hello world ## token') -> ' hello world '
|
||||
T('hello ## world## token') -> 'hello ## world'
|
||||
T(' hello world ') -> ' hello world '
|
||||
T(' hello world ## token') -> ' hello world '
|
||||
T('hello ## world## token') -> 'hello ## world'
|
||||
|
||||
the ## notation is ignored in multiline strings and strings that
|
||||
start with ##. this is to allow markmin syntax to be translated
|
||||
start with ##. This is needed to allow markmin syntax to be translated
|
||||
"""
|
||||
if isinstance(message, unicode):
|
||||
message = message.encode('utf8')
|
||||
@@ -793,25 +799,30 @@ class translator(object):
|
||||
|
||||
def params_substitution(self, message, symbols):
|
||||
"""
|
||||
substitute parameters from symbols into message using %.
|
||||
also parse %%{} placeholders for plural-forms processing.
|
||||
returns: string with parameters
|
||||
NOTE: *symbols* MUST BE OR tuple OR dict of parameters!
|
||||
Substitutes parameters from symbols into message using %.
|
||||
also parse `%%{}` placeholders for plural-forms processing.
|
||||
|
||||
Returns:
|
||||
string with parameters
|
||||
|
||||
Note:
|
||||
*symbols* MUST BE OR tuple OR dict of parameters!
|
||||
"""
|
||||
def sub_plural(m):
|
||||
"""string in %{} is transformed by this rules:
|
||||
If string starts with \\, ! or ? such transformations
|
||||
take place:
|
||||
"""String in `%{}` is transformed by this rules:
|
||||
If string starts with `\\`, `!` or `?` such transformations
|
||||
take place::
|
||||
|
||||
"!string of words" -> "String of word" (Capitalize)
|
||||
"!!string of words" -> "String Of Word" (Title)
|
||||
"!!!string of words" -> "STRING OF WORD" (Upper)
|
||||
"\\!string of words" -> "!string of word"
|
||||
(remove \\ and disable transformations)
|
||||
"?word?number" -> "word" (return word, if number == 1)
|
||||
"?number" or "??number" -> "" (remove number,
|
||||
if number == 1)
|
||||
"?word?number" -> "number" (if number != 1)
|
||||
|
||||
"!string of words" -> "String of word" (Capitalize)
|
||||
"!!string of words" -> "String Of Word" (Title)
|
||||
"!!!string of words" -> "STRING OF WORD" (Upper)
|
||||
"\\!string of words" -> "!string of word"
|
||||
(remove \\ and disable transformations)
|
||||
"?word?number" -> "word" (return word, if number == 1)
|
||||
"?number" or "??number" -> "" (remove number,
|
||||
if number == 1)
|
||||
"?word?number" -> "number" (if number != 1)
|
||||
"""
|
||||
def sub_tuple(m):
|
||||
""" word[number], !word[number], !!word[number], !!!word[number]
|
||||
@@ -894,7 +905,7 @@ class translator(object):
|
||||
|
||||
def translate(self, message, symbols):
|
||||
"""
|
||||
get cached translated message with inserted parameters(symbols)
|
||||
Gets cached translated message with inserted parameters(symbols)
|
||||
"""
|
||||
message = get_from_cache(self.cache, message,
|
||||
lambda: self.get_t(message))
|
||||
@@ -917,7 +928,8 @@ class translator(object):
|
||||
|
||||
def findT(path, language=DEFAULT_LANGUAGE):
|
||||
"""
|
||||
must be run by the admin app
|
||||
Note:
|
||||
Must be run by the admin app
|
||||
"""
|
||||
lang_file = pjoin(path, 'languages', language + '.py')
|
||||
sentences = read_dict(lang_file)
|
||||
@@ -954,6 +966,10 @@ def findT(path, language=DEFAULT_LANGUAGE):
|
||||
write_dict(lang_file, sentences)
|
||||
|
||||
def update_all_languages(application_path):
|
||||
"""
|
||||
Note:
|
||||
Must be run by the admin app
|
||||
"""
|
||||
path = pjoin(application_path, 'languages/')
|
||||
for language in oslistdir(path):
|
||||
if regex_langfile.match(language):
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
This file is part of the web2py Web Framework
|
||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
Contains:
|
||||
|
||||
- wsgibase: the gluon wsgi application
|
||||
| This file is part of the web2py Web Framework
|
||||
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
The gluon wsgi application
|
||||
---------------------------
|
||||
"""
|
||||
|
||||
if False: import import_all # DO NOT REMOVE PART OF FREEZE PROCESS
|
||||
@@ -135,9 +133,9 @@ HTTPS_SCHEMES = set(('https', 'HTTPS'))
|
||||
|
||||
def get_client(env):
|
||||
"""
|
||||
guess the client address from the environment variables
|
||||
Guesses the client address from the environment variables
|
||||
|
||||
first tries 'http_x_forwarded_for', secondly 'remote_addr'
|
||||
First tries 'http_x_forwarded_for', secondly 'remote_addr'
|
||||
if all fails, assume '127.0.0.1' or '::1' (running locally)
|
||||
"""
|
||||
eget = env.get
|
||||
@@ -160,7 +158,7 @@ def get_client(env):
|
||||
|
||||
def serve_controller(request, response, session):
|
||||
"""
|
||||
this function is used to generate a dynamic page.
|
||||
This function is used to generate a dynamic page.
|
||||
It first runs all models, then runs the function in the controller,
|
||||
and then tries to render the output using a view/template.
|
||||
this function must run from the [application] folder.
|
||||
@@ -234,7 +232,7 @@ class LazyWSGI(object):
|
||||
return self._environ
|
||||
def start_response(self,status='200', headers=[], exec_info=None):
|
||||
"""
|
||||
in controller you can use::
|
||||
in controller you can use:
|
||||
|
||||
- request.wsgi.environ
|
||||
- request.wsgi.start_response
|
||||
@@ -249,7 +247,7 @@ class LazyWSGI(object):
|
||||
"""
|
||||
In you controller use::
|
||||
|
||||
@request.wsgi.middleware(middleware1, middleware2, ...)
|
||||
@request.wsgi.middleware(middleware1, middleware2, ...)
|
||||
|
||||
to decorate actions with WSGI middleware. actions must return strings.
|
||||
uses a simulated environment so it may have weird behavior in some cases
|
||||
@@ -271,9 +269,9 @@ class LazyWSGI(object):
|
||||
|
||||
def wsgibase(environ, responder):
|
||||
"""
|
||||
this is the gluon wsgi application. the first function called when a page
|
||||
is requested (static or dynamic). it can be called by paste.httpserver
|
||||
or by apache mod_wsgi.
|
||||
The gluon wsgi application. The first function called when a page
|
||||
is requested (static or dynamic). It can be called by paste.httpserver
|
||||
or by apache mod_wsgi (or any WSGI-compatible server).
|
||||
|
||||
- fills request with info
|
||||
- the environment variables, replacing '.' with '_'
|
||||
@@ -290,13 +288,11 @@ def wsgibase(environ, responder):
|
||||
2. for dynamic pages:
|
||||
|
||||
- /<application>[/<controller>[/<function>[/<sub>]]][.<extension>]
|
||||
- (sub may go several levels deep, currently 3 levels are supported:
|
||||
sub1/sub2/sub3)
|
||||
|
||||
The naming conventions are:
|
||||
|
||||
- application, controller, function and extension may only contain
|
||||
[a-zA-Z0-9_]
|
||||
`[a-zA-Z0-9_]`
|
||||
- file and sub may also contain '-', '=', '.' and '/'
|
||||
"""
|
||||
eget = environ.get
|
||||
@@ -567,7 +563,7 @@ def wsgibase(environ, responder):
|
||||
|
||||
def save_password(password, port):
|
||||
"""
|
||||
used by main() to save the password in the parameters_port.py file.
|
||||
Used by main() to save the password in the parameters_port.py file.
|
||||
"""
|
||||
|
||||
password_file = abspath('parameters_%i.py' % port)
|
||||
@@ -607,10 +603,10 @@ def appfactory(wsgiapp=wsgibase,
|
||||
generates a wsgi application that does logging and profiling and calls
|
||||
wsgibase
|
||||
|
||||
.. function:: gluon.main.appfactory(
|
||||
[wsgiapp=wsgibase
|
||||
[, logfilename='httpserver.log'
|
||||
[, profilerfilename='profiler.log']]])
|
||||
Args:
|
||||
wsgiapp: the base application
|
||||
logfilename: where to store apache-compatible requests log
|
||||
profiler_dir: where to store profile files
|
||||
|
||||
"""
|
||||
if profilerfilename is not None:
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
This file is part of the web2py Web Framework
|
||||
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
| This file is part of the web2py Web Framework
|
||||
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
Useful regexes
|
||||
---------------
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
Reference in New Issue
Block a user