Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

English 5th: Various text corrections

  • Loading branch information...
commit 739a4c66c06a1aa5de5f4bd07b49e2f04ec30290 1 parent 796e450
@spametki spametki authored
View
10 sources/29-web2py-english/01.markmin
@@ -307,7 +307,7 @@ web2py is composed of the following components:
web2py is distributed in source code, and in binary form for Microsoft Windows and for Mac OS X.
The source code distribution can be used in any platform where Python runs and includes the above-mentioned components.
-To run the source code, you need Python 2.5 or 2.7 pre-installed on the system. You also need one of the supported database engines installed.
+To run the source code, you need Python 2.5, 2.6 or 2.7 pre-installed on the system. You also need one of the supported database engines installed.
For testing and light-demand applications, you can use the SQLite database, included with Python 2.7.
The binary versions of web2py (for Windows and Mac OS X) include a Python 2.7 interpreter and
@@ -329,7 +329,7 @@ This book includes the following chapters, besides this introduction:
- Chapter 5 is a reference for the template language used to build views. It shows how to embed Python code into HTML, and demonstrates the use of helpers (objects that can generate HTML).
- Chapter 6 covers the Database Abstraction Layer, or DAL. The syntax of the DAL is presented through a series of examples.
- Chapter 7 covers forms, form validation and form processing. FORM is the low level helper for form building. SQLFORM is the high level form builder. In Chapter 7 we also discuss Create/Read/Update/Delete (CRUD) API.
-- Chapter 8 covers communication with as sending emails and SMSes.
+- Chapter 8 covers communication features as retrieving and sending emails and SMSes.
- Chapter 9 covers authentication, authorization and the extensible Role-Based Access Control mechanism available in web2py. Mail configuration and CAPTCHA are also discussed here, since they are used for authentication. In the third edition of the book we have added extensive coverage of integration with third-party authentication mechanisms such as OpenID, OAuth, Google, Facebook, LinkedIn, etc.
- Chapter 10 is about creating web services in web2py. We provide examples of integration with the Google Web Toolkit via Pyjamas, and with Adobe Flash via PyAMF.
- Chapter 11 is about web2py and jQuery recipes. web2py is designed mainly for server-side programming, but it includes jQuery, since we have found it to be the best open-source JavaScript library available for effects and Ajax. In this chapter, we discuss how to effectively use jQuery with web2py.
@@ -349,7 +349,7 @@ This book has been written using the markmin syntax and automatically converted
### Support
The main support channel is the usergroup``usergroup``:cite, with dozens of posts every day. Even if you're a newbie, don't hesitate to ask - we'll be pleased to help you.
-There is also a formal issue tracker system on http://code.google.com/p/web2py/issue . Last but not least, you can have professional support (see the web site for details).
+There is also a formal issue tracker system on http://code.google.com/p/web2py/issues . Last but not least, you can have professional support (see the web site for details).
### Contribute
@@ -393,7 +393,7 @@ In all the examples of this book, web2py keywords are shown in bold, while strin
### License
``license``:inxx
-web2py is licensed under the LGPL version 3 License. The full text of the license if available in ref.``lgpl3``:cite.
+web2py is licensed under the LGPL version 3 License. The full text of the license is available in ref.``lgpl3``:cite.
In accordance with LGPL you may:
@@ -426,7 +426,7 @@ PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
**Earlier versions**
Earlier versions of web2py, 1.0.*-1.90.*, were released under the GPL2 license plus a
-commercial exception which, for practical purposes, was very similar to the current LPGLv3.
+commercial exception which, for practical purposes, was very similar to the current LGPLv3.
**Third party software distributed with web2py**
View
6 sources/29-web2py-english/03.markmin
@@ -1419,7 +1419,7 @@ Here @````//// stands for
but "app", "controller", and "function" are omitted thus assuming default.
-Similarly you can use the wiki menu to upload a media file (for example an image) linked to the page. The "manage media" page will show all files you have uploaded and will show the proper expression to link the media file. If, for example you upload a file "test.jpg" with title "beach", the link expression will something like:
+Similarly you can use the wiki menu to upload a media file (for example an image) linked to the page. The "manage media" page will show all the files you have uploaded and will also show the proper expression to link the media file. If, for example you upload a file named "test.jpg" with title "beach", the link expression will be something like:
``
\@////15/beach.jpg
@@ -1438,7 +1438,7 @@ If you create a page with slug "wiki-menu" page it will be interpreted as a desc
``
- Home > \@////index
- Info > \@////info
-- web2py > http://google.com
+- web2py > http://www.web2py.com
- - About us > \@////aboutus
- - Contact us > \@////contactus
``
@@ -1826,7 +1826,7 @@ Mind that this mechanism still assumes all users are trusted. All the apps creat
#### Mobile **admin**
-Notice that the admin application includes "plugin_jqmobile" which packages jQuery Mobile. When admin is accessed from a mobile device; this is detected by web2py and the interface is displayed using a mobile-friendly layout:
+Notice that the admin application includes "plugin_jqmobile" which packages jQuery Mobile. When admin is accessed from a mobile device, this is detected by web2py and the interface is displayed using a mobile-friendly layout:
[[image @///image/mobile.png center 306px]]
View
55 sources/29-web2py-english/04.markmin
@@ -1003,15 +1003,15 @@ Also notice the ``request.env.wsgi_*`` variables. They are specific to the wsgi
- ``response.status``: the HTTP status code integer to be passed to the response. Default is 200 (OK).
- ``response.stream(file, chunk_size, request=request, attachment=False, filename=None, headers=None)``: when a controller returns it, web2py streams the file content back to the client in blocks of size ``chunk_size``. The ``request`` parameter is required to use the chunk start in the HTTP header. ``file`` should be a file path (for backward compatibility, it can also be an open file object, but this is not recommended). As noted above, ``response.download`` should be used to retrieve files stored via an upload field. ``response.stream`` can be used in other cases, such as returning a temporary file or StringIO object created by the controller. If ``attachment`` is True, the Content-Disposition header will be set to "attachment", and if ``filename`` is also provided, it will be added to the Content-Disposition header as well (but only when ``attachment`` is True). If not already included in ``response.headers``, the following response headers will be set automatically: Content-Type, Content-Length, Cache-Control, Pragma, and Last-Modified (the latter three are set to allow browser caching of the file). To override any of these automatic header settings, simply set them in ``response.headers`` before calling ``response.stream``.
- ``response.subtitle``: optional parameter that may be included in the views. It should contain the subtitle of the page.
-- ``response.title``: optional parameter that may be included in the views. It should contain the title of the page and should be rendered by the HTML title TAG in the header.
+- ``response.title``: optional parameter that may be included in the views. It should contain the title of the page and should be rendered inside the html title tag in the header.
- ``response.toolbar``: a function that allows you to embed a toolbar into page for debugging purposes ``{{=response.toolbar()}}``. The toolbar displays request, response, session variables and database access time for each query.
-- ``response._vars``: this variable is accessible only in a view, not in the action. It contains the value returned by the action to the view.
+- ``response._vars``: this variable is accessible only in a view, not in the action. It contains the values returned by the action to the view.
- ``response._caller``: this is a function that wraps all action calls. It defaults to the identity function, but it can be modified in order to catch special types of exception to do extra logging;
``
response._caller = lambda f: f()
``
-- ``response.optimize_css``: if can be set to "concat,minify,inline" to concatenate, minify and inline the CSS files included by web2py.
-- ``response.optimize_js``: if can be set to "concat,minify,inline" to concatenate, minify and inline the JavaScript files included by web2py.
+- ``response.optimize_css``: it can be set to "concat,minify,inline" to concatenate, minify and inline the CSS files included by web2py.
+- ``response.optimize_js``: it can be set to "concat,minify,inline" to concatenate, minify and inline the JavaScript files included by web2py.
- ``response.view``: the name of the view template that must render the page. This is set by default to:
``
"%s/%s.%s" % (request.controller, request.function, request.extension)
@@ -1125,8 +1125,7 @@ In the "generic.html" view this is done using ``{{=response.toolbar()}}``.
#### Separate sessions
-If you are storing sessions on filesystems and you have lots of them, the file system access may become a bottle-neck. One solution is the following:
-If you are storing sessions on filesystem and you have lots of them, the file system access may become a bottle-neck. One solution is the following:
+If you are storing sessions on the filesystem and you have lots of them, the file system access may become a bottle-neck. One solution is the following:
``
session.connect(request, response, separate=True)
``:code
@@ -1246,7 +1245,7 @@ cache.ram(key, None)
where ``key`` is the key of the cached item.
-It is also possible to define other caching mechanisms such as memcache. Memcache is available via ``gluon.contrib.memcache`` and is discussed in more details in Chapter 14.
+It is also possible to define other caching mechanisms such as memcache. Memcache is available via ``gluon.contrib.memcache`` and is discussed in more detail in Chapter 14.
------
Be careful when caching to remeber that caching is usually at the app-level not at the user level. If you need, for example, to cache user specific content, choose a key that includes the user id.
@@ -1586,7 +1585,7 @@ a = T("hello %(name)s") % dict(name='Tim')
The latter syntax is recommended because it makes translation easier.
The first string is translated according to the requested language file and the ``name`` variable is replaced independently of the language.
-You can concatenating translated strings and normal strings:
+You can concatenate translated strings and normal strings:
``
T("blah ") + name + T(" blah")
``:code
@@ -1641,7 +1640,7 @@ It is possible to disable lazy evaluation via
T.lazy = False
``:code
-In this way, strings are translated immediately by the ``T`` operator based on the currently accepted or forced language.
+In this way, strings are translated inmediately by the ``T`` operator based on the currently accepted or forced language.
It is also possible to disable lazy evaluation for individual strings:
@@ -1721,7 +1720,7 @@ Now the PS is activated for the word "book" and for the number 10.
The result in English will be: "You have 10 books". Notice that "book" has been pluralized into "books".
The PS consists of 3 parts:
-- placeholders ``%%{}`` to mark words in ``T``-messages
+- placeholders ``%%{}`` to mark words in the ``T`` input
- rule to give a decision which word form to use ("rules/plural_rules/*.py")
- dictionary with word plural forms ("app/languages/plural-*.py")
@@ -1730,7 +1729,7 @@ The value of symbols can be a single variable, a list/tuple of variables, or a d
The placeholder ``%%{}`` consists of 3 parts:
``
-%%{[<modifier>]<world>[<parameter>]},
+%%{[<modifier>]<word>[<parameter>]},
``
where:
@@ -2233,7 +2232,7 @@ A manual approach consists of creating subfolders for different versions of stat
This procedure works but it is pedantic since every time you update the css file, you must remember to move it to another folder, change the URL of the file in your layout.html and deploy.
-Static asset management solves the problem by allowing the developer to declare a version for a group of static files and they will be requested again only when the version number changes. The version number of made part of the file url as in the previous example. The difference from the previous approach is that the version number only appears in the URL, not in the file system.
+Static asset management solves the problem by allowing the developer to declare a version for a group of static files and they will be requested again only when the version number changes. The asset version number is made part of the file url as in the previous example. The difference from the previous approach is that the version number only appears in the URL, not in the file system.
If you want to serve "/myapp/static/layout.css" with the cache headers, you just need to include the file with a modified URL that includes a version number:
@@ -2322,7 +2321,7 @@ app/cron/crontab
It follows the syntax defined in ref. ``cron``:cite (with some extensions that are specific to web2py).
------
-Before web2py 2.1.1, cron was enabled by default and could be disabled with the ``-N`` command line option, Since 2.1.1, cron is disabled by default and can be enabled by the ``-Y`` option. This change was motivated by the desire to push users toward using the new scheduler (which is superior to the cron mechanism) and also because cron may impact on performance.
+Before web2py 2.1.1, cron was enabled by default and could be disabled with the ``-N`` command line option. Since 2.1.1, cron is disabled by default and can be enabled by the ``-Y`` option. This change was motivated by the desire to push users toward using the new scheduler (which is superior to the cron mechanism) and also because cron may impact on performance.
------
This means that every application can have a separate cron configuration and that cron config can be changed from within web2py without affecting the host OS itself.
@@ -2342,7 +2341,7 @@ The last two lines in this example use extensions to regular cron syntax to prov
The file "applications/admin/cron/expire_sessions.py" actually exists and ships with the **admin** app. It checks for expired sessions and deletes them. "applications/admin/cron/crontab" runs this task hourly.
-------
-If the task/script is prefixed with an asterisk (``*``) and ends with ``.py``, it will be executed in the web2py environment. This means you will have all the controllers and models at your disposal. If you use two asterisks (``**``), the ``MODEL``s will not be executed. This is the recommended way of calling, as it has less overhead and avoids potential locking problems.
+If the task/script is prefixed with an asterisk (``*``) and ends with ``.py``, it will be executed in the web2py environment. This means you will have all the controllers and models at your disposal. If you use two asterisks (``**``), the models will not be executed. This is the recommended way of calling, as it has less overhead and avoids potential locking problems.
Notice that scripts/functions executed in the web2py environment require a manual ``db.commit()`` at the end of the function or the transaction will be reverted.
@@ -2484,11 +2483,9 @@ Let's see them in order:
------
NB: This is useful if you have different workers instances (e.g. on different machines) and you want to assign tasks to a specific worker.
-NB2: It's possible to assign a worker more groups, and they can be also all the same, as
+NB2: It's possible to assign a worker more groups, and they can be also all the same, as ``['mygroup','mygroup']``. Tasks will be distributed taking into consideration that a worker with group_names ``['mygroup','mygroup']`` is able to process the double of the tasks a worker with group_names ``['mygroup']`` is.
------
-``['mygroup','mygroup']``. Tasks will be distributed taking into consideration that
-a worker with group_names ``['mygroup','mygroup']`` is able to process the double of the tasks
-a worker with group_names ``['mygroup']`` is.
+
- ``heartbeat`` is by default set to 3 seconds. This parameter is the one controlling how often a scheduler will check its status on the ``scheduler_worker`` table and see if there are any **ASSIGNED** tasks to itself to process.
- ``max_empty_runs`` is 0 by default, that means that the worker will continue to process tasks as soon as they are **ASSIGNED**. If you set this to a value of, let's say, 10, a worker will die automatically if it's **ACTIVE** and no tasks are **ASSIGNED** to it for 10 loops. A loop is when a worker searches for tasks, every 3 seconds (or the set ``heartbeat``)
- ``discard_results`` is False by default. If set to True, no scheduler_run records will be created.
@@ -2624,7 +2621,7 @@ A call to ``scheduler.queue_task`` returns the task ``id`` and ``uuid`` of the t
<Row {'errors': {}, 'id': 1, 'uuid': '08e6433a-cf07-4cea-a4cb-01f16ae5f414'}>
``
-If there are errors (usually syntax error os input validation errors),
+If there are errors (usually syntax errors or input validation errors),
you get the result of the validation, and id and uuid will be None
``
@@ -2651,7 +2648,8 @@ In any case, the stdout is captured and also logged into the run record.
Using appadmin, one can check all ``RUNNING`` tasks, the output of ``COMPLETED`` tasks, the error of ``FAILED`` tasks, etc.
-The scheduler also creates one more table called "scheduler_worker", which stores the workers' heartbeat and their status. Possible worker statuses are:
+The scheduler also creates one more table called "scheduler_worker", which stores the workers' heartbeat and their status.
+
##### Managing processes
@@ -2723,8 +2721,8 @@ The scheduler is considered experimental because it needs more extensive testing
A special "word" encountered in the print statements of your functions clear all
the previous output. That word is ``!clear!``.
-This, coupled with the ``sync_output`` parameter, allows to report percentages
-a breeze.
+This, coupled with the ``sync_output`` parameter, allows to report percentages.
+
Here is an example:
@@ -2829,7 +2827,13 @@ There are many ways applications can cooperate:
- Applications can call each other's actions locally using ``exec_environment`` as discussed above.
- Applications can import each other's modules using the syntax:
``
-from applications.appname.modules import mymodule
+from applications.otherapp.modules import mymodule
+``:code
+
+or
+
+``
+import applications.otherapp.modules.othermodule
``:code
- Applications can import any module in the ``PYTHONPATH`` search path, ``sys.path``.
@@ -2842,11 +2846,6 @@ session.connect(request, response, masterapp='appname', db=db)
Here "appname" is the name of the master application, the one that sets the initial session_id in the cookie. ``db`` is a database connection to the database that contains the session table (``web2py_session``). All apps that share sessions must use the same database for session storage.
-One application can load a module from another app using
-
-``
-import applications.otherapp.modules.othermodule
-``:code
### Logging
View
56 sources/29-web2py-english/06.markmin
@@ -115,7 +115,7 @@ A connection with the database is established by creating an instance of the DAL
**Ingres** | ``ingres://username:password@localhost/test``
**Sybase** | ``sybase://username:password@localhost/test``
**Informix** | ``informix://username:password@test``
-**Teradata** | ``teradata://DSN=dsn;UID=user;PWD=pass;DATABASE=name``
+**Teradata** | ``teradata://DSN=dsn;UID=user;PWD=pass;DATABASE=test``
**Cubrid** | ``cubrid://username:password@localhost/test``
**SAPDB** | ``sapdb://username:password@localhost/test``
**IMAP** | ``imap://user:password@server:port``
@@ -142,7 +142,7 @@ Notice that by default web2py uses utf8 character encoding for databases. If you
db = DAL('...', db_codec='latin1')
``:code
-otherwise you'll get UnicodeDecodeErrors tickets.
+otherwise you'll get UnicodeDecodeError tickets.
#### Connection pooling
``connection pooling``:inxx
@@ -178,9 +178,7 @@ in Chapter 13 in the context of scalability.
### Reserved keywords
``reserved Keywords``:inxx
-``check_reserved`` is yet another argument that can be passed to the DAL constructor. It tells it to check table names and column names against reserved SQL keywords in target back-end databases.
-
-This argument is ``check_reserved`` and it defaults to None.
+``check_reserved`` is yet another argument that can be passed to the DAL constructor. It tells it to check table names and column names against reserved SQL keywords in target back-end databases. ``check_reserved`` defaults to None.
This is a list of strings that contain the database back-end adapter names.
@@ -265,7 +263,7 @@ db.define_table('person', Field('name'), redefine=True)
The redefinition may trigger a migration if field content is different.
----------
-Because usually in web2py models are executed before controllers, it is possible that some table are defined even if not needed. It is therefore necessary to speed up the code by making table definitions lazy. This is done by setting the ``DAL(...,lazy_tables=True)`` attributes. Tables will be actually created only when accessed.
+Because usually in web2py models are executed before controllers, it is possible that some table are defined even if not needed. It is therefore necessary to speed up the code by making table definitions lazy. This is done by setting the ``DAL(...,lazy_tables=True)`` attribute. Tables will be actually created only when accessed.
----------
@@ -643,11 +641,7 @@ sequence of values to be substituted in
or, if supported by the DB driver, a dictionary with keys
matching named placeholders in your SQL.
-If ``as_dict`` is set to True,
-and the results cursor returned by the DB driver will be
-converted to a sequence of dictionaries keyed with the db
-field names. Results returned with ``as_dict = True ``are
-the same as those returned when applying **.as_list()** to a normal select.
+If ``as_dict`` is set to True, the results cursor returned by the DB driver will be converted to a sequence of dictionaries keyed with the db field names. Results returned with ``as_dict = True`` are the same as those returned when applying **.as_list()** to a normal select.
``
[{field1: value1, field2: value2}, {field1: value1b, field2: value2b}]
``:code
@@ -1145,7 +1139,7 @@ and the corresponding view:
{{=grid}}
``
-``SQLFORM.grid`` and ``SQLFORM.smartgrid`` should be preferred to ``SQLTABLE`` because they are more powerful although higher level and therefore more constraining. They will be explained in more detail in chapter 8.
+``SQLFORM.grid`` and ``SQLFORM.smartgrid`` should be preferred to ``SQLTABLE`` because they are more powerful although higher level and therefore more constraining. They will be explained in more detail in chapter 7.
#### ``orderby``, ``groupby``, ``limitby``, ``distinct``, ``having``
@@ -1497,7 +1491,7 @@ John
#### ``find``, ``exclude``, ``sort``
``find``:inxx ``exclude``:inxx ``sort``:inxx
-Some times you to perform two selects and one contains a subset of a previous select. In this case it is pointless to access the database again. The ``find``, ``exclude`` and ``sort`` objects allow you to manipulate a Rows objects and generate another one without accessing the database. More specifically:
+Some times you need to perform two selects and one contains a subset of a previous select. In this case it is pointless to access the database again. The ``find``, ``exclude`` and ``sort`` objects allow you to manipulate a Rows objects and generate another one without accessing the database. More specifically:
- ``find`` returns a new set of Rows filtered by a condition and leaves the original unchanged.
- ``exclude`` returns a new set of Rows filtered by a condition and removes them from the original Rows.
- ``sort`` returns a new set of Rows sorted by a condition and leaves the original unchanged.
@@ -1541,7 +1535,7 @@ Max
Sort takes an optional argument ``reverse=True`` with the obvious meaning.
-The ``find`` method as an optional limitby argument with the same syntax and functionality as the Set select ``method``.
+The ``find`` method has an optional limitby argument with the same syntax and functionality as the Set select ``method``.
@@ -1558,7 +1552,7 @@ db.define_table('person',Field('name'),Field('birthplace'))
db.person.update_or_insert(name='John',birthplace='Chicago')
``:code
-The record will be inserted only of there is no other user called John born in Chicago.
+The record will be inserted only if there is no other user called John born in Chicago.
You can specify which values to use as a key to determine if the record exists. For example:
``
@@ -1598,7 +1592,7 @@ works very much the same as
num = db(query).update(field='value')
``:code
-except that it calls the validators for the fields before performing the update. Notice that it only works if query involves a single table. The number of updated records can be found in ``res.updated`` and errors will be ``ret.errors``.
+except that it calls the validators for the fields before performing the update. Notice that it only works if query involves a single table. The number of updated records can be found in ``res.updated`` and errors will be ``ret.errors``.
#### ``smart_query`` (experimental)
@@ -1959,7 +1953,7 @@ Alex 2
Bob 1
``:code
-Notice the count operator (which is built-in) is used as a field. The only issue here is in how to retrieve the information. Each row clearly contains a person and the count, but the count is not a field of a person nor is it a table. So where does it go? It goes into the storage object representing the record with a key equal to the query expression itself. The count method of the Field object has an optional ``distinct`` argument. When set to ``True`` it specifies that only distinct values of the field in question are to be counted.
+Notice the ``count`` operator (which is built-in) is used as a field. The only issue here is in how to retrieve the information. Each row clearly contains a person and the count, but the count is not a field of a person nor is it a table. So where does it go? It goes into the storage object representing the record with a key equal to the query expression itself. The count method of the Field object has an optional ``distinct`` argument. When set to ``True`` it specifies that only distinct values of the field in question are to be counted.
### Many to many
``many-to-many``:inxx
@@ -2197,7 +2191,7 @@ port scan
The date and datetime fields have day, month and year methods. The datetime and time fields have hour, minutes and seconds methods. Here is an example:
``
->>> for row in db(db.log.event_time.year()==2009).select():
+>>> for row in db(db.log.event_time.year()==2013).select():
print row.event
port scan
xss injection
@@ -2206,7 +2200,7 @@ unauthorized login
#### ``belongs``
-The SQL IN operator is realized via the belongs method which returns true when the field value belongs to the specified set (list of tuples):
+The SQL IN operator is realized via the belongs method which returns true when the field value belongs to the specified set (list or tuples):
``belongs``:inxx
``
@@ -2231,8 +2225,8 @@ unauthorized login
In those cases where a nested select is required and the look-up field is a reference we can also use a query as argument. For example:
``
-db.define_table('person',Field('name'))
-db.define_table('thing,Field('name'), Field('owner_id','reference thing'))
+db.define_table('person', Field('name'))
+db.define_table('thing', Field('name'), Field('owner_id', 'reference thing'))
db(db.thing.owner_id.belongs(db.person.name=='Jonathan')).select()
``:code
@@ -2459,13 +2453,13 @@ Change the above model into:
``
db.define_table('person',
Field('uuid', length=64, default=lambda:str(uuid.uuid4())),
- Field('modified_on', 'datetime', default=now),
+ Field('modified_on', 'datetime', default=request.now),
Field('name'),
format='%(name)s')
db.define_table('thing',
Field('uuid', length=64, default=lambda:str(uuid.uuid4())),
- Field('modified_on', 'datetime', default=now),
+ Field('modified_on', 'datetime', default=request.now),
Field('owner_id', length=64),
Field('name'),
format='%(name)s')
@@ -2595,7 +2589,7 @@ Here is some example usage:
Which would render something similar to
``
-"hello"|35|"this is the text description"|"2009-03-03"
+"hello"|35|"this is the text description"|"2013-03-03"
``:code
For more information consult the official Python documentation ``quoteall``:cite
@@ -2815,7 +2809,7 @@ The return values of these callback should be ``None`` or ``False``. If any of t
``update_naive``:inxx.
-Some times a callback may need to perform an update in the same of a different table and one wants to avoid callbacks calling themselves recursively.
+Some times a callback may need to perform an update in the same or a different table and one wants to avoid callbacks calling themselves recursively.
For this purpose there the Set objects have an ``update_naive`` method that works like ``update`` but ignores before and after callbacks.
@@ -2864,7 +2858,7 @@ db.stored_item._enable_record_versioning(
The ``archive_db=db`` tells web2py to store the archive table in the same database as the ``stored_item`` table. The ``archive_name`` sets the name for the archive table. The archive table has the same fields as the original table ``stored_item`` except that unique fields are no longer unique (because it needs to store multiple versions) and has an extra field which name is specified by ``current_record`` and which is a reference to the current record in the ``stored_item`` table.
-When records are deleted, they are not really deleted. A deleted record is copied in the ``stored_item_archive`` table (like when it is modified) and the ``is_active`` field is set to False. By enabling record versioning web2py sets a ``custom_filter`` on this table that hides all fields in table ``stored_item`` where the ``is_active`` field is set to False. The ``is_active`` parameter in the ``_enable_record_versioning`` method allows to specify the name of the field used by the ``custom_filter`` to determine if the field was deleted or not.
+When records are deleted, they are not really deleted. A deleted record is copied in the ``stored_item_archive`` table (like when it is modified) and the ``is_active`` field is set to False. By enabling record versioning web2py sets a ``custom_filter`` on this table that hides all records in table ``stored_item`` where the ``is_active`` field is set to False. The ``is_active`` parameter in the ``_enable_record_versioning`` method allows to specify the name of the field used by the ``custom_filter`` to determine if the field was deleted or not.
``custom_filter``s are ignored by the appadmin interface.
@@ -2946,7 +2940,7 @@ db(query, ignore_common_filters=True).select(...)
``SQLCustomType``:inxx
Aside for using ``filter_in`` and ``filter_out``, it is possible to define new/custom field types.
-For example we consider here the example if a field that contains binary data in compressed form:
+For example we consider here a field that contains binary data in compressed form:
``
from gluon.dal import SQLCustomType
@@ -3191,6 +3185,7 @@ CubridAdapter extends MySQLAdapter (experimental)
TeradataAdapter extends DB2Adapter (experimental)
SAPDBAdapter extends BaseAdapter (experimental)
CouchDBAdapter extends NoSQLAdapter (experimental)
+IMAPAdapter extends NoSQLAdapter (experimental)
MongoDBAdapter extends NoSQLAdapter (experimental)
``
@@ -3270,6 +3265,7 @@ ADAPTERS = {
'google:sql': GoogleSQLAdapter,
'couchdb': CouchDBAdapter,
'mongodb': MongoDBAdapter,
+ 'imap': IMAPAdapter
}
``:code
@@ -3292,18 +3288,18 @@ db =DAL(..., driver_args={}, adapter_args={})
#### Gotchas
-**SQLite** does not support dropping and altering columns. That means that web2py migrations will work up to a point. If you delete a field from a table, the column will remain in the database but be invisible to web2py. If you decide to reinstate the column, web2py will try re-create it and fail. In this case you must set ``fake_migrate=True`` so that metadata is rebuilt without attempting to add the column again. Also, for the same reason, **SQLite** is not aware of any change of column type. If you insert a number in a string field, it will be stored as string. If you later change the model and replace the type "string" with type "integer", SQLite will continue to keep the number as a string and this may cause problem when you try to extract the data.
+**SQLite** does not support dropping and altering columns. That means that web2py migrations will work up to a point. If you delete a field from a table, the column will remain in the database but will be invisible to web2py. If you decide to reinstate the column, web2py will try re-create it and fail. In this case you must set ``fake_migrate=True`` so that metadata is rebuilt without attempting to add the column again. Also, for the same reason, **SQLite** is not aware of any change of column type. If you insert a number in a string field, it will be stored as string. If you later change the model and replace the type "string" with type "integer", SQLite will continue to keep the number as a string and this may cause problem when you try to extract the data.
**MySQL** does not support multiple ALTER TABLE within a single transaction. This means that any migration process is broken into multiple commits. If something happens that causes a failure it is possible to break a migration (the web2py metadata are no longer in sync with the actual table structure in the database). This is unfortunate but it can be prevented (migrate one table at the time) or it can be fixed a posteriori (revert the web2py model to what corresponds to the table structure in database, set ``fake_migrate=True`` and after the metadata has been rebuilt, set ``fake_migrate=False`` and migrate the table again).
-**Google SQL** has the same problems as MySQL and more. In particular table metadata itself must be stored in the database in a table that is not migrated by web2py. This is because Google App Engine has a read-only file system. Web2py migrations in Google:SQL combined with the MySQL issue described above can result in metadata corruption. Again, this can be prevented (my migrating the table at once and then setting migrate=False so that the metadata table is not accessed any more) or it can fixed a posteriori (my accessing the database using the Google dashboard and deleting any corrupted entry from the table called ``web2py_filesystem``.
+**Google SQL** has the same problems as MySQL and more. In particular table metadata itself must be stored in the database in a table that is not migrated by web2py. This is because Google App Engine has a read-only file system. Web2py migrations in Google:SQL combined with the MySQL issue described above can result in metadata corruption. Again, this can be prevented (by migrating the table at once and then setting migrate=False so that the metadata table is not accessed any more) or it can fixed a posteriori (by accessing the database using the Google dashboard and deleting any corrupted entry from the table called ``web2py_filesystem``.
``limitby``:inxx
**MSSQL** does not support the SQL OFFSET keyword. Therefore the database cannot do pagination. When doing a ``limitby=(a,b)`` web2py will fetch the first ``b`` rows and discard the first ``a``. This may result in a considerable overhead when compared with other database engines.
**Oracle** also does not support pagination. It does not support neither the OFFSET nor the LIMIT keywords. Web2py achieves pagination by translating a ``db(...).select(limitby=(a,b))`` into a complex three-way nested select (as suggested by official Oracle documentation). This works for simple select but may break for complex selects involving aliased fields and or joins.
-**MSSQL** has problems with circular references in tables that have ONDELETE CASCADE. This is an MSSSQL bug and you work around it by setting the ondelete attribute for all reference fields to "NO ACTION". You can also do it once and for all before you define tables:
+**MSSQL** has problems with circular references in tables that have ONDELETE CASCADE. This is an MSSQL bug and you work around it by setting the ondelete attribute for all reference fields to "NO ACTION". You can also do it once and for all before you define tables:
``
db = DAL('mssql://....')
View
6 sources/29-web2py-english/07.markmin
@@ -150,7 +150,7 @@ The process function takes some extra argument that ``accepts`` does not take:
- ``onsuccess``: if equal to 'flash' (default) and the form is accepted it will flash the above `message_onsuccess``
- ``message_onfailure``
- ``onfailure``: if equal to 'flash' (default) and the form fails validation, it will flash the above `message_onfailure``
-- ``next`` the user to redirect after the form is accepted.
+- ``next`` indicates where to redirect the user after the form is accepted.
``onsuccess`` and ``onfailure`` can be functions like ``lambda form: do_something(form)``.
``
@@ -431,7 +431,7 @@ SQLFORM(table, record = None,
``:code
- The optional second argument turns the INSERT form into an UPDATE form for the specified record (see next subsection). ``showid``:inxx ``delete_label``:inxx ``id_label``:inxx ``submit_button``:inxx
-- If ``deletable`` is set to ``True``, the UPDATE form displays a "Check to delete" checkbox. The value of the label if this field is set via the ``delete_label`` argument.
+- If ``deletable`` is set to ``True``, the UPDATE form displays a "Check to delete" checkbox. The value of the label for this field is set via the ``delete_label`` argument.
- ``submit_button`` sets the value of the submit button.
- ``id_label`` sets the label of the record "id"
- The "id" of the record is not shown if ``showid`` is set to ``False``.
@@ -2319,7 +2319,7 @@ Because of the way grid works one can only have one grid per controller function
To make the default search grid work in more than one LOADed grid, please use a different ``formname`` for each one.
-----
-Because the function that contains the grid may itself manipulate the command line arguments, the grid needs to know which args should be handled by the grid and which not. For example here is an example of code that allows one to manage any table:
+Because the function that contains the grid may itself manipulate the command line arguments, the grid needs to know which args should be handled by the grid and which not. Here is an example of code that allows one to manage any table:
``
@auth.requires_login()
View
2  sources/29-web2py-english/08.markmin
@@ -322,7 +322,7 @@ Here's a list of IMAP commands you could use in the controller. For the examples
To count today's unseen messages smaller than 6000 octets from the inbox mailbox do
``
q = imapdb.INBOX.seen == False
-q &= imapdb.INBOX.created == datetime.date.today()
+q &= imapdb.INBOX.created == request.now.date()
q &= imapdb.INBOX.size < 6000
unread = imapdb(q).count()
``:code
View
2  sources/29-web2py-english/09.markmin
@@ -1404,7 +1404,7 @@ auth.settings.cas_actions['validate']='validate'
auth.settings.cas_actions['logout']='logout'
``
-If you want to connect to a web2py CAS provider from a different domain, you must enable them by attending to the list of allowed domain:
+If you want to connect to a web2py CAS provider from a different domain, you must enable them by appending to the list of allowed domains:
``
## in provider app
View
4 sources/29-web2py-english/10.markmin
@@ -506,7 +506,7 @@ Use "http://127.0.0.1:8000/app/default/call/jsonrpc2" for jsonrpc2.
#### JSONRPC and Pyjamas
``JSONRPC``:inxx ``Pyjamas``:inxx
-JSONRPC is very similar to XMLRPC, but uses the JSON-based protocol instead of XML to encode the data. As an example of application here, we discuss its usage with Pyjamas. Pyjamas is a Python port of the Google Web Toolkit (originally written in Java). Pyjamas allows writing a client application in Python. Pyjamas translates this code into JavaScript. web2py serves the JavaScript and communicates with it via AJAX requests originating from the client and triggered by user actions.
+As an example of application here, we discuss the usage of JSON Remote Procedure Calls with Pyjamas. Pyjamas is a Python port of the Google Web Toolkit (originally written in Java). Pyjamas allows writing a client application in Python. Pyjamas translates this code into JavaScript. web2py serves the JavaScript and communicates with it via AJAX requests originating from the client and triggered by user actions.
Here we describe how to make Pyjamas work with web2py. It does not require any additional libraries other than web2py and Pyjamas.
@@ -812,7 +812,7 @@ web2py includes gluon.contrib.simplejson, developed by Bob Ippolito. This module
SimpleJSON consists of two functions:
- ``gluon.contrib.simplesjson.dumps(a)`` encodes a Python object ``a`` into JSON.
-- ``gluon.contrib.simplejson.loads(b)`` decodes a JavaScript object ``b`` into a Python object.
+- ``gluon.contrib.simplejson.loads(b)`` decodes the JSON data in ``b`` into a Python object.
Object types that can be serialized include primitive types, lists, and dictionaries. Compound objects can be serialized with the exception of user defined classes.
View
4 sources/29-web2py-english/13.markmin
@@ -474,7 +474,7 @@ sudo service web2py start
#### Nginx
-Nginx is a free, open-source, that has rapidly been gaining popularity for its amazing perfomance.
+Nginx is a free, open-source web server that has rapidly been gaining popularity for its amazing perfomance.
Unlike traditional servers, Nginx does not use threads. Instead it uses an ansynchronous/event-driven architecture to handle concurrency. This architecture results in a small and predictable memory usage, even under heavy load.
@@ -1446,7 +1446,7 @@ It is also possible to connect to different databases depending on the requested
``
if request.function in read_only_actions:
db = DAL(sample(['mysql://...1','mysql://...2','mysql://...3'], 3))
-if request.action in read_only_actions:
+elif request.action in read_only_actions:
db = DAL(shuffle(['mysql://...1','mysql://...2','mysql://...3']))
else:
db = DAL(sample(['mysql://...3','mysql://...4','mysql://...5'], 3))
View
20 sources/29-web2py-english/14.markmin
@@ -84,7 +84,7 @@ def myfolder():
which you can render in a view with ``{{=files}}``. It will create an interface to view the files and folders, and navigate the tree structure. Images will have a preview.
-The path prefix "/path/to/myfolder" will be hidden to the visitors. For example a file called "/path/to/myfolder/a/b.txt" and replaced with "base/a/b.txt". The "base" prefix can be specified using the ``basename`` argument of the Expose function. Using the argument ``extensions`` can specify a list of file extensions to be listed, other files will be hidden. For example:
+The path prefix "/path/to/myfolder" will be hidden to the visitors. For example a file called "/path/to/myfolder/a/b.txt" will be replaced with "base/a/b.txt". The "base" prefix can be specified using the ``basename`` argument of the Expose function. Using the argument ``extensions`` can specify a list of file extensions to be listed, other files will be hidden. For example:
``
def myfolder():
@@ -112,13 +112,13 @@ client = WebClient('http://127.0.0.1:8000/welcome/default/',
client.get('index')
# register
-data = dict(first_name = 'Homer',
- last_name = 'Simpson',
- email = 'homer@web2py.com',
- password = 'test',
- password_two = 'test',
- _formname = 'register')
-client.post('user/register',data = data)
+data = dict(first_name='Homer',
+ last_name='Simpson',
+ email='homer@web2py.com',
+ password='test',
+ password_two='test',
+ _formname='register')
+client.post('user/register', data=data)
# logout
client.get('user/logout')
@@ -126,8 +126,8 @@ client.get('user/logout')
# login again
data = dict(email='homer@web2py.com',
password='test',
- _formname = 'login')
-client.post('user/login',data = data)
+ _formname='login')
+client.post('user/login', data=data)
# check registration and login were successful
client.get('index')
Please sign in to comment.
Something went wrong with that request. Please try again.