tools 模块

此文件是Web2py Web框架的一部分
版权所有:Massimo di Pierro<mdipierro@cs.depaul.edu>

授权、邮件、插件管理器和各种实用程序

class gluon.tools.Auth(environment=None, db=None, mailer=True, hmac_key=None, controller='default', function='user', cas_provider=None, signature=True, secure=False, csrf_prevention=True, propagate_extension=None, url_index=None, jwt=None, host_names=None)[源代码]

基类:gluon.authapi.AuthAPI

accessible_query(name, table, user_id=None)[源代码]

返回一个查询,其中包含用户u id或当前登录用户的所有可访问记录。此方法在GAE上不起作用,因为使用了join和in

例子

用作:

db(auth.accessible_query('read', db.mytable)).select(db.mytable.ALL)
allows_jwt(otherwise=None)[源代码]
static archive(form, archive_table=None, current_record='current_record', archive_current=False, fields=None)[源代码]

如果您有一个需要完整修订历史记录的表(db.mytable),可以执行以下操作:

form = crud.update(db.mytable, myrecord, onaccept=auth.archive)

或:

form = SQLFORM(db.mytable, myrecord).process(onaccept=auth.archive)

crud.archive将定义一个新表“mytable_archive”,并在新创建的表中存储当前记录的副本(如果archive_current=true)或以前记录的副本(如果archive_current=false),包括对当前记录的引用。

字段允许指定需要存档的额外字段。

如果要访问此类表,需要在模型中自己定义它::

db.define_table('mytable_archive',
                Field('current_record', db.mytable),
                db.mytable)

注意,这样的表包括db.mytable的所有字段加上一个:current_记录。crud.archive不会给存储的记录加时间戳,除非原始表具有如下字段:

db.define_table(...,
    Field('saved_on', 'datetime',
          default=request.now, update=request.now, writable=False),
    Field('saved_by', auth.user,
          default=auth.user_id, update=auth.user_id, writable=False),

这些字段没有什么特别之处,因为它们是在记录存档之前填写的。

如果要更改存档表名称和引用字段的名称,可以这样做,例如:

db.define_table('myhistory',
    Field('parent_record', db.mytable), db.mytable)

并将其用作:

form = crud.update(db.mytable, myrecord,
                   onaccept=lambda form:crud.archive(form,
                                                     archive_table=db.myhistory,
                                                     current_record='parent_record'))
basic(basic_auth_realm=False)[源代码]

执行基本登录。

参数

basic_auth_realm -- 可选的基本HTTP身份验证领域。可以采用str、unicode、function、callable或boolean。

读取current.request.env.http_授权并返回basic_allowed、basic_accepted、user。

如果定义了基本认证领域是可调用的,则返回值用于设置基本认证领域,如果是字符串,则返回内容。否则,基本身份验证领域设置为应用程序名称。如果基本的_auth_领域为none或false(默认值),则行为是跳过发送任何挑战。

bulk_register(max_emails=100)[源代码]

创建一个表单,供其他用户向其他用户发送邀请以加入

cas_login(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>, version=2)[源代码]
cas_validate(version=2, proxy=False)[源代码]
change_password(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回允许用户更改密码的表单

confirm_registration(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回确认用户注册的表单

default_messages = {'access_denied': 'Insufficient privileges', 'add_group_log': 'Group %(group_id)s created', 'add_membership_log': None, 'add_permission_log': None, 'bulk_invite_body': 'You have been invited to join %(site)s, click %(link)s to complete the process', 'bulk_invite_subject': 'Invitation to join %(site)s', 'change_password_log': 'User %(id)s Password changed', 'del_group_log': 'Group %(group_id)s deleted', 'del_membership_log': None, 'del_permission_log': None, 'delete_label': 'Check to delete', 'email_sent': 'Email sent', 'email_taken': 'This email already has an account', 'email_verified': 'Email verified', 'function_disabled': 'Function disabled', 'group_description': 'Group uniquely assigned to user %(id)s', 'has_membership_log': None, 'has_permission_log': None, 'impersonate_log': 'User %(id)s is impersonating %(other_id)s', 'invalid_email': 'Invalid email', 'invalid_key': 'Invalid key', 'invalid_login': 'Invalid login', 'invalid_password': 'Invalid password', 'invalid_reset_password': 'Invalid reset password', 'invalid_two_factor_code': 'Incorrect code. {0} more attempt(s) remaining.', 'invalid_user': 'Invalid user', 'invalid_username': 'Invalid username', 'is_empty': 'Cannot be empty', 'key_verified': 'Key verified', 'label_client_ip': 'Client IP', 'label_description': 'Description', 'label_email': 'E-mail', 'label_first_name': 'First name', 'label_group_id': 'Group ID', 'label_last_name': 'Last name', 'label_name': 'Name', 'label_origin': 'Origin', 'label_password': 'Password', 'label_record_id': 'Record ID', 'label_registration_id': 'Registration identifier', 'label_registration_key': 'Registration key', 'label_remember_me': 'Remember me (for 30 days)', 'label_reset_password_key': 'Reset Password key', 'label_role': 'Role', 'label_table_name': 'Object or table name', 'label_time_stamp': 'Timestamp', 'label_two_factor': 'Authentication code', 'label_user_id': 'User ID', 'label_username': 'Username', 'logged_in': 'Logged in', 'logged_out': 'Logged out', 'login_button': 'Log In', 'login_disabled': 'Login disabled by administrator', 'login_failed_log': None, 'login_log': 'User %(id)s Logged-in', 'logout_log': 'User %(id)s Logged-out', 'mismatched_password': "Password fields don't match", 'new_password': 'New password', 'new_password_sent': 'A new password was emailed to you', 'old_password': 'Old password', 'password_change_button': 'Change password', 'password_changed': 'Password changed', 'password_reset_button': 'Request reset password', 'profile_log': 'User %(id)s Profile updated', 'profile_save_button': 'Apply changes', 'profile_updated': 'Profile updated', 'register_button': 'Sign Up', 'register_log': 'User %(id)s Registered', 'registration_pending': 'Registration is pending approval', 'registration_successful': 'Registration successful', 'registration_verifying': 'Registration needs verification', 'reset_password': 'Click on the link %(link)s to reset your password', 'reset_password_log': 'User %(id)s Password reset', 'reset_password_subject': 'Password reset', 'retrieve_password': 'Your password is: %(password)s', 'retrieve_password_log': 'User %(id)s Password retrieved', 'retrieve_password_subject': 'Password retrieve', 'retrieve_two_factor_code': 'Your temporary login code is {0}', 'retrieve_two_factor_code_subject': 'Two-step Login Authentication Code', 'retrieve_username': 'Your username is: %(username)s', 'retrieve_username_log': 'User %(id)s Username retrieved', 'retrieve_username_subject': 'Username retrieve', 'submit_button': 'Submit', 'two_factor_comment': 'This code was emailed to you and is required for login.', 'unable_send_email': 'Unable to send email', 'username_sent': 'Your username was emailed to you', 'username_taken': 'Username already taken', 'verify_email': 'Welcome %(username)s! Click on the link %(link)s to verify your email', 'verify_email_log': 'User %(id)s Verification email sent', 'verify_email_subject': 'Email verification', 'verify_log': 'User %(id)s verified registration key', 'verify_password': 'Verify Password', 'verify_password_comment': 'please input your password again'}

用于身份验证、授权和基于角色的访问控制的类。

包括:

  • 注册和简介

  • 登录和注销

  • 用户名和密码检索

  • 事件日志

  • 角色创建和分配

  • 用户定义的基于组/角色的权限

参数
  • environment -- 是否有遗留但未使用的(糟糕的)

  • db -- 必须是创建用于身份验证的表的数据库

  • mailer -- Mail(...) 或无(无邮寄者)或真实(制作邮寄者)

  • hmac_key -- 可以是hmac_key或hmac_key=auth.get_或_create_key()。

  • controller -- (用户操作在哪里?)

  • cas_provider -- (将身份验证委托给URL,cas2)

身份验证示例:

from gluon.contrib.utils import *
mail=Mail()
mail.settings.server='smtp.gmail.com:587'
mail.settings.sender='you@somewhere.com'
mail.settings.login='username:password'
auth=Auth(db)
auth.settings.mailer=mail
# auth.settings....=...
auth.define_tables()
def authentication():
    return dict(form=auth())

暴露:

  • http://.../{application}/{controller}/authentication/login

  • http://.../{application}/{controller}/authentication/logout

  • http://.../{application}/{controller}/authentication/register

  • http://.../{application}/{controller}/authentication/verify_email

  • http://.../{application}/{controller}/authentication/retrieve_username

  • http://.../{application}/{controller}/authentication/retrieve_password

  • http://.../{application}/{controller}/authentication/reset_password

  • http://.../{application}/{controller}/authentication/profile

  • http://.../{application}/{controller}/authentication/change_password

注册时,将创建一个role=new_user.id的组,并向用户授予该组的成员资格。

您可以使用以下项创建组:

group_id=auth.add_group('Manager', 'can access the manage action')
auth.add_permission(group_id, 'access to manage')

这里的“访问管理”只是一个用户定义的字符串。您可以授予用户访问权限::

auth.add_membership(group_id, user_id)

如果省略了用户ID,则假定已登录的用户

然后你可以装饰任何动作:

@auth.requires_permission('access to manage')
def manage():
    return dict()

您可以将权限限制到特定表::

auth.add_permission(group_id, 'edit', db.sometable)
@auth.requires_permission('edit', db.sometable)

或特定记录:

auth.add_permission(group_id, 'edit', db.sometable, 45)
@auth.requires_permission('edit', db.sometable, 45)

如果未授予授权,则调用:

auth.settings.on_failed_authorization

其他选项:

auth.settings.mailer=None
auth.settings.expiration=3600 # seconds

...

### these are messages that can be customized
...
default_settings = {'allow_basic_login': False, 'allow_basic_login_only': False, 'allow_delete_accounts': False, 'alternate_requires_registration': False, 'auth_manager_role': None, 'auth_two_factor_enabled': False, 'auth_two_factor_tries_left': 3, 'bulk_register_enabled': False, 'captcha': None, 'cas_maps': None, 'client_side': True, 'create_user_groups': 'user_%(id)s', 'email_case_sensitive': False, 'everybody_group_id': None, 'expiration': 3600, 'formstyle': None, 'hideerror': False, 'keep_session_onlogin': True, 'keep_session_onlogout': False, 'label_separator': None, 'logging_enabled': True, 'login_after_password_change': True, 'login_after_registration': False, 'login_captcha': None, 'login_email_validate': True, 'login_specify_error': False, 'login_userfield': None, 'logout_onlogout': None, 'long_expiration': 2592000, 'mailer': None, 'manager_actions': {}, 'multi_login': False, 'on_failed_authentication': <function Auth.<lambda>>, 'ondelete': 'CASCADE', 'password_field': 'password', 'password_min_length': 4, 'pre_registration_div': None, 'prevent_open_redirect_attacks': True, 'prevent_password_reset_attacks': True, 'profile_fields': None, 'register_captcha': None, 'register_fields': None, 'register_verify_password': True, 'registration_requires_approval': False, 'registration_requires_verification': False, 'remember_me_form': True, 'renew_session_onlogin': True, 'renew_session_onlogout': True, 'reset_password_requires_verification': False, 'retrieve_password_captcha': None, 'retrieve_username_captcha': None, 'showid': False, 'table_cas': None, 'table_cas_name': 'auth_cas', 'table_event': None, 'table_event_name': 'auth_event', 'table_group': None, 'table_group_name': 'auth_group', 'table_membership': None, 'table_membership_name': 'auth_membership', 'table_permission': None, 'table_permission_name': 'auth_permission', 'table_token_name': 'auth_token', 'table_user': None, 'table_user_name': 'auth_user', 'two_factor_authentication_group': None, 'update_fields': ['email'], 'use_username': False, 'username_case_sensitive': True, 'wiki': {}}
define_tables(username=None, signature=None, enable_tokens=False, migrate=None, fake_migrate=None)[源代码]

除非手动定义表,否则将调用

实例

用作:

# defines all needed tables and table files
# 'myprefix_auth_user.table', ...
auth.define_tables(migrate='myprefix_')

# defines all needed tables without migration/table files
auth.define_tables(migrate=False)
email_registration(subject, body, user)[源代码]

向用户发送电子邮件邀请,通知他们已在应用程序中注册。

email_reset_password(user)[源代码]
enable_record_versioning(tables, archive_db=None, archive_names='%(tablename)s_archive', current_record='current_record', current_record_label=None)[源代码]

用于启用完整记录版本控制(包括身份验证表)::

auth = Auth(db)
auth.define_tables(signature=True)
# define our own tables
db.define_table('mything',Field('name'),auth.signature)
auth.enable_record_versioning(tables=db)

表可以是DB(所有表)或表列表。只有字段上具有modified_by和modified_的表(由auth.signature创建)才具有版本控制。旧的记录版本将在自动定义的“神话存档”表中。

启用“启用记录版本控制”时,记录不会被删除,但标记为“活动=假”。

启用记录版本控制为每个筛选出is_active=false记录的表启用一个通用的筛选

注解

如果使用auth.enable_record_版本控制,请不要使用auth.archive,否则将导致重复。auth.archive明确执行启用记录版本控制自动执行的操作。

static get_or_create_key(filename=None, alg='sha512')[源代码]
get_or_create_user(keys, update_fields=['email'], login=True, get=True)[源代码]

用于备用登录方法:如果用户已经存在,则更新密码。如果用户还不存在,则创建它们。

get_vars_next()[源代码]
groups()[源代码]

显示登录用户的组及其角色

here()[源代码]
impersonate(user_id=<function <lambda>>)[源代码]

用这个发帖子 http://..../impersonate request.post_vars.user_id=<id>

将request.post_vars.user_id设置为0以还原原始用户。

需要模拟程序已登录,并且::

has_permission('impersonate', 'auth_user', user_id)
is_impersonating()[源代码]
jwt()[源代码]

要使用JWT身份验证,请执行以下操作:1)实例化身份验证:

auth = Auth(db, jwt = {'secret_key':'secret'})

其中“秘密”是您自己的秘密字符串。

  1. 修饰需要登录但应接受JWT令牌凭据的函数:

    @auth.allows_jwt()
    @auth.requires_login()
    def myapi(): return 'hello %s' % auth.user.email
    

注意:允许但不要求JWT。如果用户已登录,则可以访问myapi。

  1. 用它!

现在,API用户可以使用

(返回具有token属性的JSON对象)API用户可以使用

在调用http://…/myapi时,它们可以通过插入头进行身份验证。

授权:持有人<JWT代币>

下面auth()的jwt参数中的任何其他属性:

auth = Auth(db, jwt = {...})

传递给类authjwt的构造函数。在那里查找文档。

login(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回登录表单

login_bare(username, password)[源代码]

按用户名(或电子邮件)和密码指定登录用户

logout(next=<function <lambda>>, onlogout=<function <lambda>>, log=<function <lambda>>)[源代码]

注销并重定向到登录

logout_bare()[源代码]
manage_tokens()[源代码]
navbar(prefix='Welcome', action=None, separators=(' [ ', ' | ', ' ] '), user_identifier=<function <lambda>>, referrer_actions=<function <lambda>>, mode='default')[源代码]

支持更多模板的导航栏,它使用旧导航栏中的一些代码。

参数

mode -- 请参阅选项以获取

not_authorized()[源代码]

您可以更改此页面的视图,使其看起来像您喜欢的那样

static prevent_open_redirect(next, host)[源代码]
profile(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回允许用户更改其配置文件的表单

random_password()[源代码]
register(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回注册表单

register_bare(**fields)[源代码]

按照用户名(或电子邮件)和原始密码指定的方式注册用户。

request_reset_password(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回一个表单以重置用户密码

requires(condition, requires_login=True, otherwise=None)[源代码]

如果未登录,则阻止访问操作的装饰器

requires_login(otherwise=None)[源代码]

如果未登录,则阻止访问操作的装饰器

requires_login_or_token(otherwise=None)[源代码]
requires_membership(role=None, group_id=None, otherwise=None)[源代码]

如果未登录或登录的用户不是组标识的成员,则阻止访问操作的修饰器。如果提供角色而不是组标识,则计算组标识。

requires_permission(name, table_name='', record_id=0, otherwise=None)[源代码]

如果未登录或登录的用户不是任何“name”访问“table_name”、“record_id”的组(角色)的成员,则阻止访问操作的修饰器。

requires_signature(otherwise=None, hash_vars=True, hash_extension=True)[源代码]

如果未登录或登录的用户不是组标识的成员,则阻止访问操作的修饰器。如果提供角色而不是组标识,则计算组标识。

reset_password(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回一个表单以重置用户密码

reset_password_deprecated(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回用于重置用户密码的表单(已弃用)

retrieve_password(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]
retrieve_username(next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

返回用于检索用户用户名的表单(仅当存在用户名字段时)

run_login_onaccept()[源代码]
select_host(host, host_names=None)[源代码]

检查主机是否有效,即在全局主机名列表中,如果主机丢失,是否从主机名中选择第一个条目阅读更多信息:https://github.com/web2py/web2py/issues/1196

table_cas()[源代码]
table_token()[源代码]
url(f=None, args=None, vars=None, scheme=False)[源代码]
verify_email(next=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>)[源代码]

用于验证注册电子邮件的操作

when_is_logged_in_bypass_next_in_url(next, session)[源代码]

当加载的页面包含“用户/登录”时,如果有人希望避免请求用户凭据,则应使用此功能。_ URL中的next=next_component“是刷新的,但用户已经过身份验证。

wiki(slug=None, env=None, render='markmin', manage_permissions=False, force_prefix='', restrict_search=False, resolve=True, extra=None, menu_groups=None, templates=None, migrate=True, controller=None, function=None, force_render=False, groups=None)[源代码]
wikimenu()[源代码]

在menu.py中用于应用程序范围的wiki菜单

class gluon.tools.Crud(environment, db=None, controller='default')[源代码]

基类:object

static archive(form, archive_table=None, current_record='current_record')[源代码]
create(table, next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, log=<function <lambda>>, message=<function <lambda>>, formname=<function <lambda>>, **attributes)[源代码]
default_messages = {'create_log': 'Record %(id)s created', 'delete_label': 'Check to delete', 'delete_log': 'Record %(id)s deleted', 'read_log': 'Record %(id)s read', 'record_created': 'Record Created', 'record_deleted': 'Record Deleted', 'record_updated': 'Record Updated', 'submit_button': 'Submit', 'update_log': 'Record %(id)s updated'}
delete(table, record_id, next=<function <lambda>>, message=<function <lambda>>)[源代码]
get_format(field)[源代码]
get_query(field, op, value, refsearch=False)[源代码]
has_permission(name, table, record=0)[源代码]
log_event(message, vars)[源代码]
read(table, record)[源代码]
rows(table, query=None, fields=None, orderby=None, limitby=None)[源代码]
search(*tables, **args)[源代码]

为表创建搜索表单及其结果。rubric::示例

用作:

form, results = crud.search(db.test,
   queries = ['equals', 'not equal', 'contains'],
   query_labels={'equals':'Equals',
                 'not equal':'Not equal'},
   fields = ['id','children'],
   field_labels = {
       'id':'ID','children':'Children'},
   zero='Please choose',
   query = (db.test.id > 0)&(db.test.id != 3) )
select(table, query=None, fields=None, orderby=None, limitby=None, headers=None, **attr)[源代码]
tables()[源代码]
update(table, record, next=<function <lambda>>, onvalidation=<function <lambda>>, onaccept=<function <lambda>>, ondelete=<function <lambda>>, log=<function <lambda>>, message=<function <lambda>>, deletable=<function <lambda>>, formname=<function <lambda>>, **attributes)[源代码]
url(f=None, args=None, vars=None)[源代码]

这应该指向暴露下载和CRUD的控制器

class gluon.tools.Mail(server=None, sender=None, login=None, tls=True)[源代码]

基类:object

用于配置和发送具有可选文本/HTML正文、多个附件和加密支持的电子邮件的类

与smtp和google app引擎配合使用。

参数
  • server -- 地址:端口符号中的SMTP服务器地址

  • sender -- 发件人电子邮件地址

  • login -- 登录中的发送方登录名和密码:密码表示法,如果不需要身份验证,则不需要。

  • tls -- 启用/禁用加密(默认为true)

在谷歌应用程序引擎中使用:

server='gae'

为了向后兼容,所有字段都是可选的,并且默认为无,但是,为了能够发送电子邮件,必须至少指定服务器和发件人。它们在以下字段下可用:

mail.settings.server
mail.settings.sender
mail.settings.login
mail.settings.timeout = 60 # seconds (default)

当服务器为“日志记录”时,将记录但不发送电子邮件(调试模式)

您可以选择使用PGP加密或X509::

mail.settings.cipher_type = None
mail.settings.gpg_home = None
mail.settings.sign = True
mail.settings.sign_passphrase = None
mail.settings.encrypt = True
mail.settings.x509_sign_keyfile = None
mail.settings.x509_sign_certfile = None
mail.settings.x509_sign_chainfile = None
mail.settings.x509_nocerts = False
mail.settings.x509_crypt_certfiles = None

cipher_type       : None
                    gpg - need a python-pyme package and gpgme lib
                    x509 - smime
gpg_home          : you can set a GNUPGHOME environment variable
                    to specify home of gnupg
sign              : sign the message (True or False)
sign_passphrase   : passphrase for key signing
encrypt           : encrypt the message (True or False). It defaults
                    to True
                 ... x509 only ...
x509_sign_keyfile : the signers private key filename or
                    string containing the key. (PEM format)
x509_sign_certfile: the signers certificate filename or
                    string containing the cert. (PEM format)
x509_sign_chainfile: sets the optional all-in-one file where you
                     can assemble the certificates of Certification
                     Authorities (CA) which form the certificate
                     chain of email certificate. It can be a
                     string containing the certs to. (PEM format)
x509_nocerts      : if True then no attached certificate in mail
x509_crypt_certfiles: the certificates file or strings to encrypt
                      the messages with can be a file name /
                      string or a list of file names /
                      strings (PEM format)

实例

使用远程服务器的身份验证数据创建邮件对象::

mail = Mail('example.com:25', 'me@example.com', 'me:password')
GAE用户须知:

附件有一个自动内容“id='attachment-i”,其中i是累进数,通过这种方式,可以从HTML中引用为<img src=“cid:attachment-0”/>等。

class Attachment(payload, filename=None, content_id=None, content_type=None, encoding='utf-8')[源代码]

基类:email.mime.base.MIMEBase

电子邮件附件

参数
  • payload -- 使用read()方法指向文件或类似文件的对象的路径

  • filename -- 存储在消息中的附件的名称;如果设置为“无”,它将从有效负载路径中提取;像对象有效负载这样的文件必须指定显式文件名

  • content_id -- 附件的ID;自动包含在 <>

  • content_type -- 附件的内容类型;如果设置为“无”,则将使用gluon.content type模块从文件名中提取。

  • encoding -- 传递给此函数的所有字符串的编码(附件正文除外)

内容ID用于标识HTML正文中的附件;例如,带有内容ID“photo”的附加图像可以在HTML邮件中用作img标记的源。 <img src="cid:photo" /> .

例子::

从文本文件创建附件::

attachment = Mail.Attachment('/path/to/file.txt')

Content-Type: text/plain
MIME-Version: 1.0
Content-Disposition: attachment; filename="file.txt"
Content-Transfer-Encoding: base64

SOMEBASE64CONTENT=

使用自定义文件名和cid:从图像文件创建附件:

attachment = Mail.Attachment('/path/to/file.png',
                                 filename='photo.png',
                                 content_id='photo')

Content-Type: image/png
MIME-Version: 1.0
Content-Disposition: attachment; filename="photo.png"
Content-Id: <photo>
Content-Transfer-Encoding: base64

SOMEOTHERBASE64CONTENT=
send(to, subject='[no subject]', message='[no message]', attachments=None, cc=None, bcc=None, reply_to=None, sender=None, encoding='utf-8', raw=False, headers={}, from_address=None, cipher_type=None, sign=None, sign_passphrase=None, encrypt=None, x509_sign_keyfile=None, x509_sign_chainfile=None, x509_sign_certfile=None, x509_crypt_certfiles=None, x509_nocerts=None)[源代码]

使用构造函数中指定的数据发送电子邮件

参数
  • to -- 接收地址的列表或元组;也将接受单个对象

  • subject -- 电子邮件主题

  • message -- 电子邮件正文文本;取决于传递的对象的类型:-如果传递了2-list或2-tuple:第一个元素将是纯文本的源,第二个是HTML文本;-否则:对象将是纯文本的唯一源,如果文本或HTML源为-none:内容部分将被忽略,-string:内容部分将被忽略设置为-file-like-object:content-part将使用它的read()方法从中提取

  • attachments -- mail.attachment对象的列表或元组;还将接受单个对象

  • cc -- 碳拷贝接收器地址的列表或元组;也将接受单个对象

  • bcc -- 盲副本接收器地址的列表或元组;也将接受单个对象

  • reply_to -- 答复的地址

  • encoding -- 传递给此方法的所有字符串的编码(包括消息正文)

  • headers -- 在发送邮件前对邮件头进行优化的标题字典,例如 {{'X-Mailer' : 'web2py mailer'}}

  • from_address -- 要出现在“发件人:”标题中的地址,这不是信封发件人。如果未指定,将使用发件人

  • cipher_type -- gpg-需要一个python pyme包和gpgme lib x509-smime

  • gpg_home -- 可以设置gnupg home环境变量以指定gnupg的home

  • sign -- 在消息上签名(对或错)

  • sign_passphrase -- 密钥签名的密码短语

  • encrypt -- 加密消息(真或假)。它默认为真。…只有X509…

  • x509_sign_keyfile -- 签名者的私钥文件名或包含该密钥的字符串。(PEM格式)

  • x509_sign_certfile -- 签名者证书文件名或包含证书的字符串。(PEM格式)

  • x509_sign_chainfile -- 设置可选的一体式文件,您可以在其中组装证书颁发机构(CA)的证书,该证书构成电子邮件证书的证书链。它可以是包含证书的字符串。(PEM格式)

  • x509_nocerts -- 如果为真,则邮件中没有附加证书

  • x509_crypt_certfiles -- 用于加密消息的证书文件或字符串可以是文件名/字符串或文件名/字符串列表(PEM格式)

实例

将纯文本消息发送到单个地址::

mail.send('you@example.com',
          'Message subject',
          'Plain text body of the message')

将HTML邮件发送到单个地址:

mail.send('you@example.com',
          'Message subject',
          '<html>Plain text body of the message</html>')

将文本和HTML消息发送到三个地址(两个在CC中)::

mail.send('you@example.com',
          'Message subject',
          ('Plain text body', '<html>html body</html>'),
          cc=['other1@example.com', 'other2@example.com'])

通过“照片”内容ID:从邮件中仅发送带有图片附件的HTML邮件:

mail.send('you@example.com',
          'Message subject',
          (None, '<html><img src="cid:photo" /></html>'),
          Mail.Attachment('/path/to/photo.jpg'
                          content_id='photo'))

发送包含两个附件且没有正文的电子邮件::

mail.send('you@example.com,
          'Message subject',
          None,
          [Mail.Attachment('/path/to/fist.file'),
           Mail.Attachment('/path/to/second.file')])
返回

成功时正确,失败时错误。

返回前,方法更新两个对象的字段:

  • self.result:smtplib.smtp.send mail()或gae的mail.send_mail()方法的返回值

  • self.error:异常消息,如果上述操作成功,则无异常消息

class gluon.tools.PluginManager(*a, **b)[源代码]

基类:object

插件管理器类似于存储对象,但它是一个单级的。这意味着同一线程中的多个实例共享相同的属性。它的构造也很特殊。第一个参数是您定义的插件的名称。命名参数是具有默认值的插件所需的参数。如果以前定义了参数,则使用旧值。

例子

在某些常规配置文件中:

plugins = PluginManager()
plugins.me.param1=3

在插件模型中:

_ = PluginManager('me',param1=5,param2=6,param3=7)

使用插件的位置:

>>> print(plugins.me.param1)
3
>>> print(plugins.me.param2)
6
>>> plugins.me.param3 = 8
>>> print(plugins.me.param3)
8

以下是一些测试:

>>> a=PluginManager()
>>> a.x=6
>>> b=PluginManager('check')
>>> print(b.x)
6
>>> b=PluginManager() # reset settings
>>> print(b.x)
<Storage {}>
>>> b.x=7
>>> print(a.x)
7
>>> a.y.z=8
>>> print(b.y.z)
8
>>> test_thread_separation()
5
>>> plugins=PluginManager('me',db='mydb')
>>> print(plugins.me.db)
mydb
>>> print('me' in plugins)
True
>>> print(plugins.me.installed)
True
instances = {}
keys()[源代码]
class gluon.tools.Recaptcha2(request=None, public_key='', private_key='', error_message='invalid', label='Verify:', options=None, comment='')[源代码]

基类:gluon.html.DIV

实验:创建一个DIV,保存来自Google(v2)的更新的recatcha

参数
  • request -- 请求。如果未通过,则使用当前请求

  • public_key -- 谷歌给你的公开密钥

  • private_key -- 谷歌给你的私钥

  • error_message -- 验证失败时显示的错误消息

  • label -- 要使用的标签

  • options (dict) -- 获取这些参数-hl-theme-type-tabindex-callback-expired callback有关这些参数的文档,请参阅https://developers.google.com/recaptcha/docs/display

  • comment -- 评论

实例

用作:

form = FORM(Recaptcha2(public_key='...', private_key='...'))

或:

form = SQLFORM(...)
form.append(Recaptcha2(public_key='...', private_key='...'))

要保护登录页面,请使用:

from gluon.tools import Recaptcha2
auth.settings.captcha = Recaptcha2(request, public_key='...', private_key='...')
API_URI = 'https://www.google.com/recaptcha/api.js'
VERIFY_SERVER = 'https://www.google.com/recaptcha/api/siteverify'
xml()[源代码]

为此组件生成XML。

class gluon.tools.Service(environment=None, check_args=False)[源代码]

基类:object

exception JsonRpcException(code, info)[源代码]

基类:Exception

amfrpc(f)[源代码]

例子

用作:

service = Service()
@service.amfrpc
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget http://..../app/default/call/amfrpc/myfunction?a=hello&b=world
amfrpc3(domain='default')[源代码]

例子

用作:

service = Service()
@service.amfrpc3('domain')
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget http://…/app/default/call/amfrpc3/myfunction?A =你好,B =世界

call_service_function(f, *a, **b)[源代码]
csv(f)[源代码]

例子

用作:

service = Service()
@service.csv
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget http://..../app/default/call/csv/myfunction?a=3&b=4
error()[源代码]
json(f)[源代码]

例子

用作:

service = Service()
@service.json
def myfunction(a, b):
    return [{a: b}]
def call():
    return service()

那就叫它:;

wget http://…/app/default/call/json/myfunction?A =你好,B =世界

jsonrpc(f)[源代码]

例子

用作:

service = Service()
@service.jsonrpc
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget http://…/app/default/call/jsonrpc/myfunction?A =你好,B =世界

jsonrpc2(f)[源代码]

例子

用作:

service = Service()
@service.jsonrpc2
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget—发布数据'“jsonrpc”:“2.0”,

“id”:1,“method”:“myfunction”,“params”:“a”:1,“b”:2”http://…./app/default/call/jsonrpc2

jsonrpc_errors = {-32700: ('Parse error. Invalid JSON was received by the server.', 'An error occurred on the server while parsing the JSON text.'), -32603: ('Internal error', 'Internal JSON-RPC error.'), -32602: ('Invalid params', 'Invalid method parameter(s).'), -32601: ('Method not found', 'The method does not exist / is not available.'), -32600: ('Invalid Request', 'The JSON sent is not a valid Request object.'), -32099: ('Server error', 'Reserved for implementation-defined server-errors.')}
rss(f)[源代码]

例子

用作:

service = Service()
@service.rss
def myfunction():
    return dict(title=..., link=..., description=...,
        created_on=..., entries=[dict(title=..., link=...,
            description=..., created_on=...])
def call():
    return service()

然后打电话给:

wget http://…/app/default/call/rss/myfunction

run(f)[源代码]

例子

用作:

service = Service()
@service.run
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget http://..../app/default/call/run/myfunction?a=3&b=4
serve_amfrpc(version=0)[源代码]
serve_csv(args=None)[源代码]
serve_json(args=None)[源代码]
serve_jsonrpc()[源代码]
serve_jsonrpc2(data=None, batch_element=False)[源代码]
serve_rss(args=None)[源代码]
serve_run(args=None)[源代码]
serve_soap(version='1.1')[源代码]
serve_xml(args=None)[源代码]
serve_xmlrpc()[源代码]
soap(name=None, returns=None, args=None, doc=None, response_element_name=None)[源代码]

例子

用作:

service = Service()
@service.soap('MyFunction',returns={'result':int},args={'a':int,'b':int,})
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

from gluon.contrib.pysimplesoap.client import SoapClient
client = SoapClient(wsdl="http://..../app/default/call/soap?WSDL")
response = client.MyFunction(a=1,b=2)
return response['result']

它还公开在线生成的文档和XML示例消息,位于 http://..../app/default/call/soap

xml(f)[源代码]

例子

用作:

service = Service()
@service.xml
def myfunction(a, b):
    return a + b
def call():
    return service()

然后打电话给:

wget http://..../app/default/call/xml/myfunction?a=3&b=4
xmlrpc(f)[源代码]

例子

用作:

service = Service()
@service.xmlrpc
def myfunction(a, b):
    return a + b
def call():
    return service()

它的名字是:

wget http://…/app/default/call/xmlrpc/myfunction?A =你好,B =世界

class gluon.tools.Wiki(auth, env=None, render='markmin', manage_permissions=False, force_prefix='', restrict_search=False, extra=None, menu_groups=None, templates=None, migrate=True, controller=None, function=None, groups=None)[源代码]

基类:object

automenu()[源代码]

如果不存在,则添加菜单

can_edit(page=None)[源代码]
can_manage()[源代码]
can_read(page)[源代码]
can_see_menu()[源代码]
cloud()[源代码]
static component(text)[源代码]

在wiki文档中允许 @{{component:controller/function/args}} 呈现为 LOAD(..., ajax=True)

create()[源代码]
edit(slug, from_template=0)[源代码]
editmedia(slug)[源代码]
everybody = 'everybody'
first_paragraph(page)[源代码]
fix_hostname(body)[源代码]
get_renderer()[源代码]
html_render(page)[源代码]
markmin_base(body)[源代码]
markmin_render(page)[源代码]
media(id)[源代码]
menu(controller='default', function='index')[源代码]
not_authorized(page=None)[源代码]
pages()[源代码]
preview(render)[源代码]
read(slug, force_render=False)[源代码]
render_tags(tags)[源代码]
rows_page = 25
search(tags=None, query=None, cloud=True, preview=True, limitby=(0, 100), orderby=None)[源代码]
gluon.tools.fetch(url, data=None, headers=None, cookie={}, user_agent='Mozilla/5.0')[源代码]
gluon.tools.geocode(address)[源代码]
gluon.tools.prettydate(d, T=<function <lambda>>, utc=False)[源代码]
gluon.tools.reverse_geocode(lat, lng, lang=None)[源代码]

尝试获得给定纬度、经度的大致地址。