removed trailing whitespaces

This commit is contained in:
Damien Laniel 2009-01-15 09:50:37 +00:00
parent 63864ec926
commit f4d26e55e2
50 changed files with 304 additions and 304 deletions

View File

@ -16,7 +16,7 @@ class VoteAnonymityWidget(CheckboxWidget):
# XXX: include info for user ?
return ''
return CheckboxWidget.render(self)
def render_title(self, title):
return CheckboxWidget.render_title(self, _('Anonymous Voting'))

View File

@ -49,7 +49,7 @@ class RankedItemsWidget(CompositeWidget):
position = None
self.add(IntWidget, name, title = title, value = position, size = 5, **kwargs)
self.element_names[name] = key
if self.randomize_items:
random.shuffle(self.widgets)

View File

@ -152,7 +152,7 @@ class CategoriesDirectory(Directory):
html_top('categories', title = _('New Category'))
'<h2>%s</h2>' % _('New Category')
form.render()
def _q_lookup(self, component):
get_response().breadcrumb.append( ('categories/', _('Categories')) )
return CategoryPage(component)

View File

@ -304,6 +304,6 @@ class FieldsDirectory(Directory):
return redirect('.')
self.objectdef.store()
return redirect('.')

View File

@ -492,7 +492,7 @@ class FormsDirectory(Directory):
html_top('forms', title = _('New Form'))
'<h2>%s</h2>' % _('New Form')
form.render()
def _q_lookup(self, component):
get_response().breadcrumb.append( ('forms/', _('Forms')) )
return FormDefPage(component)

View File

@ -150,7 +150,7 @@ class RolesDirectory(Directory):
html_top('roles', title = _('New Role'))
'<h2>%s</h2>' % _('New Role')
form.render()
def _q_lookup(self, component):
get_response().breadcrumb.append(('roles/', _('Roles')))
return RolePage(component)

View File

@ -95,7 +95,7 @@ Public License:''')
doc_url = 'http://wcs.labs.libre-entreprise.org/doc/%s' % \
_('en/wcs-admin.html')
'<p>'
_('For more information:')
'</p>'

View File

@ -21,7 +21,7 @@ from qommon.admin.emails import EmailsDirectory
from qommon.admin.texts import TextsDirectory
import qommon.ident
import qommon.template
from formdef import FormDef
from fields import FieldWidget, FieldDefPage, FieldsDirectory
@ -55,7 +55,7 @@ class IdentificationDirectory(Directory):
],
inline = False,
required = True)
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
@ -115,7 +115,7 @@ class UserFieldsDirectory(FieldsDirectory):
form = self.mapping_form()
cfg_submit(form, 'users', ['field_name', 'field_email'])
return redirect('.')
class UsersDirectory(Directory):
_q_exports = ['', 'fields']
@ -142,7 +142,7 @@ class UsersDirectory(Directory):
class SettingsDirectory(AccessControlled, Directory):
_q_exports = ['', 'themes', 'users',
'template', 'misc', 'emails', 'debug_options', 'language',
'template', 'misc', 'emails', 'debug_options', 'language',
('import', 'p_import'), 'export', 'identification', 'sitename',
'texts', 'utf8switch', 'upload_theme']
@ -493,7 +493,7 @@ class SettingsDirectory(AccessControlled, Directory):
results[os.path.split(f)[0]] += 1
z.close()
return results
def debug_options [html] (self):
form = Form(enctype="multipart/form-data")
debug_cfg = get_cfg('debug', {})
@ -534,7 +534,7 @@ class SettingsDirectory(AccessControlled, Directory):
(str('en'), _('English')),
(str('es'), _('Spanish')),
(str('fr'), _('French')) ] )
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
@ -554,7 +554,7 @@ class SettingsDirectory(AccessControlled, Directory):
misc_cfg = get_cfg('misc', {})
form.add(StringWidget, 'sitename', title = _('Site Name'),
value = misc_cfg.get('sitename', ''))
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():

View File

@ -80,7 +80,7 @@ class UserUI:
widget = form.get_widget('method_%s' % klass.key)
if widget:
klass().submit(self.user, widget)
# XXX: and store!
# XXX 2: but pay attention to errors set on widget (think
# "duplicate username") (and the calling method will also
@ -211,7 +211,7 @@ class UserPage(Directory):
token_url = '%s://%s%sident/idp/token?%s' % (request.get_scheme(), request.get_server(),
get_publisher().get_root_url(), self.user.identification_token)
'<p>'
_('The identification token for this user is %s.\n') % token
'<p>'
@ -357,7 +357,7 @@ class UsersDirectory(Directory):
user_ui.user.store()
get_session().set_user(user_ui.user.id)
return redirect('.')
def _q_lookup(self, component):
get_response().breadcrumb.append( ('users/', _('Users')) )
try:

View File

@ -77,7 +77,7 @@ class WorkflowItemPage(Directory):
self.item.submit_admin_form(form)
self.workflow.store()
return redirect('..')
def delete [html] (self):
form = Form(enctype='multipart/form-data')
form.widgets.append(HtmlWidget('<p>%s</p>' % _('You are about to remove an item.')))
@ -95,7 +95,7 @@ class WorkflowItemPage(Directory):
self.workflow.store()
return redirect('../../')
class WorkflowItemsDir(Directory):
_q_exports = ['']
@ -113,7 +113,7 @@ class WorkflowItemsDir(Directory):
class WorkflowStatusPage(Directory):
_q_exports = ['', 'delete', 'newitem', ('items', 'items_dir'), 'update_order', 'edit']
def __init__(self, workflow, status_id):
self.workflow = workflow
try:
@ -187,9 +187,9 @@ class WorkflowStatusPage(Directory):
return redirect('.')
self.workflow.store()
return redirect('.')
def delete [html] (self):
form = Form(enctype="multipart/form-data")
@ -315,9 +315,9 @@ class WorkflowPage(Directory):
return redirect('.')
self.workflow.store()
return redirect('.')
def edit [html] (self, duplicate = False):
@ -408,7 +408,7 @@ class WorkflowsDirectory(Directory):
html_top('workflows', title = _('New Workflow'))
'<h2>%s</h2>' % _('New Workflow')
form.render()
def _q_lookup(self, component):
get_response().breadcrumb.append( ('workflows/', _('Workflows')) )
return WorkflowPage(component)

View File

@ -165,7 +165,7 @@ class RootDirectory(AccessControlled, Directory):
'<h2>%s</h2>' % formdef.name
first = False
'<h3>%s</h3>' % _('Forms with status "%s"') % status.name
'<ul>'
for f in status_forms:
try:
@ -179,7 +179,7 @@ class RootDirectory(AccessControlled, Directory):
userlabel)
'</ul>'
else:
# COMPAT (behaviour when no workflow)
@ -288,7 +288,7 @@ class FormPage(Directory):
'<h2>%s</h2>' % self.formdef.name
first = False
'<h3>%s</h3>' % _('Forms with status "%s"') % status.name
'<ul>'
for f in status_forms:
try:
@ -502,7 +502,7 @@ class FormPage(Directory):
except:
variance = 0
# not displayed since in square seconds which is not easy to grasp
from math import sqrt
# and standard deviation
std_dev = sqrt(variance)

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Parse mystery style generated by MTA at caiwireless.net."""

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Compuserve has its own weird format for bounces."""

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Parse bounce messages generated by Exim.

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""This appears to be the format for Novell GroupWise and NTMail

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""LLNL's custom Sendmail bounce message."""

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Netscape Messaging Server bounce formats.

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""sina.com bounces"""

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Yahoo! has its own weird format for bounces."""

View File

@ -4,14 +4,14 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Yale's mail server is pretty dumb.

View File

@ -4,12 +4,12 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -28,27 +28,27 @@ def process_bounce(args):
break
else:
return # didn't find any match
try:
to = msg['To']
local_part, server_part = to.split('@')
token_id = local_part.split('+')[1]
except (IndexError, KeyError):
return
pub = publisher.WcsPublisher.create_publisher()
pub.app_dir = os.path.join(pub.app_dir, server_part)
try:
token = Token.get(token_id)
except KeyError:
return
if token.type != 'email-bounce':
return
token.remove_self()
bounce = Bounce()
bounce.arrival_time = time.time()
bounce.bounce_message = msg.as_string()

View File

@ -79,7 +79,7 @@ class Field:
convert_value_to_str = None
in_listing = False
prefill = None
stats = None
def __init__(self, **kwargs):
@ -173,7 +173,7 @@ class WidgetField(Field):
def add_to_view_form(self, form, value = None):
kwargs = {}
self.field_key = 'f%s' % self.id
self.perform_more_widget_changes(form, kwargs, False)
@ -451,7 +451,7 @@ class DateField(WidgetField):
def convert_value_from_str(self, value):
return time.strptime(value, date_format())
def convert_value_to_str(self, value):
if value is None:
return ''
@ -459,7 +459,7 @@ class DateField(WidgetField):
return strftime(date_format(), value)
except TypeError:
return ''
def add_to_view_form(self, form, value = None):
value = localstrftime(value)
return WidgetField.add_to_view_form(self, form, value = value)

View File

@ -25,7 +25,7 @@ class Evolution:
def display_parts(self):
if not self.parts:
return []
l = []
for p in self.parts:
if not hasattr(p, 'view'):

View File

@ -248,7 +248,7 @@ class FormDef(StorableObject):
form.widgets.append(HtmlWidget(
htmltext('<div class="page"><h3>%s</h3>' % field.label)))
on_page = True
value = dict.get(field.id, '')
field.add_to_view_form(form, value)
@ -267,7 +267,7 @@ class FormDef(StorableObject):
d[field.id] = field.convert_value_from_str(d[field.id])
if widget and widget.cleanup:
widget.cleanup()
return d
@ -370,7 +370,7 @@ class FormDef(StorableObject):
if v:
return v
return None
def notify_new_user(self, formdata):
submitter_email = self.get_submitter_email(formdata)
if not submitter_email:
@ -432,7 +432,7 @@ link: [url]
from_email = self.receiver.emails[0]
else:
from_email = None
url = formdata.get_url()
if old_status != formdata.status:
@ -494,7 +494,7 @@ link: [url]
'before': _(status_labels[old_status]),
'after': _(status_labels[formdata.status])
}
emails.custom_ezt_email(email_key, data, self.receiver.emails,
exclude_current_user = True,
fire_and_forget = True)

View File

@ -45,7 +45,7 @@ class FormStatusPage(Directory):
mine = True
elif self.filled.user_id == user.id:
mine = True
if not self.filled.is_user_allowed_read(user):
if not user:
raise errors.AccessUnauthorizedError()
@ -270,7 +270,7 @@ class FormStatusPage(Directory):
form.get_widget('comment').attrs[str('class')] = str('comment')
form.add_submit('add-comment', _('Add Comment'))
form.add_submit('finish', _('Finish'))
if form and form.is_submitted():
url = self.submit(form)
if url is None:
@ -292,7 +292,7 @@ class FormStatusPage(Directory):
_('The form has been recorded on %(date)s with the number %(number)s.') % {
'date': tm, 'number': self.filled.id}
"</p>"
self.receipt(always_include_user = True)
if self.formdef.workflow:

View File

@ -211,7 +211,7 @@ class FormPage(Directory):
else:
magictoken = get_request().form['magictoken']
form.add_hidden('magictoken', magictoken)
form.add_submit('submit', _('Next'))
data = session.get_by_magictoken(magictoken, {})
else:
@ -287,9 +287,9 @@ class FormPage(Directory):
self.check_role()
if self.formdef.disabled:
raise errors.AccessForbiddenError()
session = get_session()
existing_formdata = None
if editing:
existing_formdata = editing.data
@ -370,7 +370,7 @@ class FormPage(Directory):
form_data = session.get_by_magictoken(magictoken, {})
data = self.formdef.get_data(form)
form_data.update(data)
if self.formdef.allow_drafts and form.get_submit() == 'savedraft':
self.save_draft(form_data, page_no)
return redirect(get_publisher().get_root_url())
@ -533,7 +533,7 @@ class FormPage(Directory):
del tempfile['value']
return value
def validating [html] (self, data):
html_top(self.formdef.name)
self.step(1, data = data)
@ -759,7 +759,7 @@ class RootDirectory(AccessControlled, Directory):
'<ul>'
for f in current:
'<li><a href="%s/%s/">%s</a>, %s, %s: %s</li>' % (
f.formdef.url_name, f.id, f.formdef.name,
f.formdef.url_name, f.id, f.formdef.name,
misc.localstrftime(f.receipt_time),
_('status'),
_(status_labels[f.status]) )
@ -770,7 +770,7 @@ class RootDirectory(AccessControlled, Directory):
'<ul>'
for f in done:
'<li><a href="%s/%s/">%s</a>, %s, %s: %s</li>' % (
f.formdef.url_name, f.id, f.formdef.name,
f.formdef.url_name, f.id, f.formdef.name,
misc.localstrftime(f.receipt_time),
_('status'),
_(status_labels[f.status]) )
@ -789,7 +789,7 @@ class RootDirectory(AccessControlled, Directory):
'<ul>'
for f in fms:
'<li><a href="%s/%s/">%s</a>, %s</li>' % (
f.formdef.url_name, f.id, f.formdef.name,
f.formdef.url_name, f.id, f.formdef.name,
misc.localstrftime(f.receipt_time))
'</ul>'

View File

@ -70,7 +70,7 @@ class LibertyDirectory(qommon.liberty.LibertyDirectory):
if nameNode:
doc = libxml2.parseDoc(nameNode)
name = unicode(doc.getContent(), 'utf-8').encode('iso-8859-1')
if email and name:
user = get_publisher().user_class()
user.email = email

View File

@ -64,7 +64,7 @@ class EmailsDirectory(Directory):
title = _('Check DNS for domain name'),
value = emails.get('check_domain_with_dns', True),
hint = _('Use a DNS request to check domain names used in email fields'))
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():

View File

@ -9,7 +9,7 @@ def generate_header_menu(selected = None):
show_logger = get_cfg('debug', {}).get('logger', False)
show_debug = get_cfg('debug', {}).get('debug_panel', False)
show_bounces = (get_cfg('emails', {}).get('bounce_handler') == True and Bounce.count() > 0)
for k, v in get_publisher().get_admin_root().menu_items:
if k == '/':
continue # skip root

View File

@ -83,7 +83,7 @@ class SMTPWithTimeout(smtplib.SMTP):
def custom_ezt_email(key, mail_body_data, email_rcpt, **kwargs):
if not EmailsDirectory.is_enabled(key):
return

View File

@ -56,21 +56,21 @@ class FormError(Exception):
def __init__(self, field, msg):
self.field = field
self.msg = msg
def __str__(self):
return self.msg
class ConnectionError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
class ConfigurationError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg

View File

@ -18,7 +18,7 @@ EZT files (convention: use the suffix .ezt for such files):
>>> template = Template("../templates/log.ezt")
or by calling the parse() method of a template instance directly with
or by calling the parse() method of a template instance directly with
a EZT template string:
>>> template = Template()
@ -52,7 +52,7 @@ with the output fileobject to the templates generate method:
</body>
</html>
Template syntax error reporting should be improved. Currently it is
Template syntax error reporting should be improved. Currently it is
very sparse (template line numbers would be nice):
>>> Template().parse("[if-any where] foo [else] bar [end unexpected args]")
@ -77,7 +77,7 @@ Directives
==========
Several directives allow the use of dotted qualified names refering to objects
or attributes of objects contained in the data dictionary given to the
or attributes of objects contained in the data dictionary given to the
.generate() method.
Qualified names
@ -102,7 +102,7 @@ Directives
[QUAL_NAME]
This directive is simply replaced by the value of the qualified name.
If the value is a number it's converted to a string before being
If the value is a number it's converted to a string before being
outputted. If it is None, nothing is outputted. If it is a python file
object (i.e. any object with a "read" method), it's contents are
outputted. If it is a callback function (any callable python object
@ -137,7 +137,7 @@ Directives
----------------
[for QUAL_NAME] ... [end]
The text within the [for ...] directive and the corresponding [end]
is repeated for each element in the sequence referred to by the
qualified name in the for directive. Within the for block this
@ -187,7 +187,7 @@ Directives
The format directive controls how the values substituted into
templates are escaped before they are put into the output stream. It
has no effect on the literal text of the templates, only the output
from [QUAL_NAME ...] directives. STRING can be one of "raw" "html"
from [QUAL_NAME ...] directives. STRING can be one of "raw" "html"
or "xml". The "raw" mode leaves the output unaltered. The "html" and
"xml" modes escape special characters using entity escapes (like
&quot; and &gt;)
@ -195,27 +195,27 @@ Directives
#
# Copyright (C) 2001-2005 Greg Stein. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#
@ -545,7 +545,7 @@ def _prepare_ref(refname, for_names, file_args):
"""refname -> a string containing a dotted identifier. example:"foo.bar.bang"
for_names -> a list of active for sequences.
Returns a `value reference', a 3-tuple made out of (refname, start, rest),
Returns a `value reference', a 3-tuple made out of (refname, start, rest),
for fast access later.
"""
# is the reference a string constant?
@ -593,8 +593,8 @@ def _get_value((refname, start, rest), ctx):
"""(refname, start, rest) -> a prepared `value reference' (see above).
ctx -> an execution context instance.
Does a name space lookup within the template name space. Active
for blocks take precedence over data dictionary members with the
Does a name space lookup within the template name space. Active
for blocks take precedence over data dictionary members with the
same name.
"""
if rest is None:
@ -731,7 +731,7 @@ def test_parse():
['', '["a \\"b[foo]" c.d f]', None, '']
def _test(argv):
import doctest, ezt
import doctest, ezt
verbose = "-v" in argv
return doctest.testmod(ezt, verbose=verbose)

View File

@ -202,7 +202,7 @@ class FileWithPreviewWidget(CompositeWidget):
if self.token in session.tempfiles.keys():
session.tempfiles[self.token]['value'] = self.value.fp.read()
r += htmltext('<img alt="%s" src="tempfile?t=%s" />' % \
(self.value.orig_filename,
(self.value.orig_filename,
self.token))
self.value.fp.seek(0)
for widget in self.get_widgets():
@ -386,7 +386,7 @@ class DateWidget(StringWidget):
elif self.maximum_date and value[:3] > self.maximum_date[:3]:
self.error = _('invalid date; date must be on or before %s') % time.strftime(
format_string, self.maximum_date)
def render_content(self):
self.attrs['id'] = 'id_%s' % self.name
self.attrs['class'] = 'date-pick'
@ -704,7 +704,7 @@ class TagsWidget(StringWidget):
def __init__(self, name, value = None, known_tags = None, **kwargs):
StringWidget.__init__(self, name, value, **kwargs)
self.known_tags = known_tags
def _parse(self, request):
StringWidget._parse(self, request)
if self.value is not None:

View File

@ -55,7 +55,7 @@ class MethodDirectory(Directory):
providers[p.providerId] = p
include_protocol = True
if len([x for x in providers.values() if
if len([x for x in providers.values() if
x.getProtocolConformance() == lasso.PROTOCOL_SAML_2_0]) in (0, len(providers)):
include_protocol = False
@ -93,7 +93,7 @@ class MethodDirectory(Directory):
def register [html] (self):
if get_cfg('sp', {}).get('identity_creation', 'admin') == 'admin':
raise errors.TraversalError()
if not get_request().user:
raise errors.AccessUnauthorizedError()
@ -585,7 +585,7 @@ class AdminIDPUI(Directory):
provider_id = re.findall(r'(provider|entity)ID="(.*?)"', metadata)[0][1]
except IndexError:
return error_page(_('Bad metadata'))
new_key_provider_id = misc.get_provider_key(provider_id)
key_provider_id = self.idpk
old_metadata_fn = None
@ -698,7 +698,7 @@ class MethodAdminDirectory(Directory):
metadata_url,
_('SAML 2.0 Service Provider Metadata'),
_('Download Service Provider SAML 2.0 Metadata file'))
'<dt><a href="idp/">%s</a></dt> <dd>%s</dd>' % (
_('Identity Providers'), _('Add and remove identity providers'))
@ -865,7 +865,7 @@ class MethodAdminDirectory(Directory):
encryption_pem_key = ''
if os.path.exists(encryption_publickey_fn):
encryption_pem_key = open(encryption_publickey_fn).read()
for key_type in ('signing', 'encryption'):
if key_type == 'signing':
pem_key = signing_pem_key
@ -886,7 +886,7 @@ class MethodAdminDirectory(Directory):
else:
sp_key[key_type] = ''
sp_body = '''
sp_body = '''
<SoapEndpoint>%(base_url)s/soapEndpoint</SoapEndpoint>
<SingleLogoutServiceURL>%(base_url)s/singleLogout</SingleLogoutServiceURL>
@ -917,7 +917,7 @@ class MethodAdminDirectory(Directory):
</SPDescriptor>''' % get_cfg('sp')
orga = ''
if get_cfg('sp').get('organization_name'):
orga = '''
@ -952,7 +952,7 @@ class MethodAdminDirectory(Directory):
encryption_pem_key = ''
if os.path.exists(encryption_publickey_fn):
encryption_pem_key = open(encryption_publickey_fn).read()
for key_type in ('signing', 'encryption'):
if key_type == 'signing':
pem_key = signing_pem_key
@ -1001,7 +1001,7 @@ class MethodAdminDirectory(Directory):
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="%(saml2_base_url)s/singleSignOnRedirect" />
</SPSSODescriptor>''' % get_cfg('sp')
orga = ''
if get_cfg('sp').get('organization_name'):
orga = '''<Organization>
@ -1056,7 +1056,7 @@ class MethodAdminDirectory(Directory):
def identities_submit(self, form):
from admin.settings import cfg_submit
cfg_submit(form, 'saml_identities',
cfg_submit(form, 'saml_identities',
('grab-user-with-wsf', 'creation', 'notify-on-register', 'email-confirmation'))

View File

@ -259,7 +259,7 @@ class MethodDirectory(Directory):
TextsDirectory.get_html_text(str('password-forgotten-token-sent'))
return forgotten_token_sent()
def forgotten_token [html] (self):
tokenv = get_request().form.get('t')
@ -574,7 +574,7 @@ class MethodAdminDirectory(Directory):
def passwords_submit(self, form):
from admin.settings import cfg_submit
cfg_submit(form, 'passwords',
cfg_submit(form, 'passwords',
('can_change', 'generate', 'lost_password_behaviour',
'min_length', 'max_length', 'admin_email',
'hashing_algo'))
@ -621,7 +621,7 @@ class MethodAdminDirectory(Directory):
def identities_submit(self, form):
from admin.settings import cfg_submit
cfg_submit(form, 'identities',
cfg_submit(form, 'identities',
('creation', 'email-as-username', 'notify-on-register', 'email-confirmation',
'warn_about_unused_account_delay', 'remove_unused_account_delay'))
@ -1018,8 +1018,8 @@ A new account has been created on [hostname].
TextsDirectory.register('account-created-waiting-activation',
N_('Text when account confirmed by user but waiting moderator approval'),
default = N_('''<p>
Your account has been created. In order to be effective
it must be activated by a moderator. You will receive an
Your account has been created. In order to be effective
it must be activated by a moderator. You will receive an
email when this is done.
</p>'''))

View File

@ -175,7 +175,7 @@ class LibertyDirectory(Directory):
else:
raise
else:
get_session_manager().expire_session()
get_session_manager().expire_session()
try:
del get_session_manager()[session.id]
except KeyError:
@ -204,14 +204,14 @@ class LibertyDirectory(Directory):
logout.initRequest(None, lasso.HTTP_METHOD_REDIRECT)
except lasso.Error, error:
if error[0] == lasso.PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
if error[0] == lasso.PROFILE_ERROR_SESSION_NOT_FOUND:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
raise
logout.buildRequestMsg()
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(logout.msgUrl)
def soapEndpoint(self):
@ -230,7 +230,7 @@ class LibertyDirectory(Directory):
length = int(request.environ.get('CONTENT_LENGTH'))
soap_message = request.stdin.read(length)
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
if request_type == lasso.REQUEST_TYPE_LOGOUT:
logout = lasso.Logout(misc.get_lasso_server())
@ -271,7 +271,7 @@ class LibertyDirectory(Directory):
request = get_request()
if not lasso.isLibertyQuery(request.get_query()):
return redirect('.')
defederation = lasso.Defederation(misc.get_lasso_server())
defederation.processNotificationMsg(request.get_query())
session = get_session()

View File

@ -221,12 +221,12 @@ xlate = {
def latin1_to_ascii (unicrap):
"""This takes a UNICODE string and replaces Latin-1 characters with
something equivalent in 7-bit ASCII. It returns a plain ASCII string.
This function makes a best effort to convert Latin-1 characters into
something equivalent in 7-bit ASCII. It returns a plain ASCII string.
This function makes a best effort to convert Latin-1 characters into
ASCII equivalents. It does not just strip out the Latin-1 characters.
All characters in the standard 7-bit ASCII range are preserved.
In the 8th bit range all the Latin-1 accented letters are converted
to unaccented equivalents. Most symbol characters are converted to
All characters in the standard 7-bit ASCII range are preserved.
In the 8th bit range all the Latin-1 accented letters are converted
to unaccented equivalents. Most symbol characters are converted to
something meaningful. Anything not converted is deleted.
<http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/251871>
@ -307,7 +307,7 @@ def format_time(datetime, formatstring, gmtime = False):
weekday = None
else:
year, month, day, hour, minute, second, weekday = datetime[:7]
weekday_names = [_('Monday'), _('Tuesday'), _('Wednesday'),
_('Thursday'), _('Friday'), _('Saturday'), _('Sunday')]

View File

@ -154,7 +154,7 @@ class QommonPublisher(Publisher):
gettext.install(self.APP_NAME) # will use environment variable to get language
else:
self.translations[lang].install()
_1 = _
_1 = _
__builtin__.__dict__['_'] = lambda x: unicode(_1(str(x)), 'utf-8').encode(self.site_charset)
__builtin__.__dict__['_1'] = _1
@ -511,7 +511,7 @@ class QommonPublisher(Publisher):
'%(asctime)s %(levelname)s %(address)s '\
'%(session_id)s %(path)s %(user_id)s - %(message)s')
hdlr.setFormatter(formatter)
self._app_logger.addHandler(hdlr)
self._app_logger.addHandler(hdlr)
self._app_logger.setLevel(logging.DEBUG)
return self._app_logger

View File

@ -47,7 +47,7 @@ class Saml2Directory(Directory):
response.set_status(401)
return 'Unknown authentication failure'
raise
login.acceptSso()
login.acceptSso()
return self.success_ecp()
@ -260,7 +260,7 @@ class Saml2Directory(Directory):
else:
ni = name_id
nis = list(get_publisher().user_class.select(lambda x: ni in x.name_identifiers))
if nis:
if nis:
user = nis[0]
else:
if not session.ident_idp_token:
@ -308,10 +308,10 @@ class Saml2Directory(Directory):
logout.initRequest(None, lasso.HTTP_METHOD_REDIRECT)
except lasso.Error, error:
if error[0] == lasso.PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
if error[0] == lasso.PROFILE_ERROR_SESSION_NOT_FOUND:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
raise
if session.lasso_session_index:
@ -345,7 +345,7 @@ class Saml2Directory(Directory):
session.lasso_session_dump = None
else:
raise
if logout.isSessionDirty:
if logout.session:
session.lasso_session_dump = logout.session.dump()
@ -353,7 +353,7 @@ class Saml2Directory(Directory):
session.lasso_session_dump = None
if not session.lasso_session_dump:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
@ -363,10 +363,10 @@ class Saml2Directory(Directory):
logout.initRequest(None, lasso.HTTP_METHOD_SOAP)
except lasso.Error, error:
if error[0] == lasso.PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
if error[0] == lasso.PROFILE_ERROR_SESSION_NOT_FOUND:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
raise
logout.buildRequestMsg()
@ -427,7 +427,7 @@ class Saml2Directory(Directory):
response = get_response()
response.set_content_type('text/xml')
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
if request_type != lasso.REQUEST_TYPE_LOGOUT:
get_logger().warn('SOAP message on single logout url not a slo message')
@ -489,7 +489,7 @@ class Saml2Directory(Directory):
logout.setSessionFromDump('<Session />')
except:
pass
try:
logout.validateRequest()
except lasso.Error, error:
@ -502,7 +502,7 @@ class Saml2Directory(Directory):
else:
raise
else:
get_session_manager().expire_session()
get_session_manager().expire_session()
try:
del get_session_manager()[session.id]
except KeyError:
@ -563,7 +563,7 @@ class Saml2Directory(Directory):
response = get_response()
response.set_content_type('text/xml')
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
if request_type != lasso.REQUEST_TYPE_NAME_ID_MANAGEMENT:
get_logger().warn('SOAP message on name id management url of not appropriate type')
@ -640,7 +640,7 @@ class Saml2Directory(Directory):
get_request().user.lasso_dump = None
if not get_request().user.lasso_dump:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())

View File

@ -130,7 +130,7 @@ class StorageSessionManager(QuixoteSessionManager):
def commit_changes(self, session):
if session and session.id:
session.store()
def keys(self):
return BasicSession.keys()

View File

@ -47,7 +47,7 @@ class StorableObject(object):
def items(cls):
return [(x, cls.get(x)) for x in cls.keys()]
items = classmethod(items)
def count(cls):
return len(cls.keys())
count = classmethod(count)
@ -73,7 +73,7 @@ class StorableObject(object):
objects.reverse()
return objects
select = classmethod(select)
def has_key(cls, id):
return fix_key(id) in cls.keys()
has_key = classmethod(has_key)

View File

@ -94,4 +94,4 @@ def test():
testdate = testdate + one_day
if __name__ == "__main__":
test()
test()

View File

@ -263,13 +263,13 @@ class FeedParserDict(UserDict):
if not self.has_key(key):
self[key] = value
return self[key]
def has_key(self, key):
try:
return hasattr(self, key) or UserDict.has_key(self, key)
except AttributeError:
return False
def __getattr__(self, key):
try:
return self.__dict__[key]
@ -325,7 +325,7 @@ def _ebcdic_to_ascii(s):
_ebcdic_to_ascii_map = string.maketrans( \
''.join(map(chr, range(256))), ''.join(map(chr, emap)))
return s.translate(_ebcdic_to_ascii_map)
_cp1252 = {
unichr(128): unichr(8364), # euro sign
unichr(130): unichr(8218), # single low-9 quotation mark
@ -378,7 +378,7 @@ class _FeedParserMixin:
'http://purl.org/atom/ns#': '',
'http://www.w3.org/2005/Atom': '',
'http://purl.org/rss/1.0/modules/rss091#': '',
'http://webns.net/mvcb/': 'admin',
'http://purl.org/rss/1.0/modules/aggregation/': 'ag',
'http://purl.org/rss/1.0/modules/annotate/': 'annotate',
@ -433,7 +433,7 @@ class _FeedParserMixin:
can_contain_relative_uris = ['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description']
can_contain_dangerous_markup = ['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description']
html_types = ['text/html', 'application/xhtml+xml']
def __init__(self, baseuri=None, baselang=None, encoding='utf-8'):
if _debug: sys.stderr.write('initializing FeedParser\n')
if not self._matchnamespaces:
@ -474,7 +474,7 @@ class _FeedParserMixin:
# normalize attrs
attrs = [(k.lower(), v) for k, v in attrs]
attrs = [(k, k in ('rel', 'type') and v.lower() or v) for k, v in attrs]
# track xml:base and xml:lang
attrsD = dict(attrs)
baseuri = attrsD.get('xml:base', attrsD.get('base')) or self.baseuri
@ -497,7 +497,7 @@ class _FeedParserMixin:
self.lang = lang
self.basestack.append(self.baseuri)
self.langstack.append(lang)
# track namespaces
for prefix, uri in attrs:
if prefix.startswith('xmlns:'):
@ -543,7 +543,7 @@ class _FeedParserMixin:
self.intextinput = 0
if (not prefix) and tag not in ('title', 'link', 'description', 'url', 'href', 'width', 'height'):
self.inimage = 0
# call special handler (if defined) or default handler
methodname = '_start_' + prefix + suffix
try:
@ -661,7 +661,7 @@ class _FeedParserMixin:
elif contentType == 'xhtml':
contentType = 'application/xhtml+xml'
return contentType
def trackNamespace(self, prefix, uri):
loweruri = uri.lower()
if (prefix, loweruri) == (None, 'http://my.netscape.com/rdf/simple/0.9/') and not self.version:
@ -682,7 +682,7 @@ class _FeedParserMixin:
def resolveURI(self, uri):
return _urljoin(self.baseuri or '', uri)
def decodeEntities(self, element, data):
return data
@ -695,7 +695,7 @@ class _FeedParserMixin:
def pop(self, element, stripWhitespace=1):
if not self.elementstack: return
if self.elementstack[-1][0] != element: return
element, expectingText, pieces = self.elementstack.pop()
if self.version == 'atom10' and self.contentparams.get('type','text') == 'application/xhtml+xml':
@ -731,11 +731,11 @@ class _FeedParserMixin:
pass
except binascii.Incomplete:
pass
# resolve relative URIs
if (element in self.can_be_relative_uri) and output:
output = self.resolveURI(output)
# decode entities within embedded markup
if not self.contentparams.get('base64', 0):
output = self.decodeEntities(element, output)
@ -758,7 +758,7 @@ class _FeedParserMixin:
if is_htmlish and RESOLVE_RELATIVE_URIS:
if element in self.can_contain_relative_uris:
output = _resolveRelativeURIs(output, self.baseuri, self.encoding, self.contentparams.get('type', 'text/html'))
# parse microformats
# (must do this before sanitizing because some microformats
# rely on elements that we sanitize)
@ -774,7 +774,7 @@ class _FeedParserMixin:
vcard = mfresults.get('vcard')
if vcard:
self._getContext()['vcard'] = vcard
# sanitize embedded markup
if is_htmlish and SANITIZE_HTML:
if element in self.can_contain_dangerous_markup:
@ -801,7 +801,7 @@ class _FeedParserMixin:
# categories/tags/keywords/whatever are handled in _end_category
if element == 'category':
return output
# store output in appropriate place(s)
if self.inentry and not self.insource:
if element == 'content':
@ -849,7 +849,7 @@ class _FeedParserMixin:
self.incontent -= 1
self.contentparams.clear()
return value
# a number of elements in a number of RSS variants are nominally plain
# text, but this is routinely ignored. This is an attempt to detect
# the most common cases. As false positives often result in silent
@ -880,7 +880,7 @@ class _FeedParserMixin:
prefix = self.namespacemap.get(prefix, prefix)
name = prefix + ':' + suffix
return name
def _getAttribute(self, attrsD, name):
return attrsD.get(self._mapToStandardPrefix(name))
@ -908,7 +908,7 @@ class _FeedParserMixin:
pass
attrsD['href'] = href
return attrsD
def _save(self, key, value):
context = self._getContext()
context.setdefault(key, value)
@ -927,7 +927,7 @@ class _FeedParserMixin:
self.version = 'rss20'
else:
self.version = 'rss'
def _start_dlhottitles(self, attrsD):
self.version = 'hotrss'
@ -945,7 +945,7 @@ class _FeedParserMixin:
self._start_link({})
self.elementstack[-1][-1] = attrsD['href']
self._end_link()
def _start_feed(self, attrsD):
self.infeed = 1
versionmap = {'0.1': 'atom01',
@ -962,13 +962,13 @@ class _FeedParserMixin:
def _end_channel(self):
self.infeed = 0
_end_feed = _end_channel
def _start_image(self, attrsD):
context = self._getContext()
context.setdefault('image', FeedParserDict())
self.inimage = 1
self.push('image', 0)
def _end_image(self):
self.pop('image')
self.inimage = 0
@ -979,7 +979,7 @@ class _FeedParserMixin:
self.intextinput = 1
self.push('textinput', 0)
_start_textInput = _start_textinput
def _end_textinput(self):
self.pop('textinput')
self.intextinput = 0
@ -1173,7 +1173,7 @@ class _FeedParserMixin:
self.popContent('subtitle')
_end_tagline = _end_subtitle
_end_itunes_subtitle = _end_subtitle
def _start_rights(self, attrsD):
self.pushContent('rights', attrsD, 'text/plain', 1)
_start_dc_rights = _start_rights
@ -1268,7 +1268,7 @@ class _FeedParserMixin:
attrsD['rel']='license'
if value: attrsD['href']=value
context.setdefault('links', []).append(attrsD)
def _start_creativecommons_license(self, attrsD):
self.push('license', 1)
_start_creativeCommons_license = _start_creativecommons_license
@ -1289,7 +1289,7 @@ class _FeedParserMixin:
value = FeedParserDict({'relationships': relationships, 'href': href, 'name': name})
if value not in xfn:
xfn.append(value)
def _addTag(self, term, scheme, label):
context = self._getContext()
tags = context.setdefault('tags', [])
@ -1307,15 +1307,15 @@ class _FeedParserMixin:
self.push('category', 1)
_start_dc_subject = _start_category
_start_keywords = _start_category
def _end_itunes_keywords(self):
for term in self.pop('itunes_keywords').split():
self._addTag(term, 'http://www.itunes.com/', None)
def _start_itunes_category(self, attrsD):
self._addTag(attrsD.get('text'), 'http://www.itunes.com/', None)
self.push('category', 1)
def _end_category(self):
value = self.pop('category')
if not value: return
@ -1331,7 +1331,7 @@ class _FeedParserMixin:
def _start_cloud(self, attrsD):
self._getContext()['cloud'] = FeedParserDict(attrsD)
def _start_link(self, attrsD):
attrsD.setdefault('rel', 'alternate')
if attrsD['rel'] == 'self':
@ -1428,7 +1428,7 @@ class _FeedParserMixin:
context = self._getContext()
if context.has_key('generator_detail'):
context['generator_detail']['name'] = value
def _start_admin_generatoragent(self, attrsD):
self.push('generator', 1)
value = self._getAttribute(attrsD, 'rdf:resource')
@ -1443,7 +1443,7 @@ class _FeedParserMixin:
if value:
self.elementstack[-1][2].append(value)
self.pop('errorreportsto')
def _start_summary(self, attrsD):
context = self._getContext()
if context.has_key('summary'):
@ -1461,7 +1461,7 @@ class _FeedParserMixin:
self.popContent(self._summaryKey or 'summary')
self._summaryKey = None
_end_itunes_summary = _end_summary
def _start_enclosure(self, attrsD):
attrsD = self._itsAnHrefDamnIt(attrsD)
context = self._getContext()
@ -1470,7 +1470,7 @@ class _FeedParserMixin:
href = attrsD.get('href')
if href and not context.get('id'):
context['id'] = href
def _start_source(self, attrsD):
self.insource = 1
@ -1513,7 +1513,7 @@ class _FeedParserMixin:
self.push('itunes_image', 0)
self._getContext()['image'] = FeedParserDict({'href': attrsD.get('href')})
_start_itunes_link = _start_itunes_image
def _end_itunes_block(self):
value = self.pop('itunes_block', 0)
self._getContext()['itunes_block'] = (value == 'yes') and 1 or 0
@ -1530,10 +1530,10 @@ if _XML_AVAILABLE:
_FeedParserMixin.__init__(self, baseuri, baselang, encoding)
self.bozo = 0
self.exc = None
def startPrefixMapping(self, prefix, uri):
self.trackNamespace(prefix, uri)
def startElementNS(self, name, qname, attrs):
namespace, localname = name
lowernamespace = str(namespace or '').lower()
@ -1606,7 +1606,7 @@ if _XML_AVAILABLE:
def error(self, exc):
self.bozo = 1
self.exc = exc
def fatalError(self, exc):
self.error(exc)
raise exc
@ -1616,13 +1616,13 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
bare_ampersand = re.compile("&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)")
elements_no_end_tag = ['area', 'base', 'basefont', 'br', 'col', 'frame', 'hr',
'img', 'input', 'isindex', 'link', 'meta', 'param']
def __init__(self, encoding, type):
self.encoding = encoding
self.type = type
if _debug: sys.stderr.write('entering BaseHTMLProcessor, encoding=%s\n' % self.encoding)
sgmllib.SGMLParser.__init__(self)
def reset(self):
self.pieces = []
sgmllib.SGMLParser.reset(self)
@ -1644,7 +1644,7 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
def feed(self, data):
data = re.compile(r'<!((?!DOCTYPE|--|\[))', re.IGNORECASE).sub(r'&lt;!\1', data)
#data = re.sub(r'<(\S+?)\s*?/>', self._shorttag_replace, data) # bug [ 1399464 ] Bad regexp for _shorttag_replace
data = re.sub(r'<([^<\s]+?)\s*/>', self._shorttag_replace, data)
data = re.sub(r'<([^<\s]+?)\s*/>', self._shorttag_replace, data)
data = data.replace('&#39;', "'")
data = data.replace('&#34;', '"')
if self.encoding and type(data) == type(u''):
@ -1707,7 +1707,7 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
self.pieces.append('&#%s;' % hex(ord(_cp1252[value]))[1:])
else:
self.pieces.append('&#%(ref)s;' % locals())
def handle_entityref(self, ref):
# called for each entity reference, e.g. for '&copy;', ref will be 'copy'
# Reconstruct the original entity reference.
@ -1722,12 +1722,12 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
# Store the original text verbatim.
if _debug: sys.stderr.write('_BaseHTMLProcessor, handle_text, text=%s\n' % text)
self.pieces.append(text)
def handle_comment(self, text):
# called for each HTML comment, e.g. <!-- insert Javascript code here -->
# Reconstruct the original comment.
self.pieces.append('<!--%(text)s-->' % locals())
def handle_pi(self, text):
# called for each processing instruction, e.g. <?instruction>
# Reconstruct original processing instruction.
@ -1739,7 +1739,7 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
# "http://www.w3.org/TR/html4/loose.dtd">
# Reconstruct original DOCTYPE
self.pieces.append('<!%(text)s>' % locals())
_new_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9:]*\s*').match
def _scan_name(self, i, declstartpos):
rawdata = self.rawdata
@ -1795,7 +1795,7 @@ class _LooseFeedParser(_FeedParserMixin, _BaseHTMLProcessor):
data = data.replace('&quot;', '"')
data = data.replace('&apos;', "'")
return data
def strattrs(self, attrs):
return ''.join([' %s="%s"' % (n,v.replace('"','&quot;')) for n,v in attrs])
@ -1819,12 +1819,12 @@ class _MicroformatsParser:
self.enclosures = []
self.xfn = []
self.vcard = None
def vcardEscape(self, s):
if type(s) in (type(''), type(u'')):
s = s.replace(',', '\\,').replace(';', '\\;').replace('\n', '\\n')
return s
def vcardFold(self, s):
s = re.sub(';+$', '', s)
sFolded = ''
@ -1840,14 +1840,14 @@ class _MicroformatsParser:
def normalize(self, s):
return re.sub(r'\s+', ' ', s).strip()
def unique(self, aList):
results = []
for element in aList:
if element not in results:
results.append(element)
return results
def toISO8601(self, dt):
return time.strftime('%Y-%m-%dT%H:%M:%SZ', dt)
@ -1937,21 +1937,21 @@ class _MicroformatsParser:
def findVCards(self, elmRoot, bAgentParsing=0):
sVCards = ''
if not bAgentParsing:
arCards = self.getPropertyValue(elmRoot, 'vcard', bAllowMultiple=1)
else:
arCards = [elmRoot]
for elmCard in arCards:
arLines = []
def processSingleString(sProperty):
sValue = self.getPropertyValue(elmCard, sProperty, self.STRING, bAutoEscape=1)
if sValue:
arLines.append(self.vcardFold(sProperty.upper() + ':' + sValue))
return sValue or ''
def processSingleURI(sProperty):
sValue = self.getPropertyValue(elmCard, sProperty, self.URI)
if sValue:
@ -1974,7 +1974,7 @@ class _MicroformatsParser:
if sContentType:
sContentType = ';TYPE=' + sContentType.upper()
arLines.append(self.vcardFold(sProperty.upper() + sEncoding + sContentType + sValueKey + ':' + sValue))
def processTypeValue(sProperty, arDefaultType, arForceType=None):
arResults = self.getPropertyValue(elmCard, sProperty, bAllowMultiple=1)
for elmResult in arResults:
@ -1986,7 +1986,7 @@ class _MicroformatsParser:
sValue = self.getPropertyValue(elmResult, 'value', self.EMAIL, 0)
if sValue:
arLines.append(self.vcardFold(sProperty.upper() + ';TYPE=' + ','.join(arType) + ':' + sValue))
# AGENT
# must do this before all other properties because it is destructive
# (removes nested class="vcard" nodes so they don't interfere with
@ -2005,10 +2005,10 @@ class _MicroformatsParser:
sAgentValue = self.getPropertyValue(elmAgent, 'value', self.URI, bAutoEscape=1);
if sAgentValue:
arLines.append(self.vcardFold('AGENT;VALUE=uri:' + sAgentValue))
# FN (full name)
sFN = processSingleString('fn')
# N (name)
elmName = self.getPropertyValue(elmCard, 'n')
if elmName:
@ -2017,7 +2017,7 @@ class _MicroformatsParser:
arAdditionalNames = self.getPropertyValue(elmName, 'additional-name', self.STRING, 1, 1) + self.getPropertyValue(elmName, 'additional-names', self.STRING, 1, 1)
arHonorificPrefixes = self.getPropertyValue(elmName, 'honorific-prefix', self.STRING, 1, 1) + self.getPropertyValue(elmName, 'honorific-prefixes', self.STRING, 1, 1)
arHonorificSuffixes = self.getPropertyValue(elmName, 'honorific-suffix', self.STRING, 1, 1) + self.getPropertyValue(elmName, 'honorific-suffixes', self.STRING, 1, 1)
arLines.append(self.vcardFold('N:' + sFamilyName + ';' +
arLines.append(self.vcardFold('N:' + sFamilyName + ';' +
sGivenName + ';' +
','.join(arAdditionalNames) + ';' +
','.join(arHonorificPrefixes) + ';' +
@ -2034,25 +2034,25 @@ class _MicroformatsParser:
arLines.append(self.vcardFold('N:' + arNames[0] + ';' + arNames[1]))
else:
arLines.append(self.vcardFold('N:' + arNames[1] + ';' + arNames[0]))
# SORT-STRING
sSortString = self.getPropertyValue(elmCard, 'sort-string', self.STRING, bAutoEscape=1)
if sSortString:
arLines.append(self.vcardFold('SORT-STRING:' + sSortString))
# NICKNAME
arNickname = self.getPropertyValue(elmCard, 'nickname', self.STRING, 1, 1)
if arNickname:
arLines.append(self.vcardFold('NICKNAME:' + ','.join(arNickname)))
# PHOTO
processSingleURI('photo')
# BDAY
dtBday = self.getPropertyValue(elmCard, 'bday', self.DATE)
if dtBday:
arLines.append(self.vcardFold('BDAY:' + self.toISO8601(dtBday)))
# ADR (address)
arAdr = self.getPropertyValue(elmCard, 'adr', bAllowMultiple=1)
for elmAdr in arAdr:
@ -2074,38 +2074,38 @@ class _MicroformatsParser:
sRegion + ';' +
sPostalCode + ';' +
sCountryName))
# LABEL
processTypeValue('label', ['intl','postal','parcel','work'])
# TEL (phone number)
processTypeValue('tel', ['voice'])
# EMAIL
processTypeValue('email', ['internet'], ['internet'])
# MAILER
processSingleString('mailer')
# TZ (timezone)
processSingleString('tz')
# GEO (geographical information)
elmGeo = self.getPropertyValue(elmCard, 'geo')
if elmGeo:
sLatitude = self.getPropertyValue(elmGeo, 'latitude', self.STRING, 0, 1)
sLongitude = self.getPropertyValue(elmGeo, 'longitude', self.STRING, 0, 1)
arLines.append(self.vcardFold('GEO:' + sLatitude + ';' + sLongitude))
# TITLE
processSingleString('title')
# ROLE
processSingleString('role')
# LOGO
processSingleURI('logo')
# ORG (organization)
elmOrg = self.getPropertyValue(elmCard, 'org')
if elmOrg:
@ -2119,39 +2119,39 @@ class _MicroformatsParser:
else:
arOrganizationUnit = self.getPropertyValue(elmOrg, 'organization-unit', self.STRING, 1, 1)
arLines.append(self.vcardFold('ORG:' + sOrganizationName + ';' + ';'.join(arOrganizationUnit)))
# CATEGORY
arCategory = self.getPropertyValue(elmCard, 'category', self.STRING, 1, 1) + self.getPropertyValue(elmCard, 'categories', self.STRING, 1, 1)
if arCategory:
arLines.append(self.vcardFold('CATEGORIES:' + ','.join(arCategory)))
# NOTE
processSingleString('note')
# REV
processSingleString('rev')
# SOUND
processSingleURI('sound')
# UID
processSingleString('uid')
# URL
processSingleURI('url')
# CLASS
processSingleString('class')
# KEY
processSingleURI('key')
if arLines:
arLines = ['BEGIN:vCard','VERSION:3.0'] + arLines + ['END:vCard']
sVCards += '\n'.join(arLines) + '\n'
return sVCards.strip()
def isProbablyDownloadable(self, elm):
attrsD = elm.attrMap
if not attrsD.has_key('href'): return 0
@ -2245,12 +2245,12 @@ class _RelativeURIResolver(_BaseHTMLProcessor):
def resolveURI(self, uri):
return _urljoin(self.baseuri, uri.strip())
def unknown_starttag(self, tag, attrs):
attrs = self.normalize_attrs(attrs)
attrs = [(key, ((tag, key) in self.relative_uris) and self.resolveURI(value) or value) for key, value in attrs]
_BaseHTMLProcessor.unknown_starttag(self, tag, attrs)
def _resolveRelativeURIs(htmlSource, baseURI, encoding, type):
if _debug: sys.stderr.write('entering _resolveRelativeURIs\n')
p = _RelativeURIResolver(baseURI, encoding, type)
@ -2350,7 +2350,7 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
'class', 'color', 'color-rendering', 'content', 'cx', 'cy', 'd', 'dx',
'dy', 'descent', 'display', 'dur', 'end', 'fill', 'fill-rule',
'font-family', 'font-size', 'font-stretch', 'font-style', 'font-variant',
'font-weight', 'from', 'fx', 'fy', 'g1', 'g2', 'glyph-name',
'font-weight', 'from', 'fx', 'fy', 'g1', 'g2', 'glyph-name',
'gradientUnits', 'hanging', 'height', 'horiz-adv-x', 'horiz-origin-x',
'id', 'ideographic', 'k', 'keyPoints', 'keySplines', 'keyTimes',
'lang', 'mathematical', 'marker-end', 'marker-mid', 'marker-start',
@ -2384,7 +2384,7 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
self.unacceptablestack = 0
self.mathmlOK = 0
self.svgOK = 0
def unknown_starttag(self, tag, attrs):
acceptable_attributes = self.acceptable_attributes
keymap = {}
@ -2435,7 +2435,7 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
clean_value = self.sanitize_style(value)
if clean_value: clean_attrs.append((key,clean_value))
_BaseHTMLProcessor.unknown_starttag(self, tag, clean_attrs)
def unknown_endtag(self, tag):
if not tag in self.acceptable_elements:
if tag in self.unacceptable_elements_with_end_tag:
@ -2553,7 +2553,7 @@ class _FeedURLHandler(urllib2.HTTPDigestAuthHandler, urllib2.HTTPRedirectHandler
http_error_300 = http_error_302
http_error_303 = http_error_302
http_error_307 = http_error_302
def http_error_401(self, req, fp, code, msg, headers):
# Check if
# - server requires digest auth, AND
@ -2672,7 +2672,7 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
return opener.open(request)
finally:
opener.close() # JohnD
# try to open with native open function (if url_file_stream_or_string is a filename)
try:
return open(url_file_stream_or_string)
@ -2686,7 +2686,7 @@ _date_handlers = []
def registerDateHandler(func):
'''Register a date handler function (takes string, returns 9-tuple date in GMT)'''
_date_handlers.insert(0, func)
# ISO-8601 date parsing routines written by Fazal Majid.
# The ISO 8601 standard is very convoluted and irregular - a full ISO 8601
# parser is beyond the scope of feedparser and would be a worthwhile addition
@ -2697,7 +2697,7 @@ def registerDateHandler(func):
# Please note the order in templates is significant because we need a
# greedy match.
_iso8601_tmpl = ['YYYY-?MM-?DD', 'YYYY-0MM?-?DD', 'YYYY-MM', 'YYYY-?OOO',
'YY-?MM-?DD', 'YY-?OOO', 'YYYY',
'YY-?MM-?DD', 'YY-?OOO', 'YYYY',
'-YY-?MM', '-OOO', '-YY',
'--MM-?DD', '--MM',
'---DD',
@ -2792,7 +2792,7 @@ def _parse_date_iso8601(dateString):
# Many implementations have bugs, but we'll pretend they don't.
return time.localtime(time.mktime(tm))
registerDateHandler(_parse_date_iso8601)
# 8-bit date handling routines written by ytrewq1.
_korean_year = u'\ub144' # b3e2 in euc-kr
_korean_month = u'\uc6d4' # bff9 in euc-kr
@ -2883,7 +2883,7 @@ _greek_wdays = \
u'\u03a4\u03b5\u03c4': u'Wed', # d4e5f4 in iso-8859-7
u'\u03a0\u03b5\u03bc': u'Thu', # d0e5ec in iso-8859-7
u'\u03a0\u03b1\u03c1': u'Fri', # d0e1f1 in iso-8859-7
u'\u03a3\u03b1\u03b2': u'Sat', # d3e1e2 in iso-8859-7
u'\u03a3\u03b1\u03b2': u'Sat', # d3e1e2 in iso-8859-7
}
_greek_date_format_re = \
@ -3069,7 +3069,7 @@ def _parse_date_rfc822(dateString):
# 'ET' is equivalent to 'EST', etc.
_additional_timezones = {'AT': -400, 'ET': -500, 'CT': -600, 'MT': -700, 'PT': -800}
rfc822._timezones.update(_additional_timezones)
registerDateHandler(_parse_date_rfc822)
registerDateHandler(_parse_date_rfc822)
def _parse_date_perforce(aDateString):
"""parse a date in yyyy/mm/dd hh:mm:ss TTT format"""
@ -3116,7 +3116,7 @@ def _getCharacterEncoding(http_headers, xml_data):
http_headers is a dictionary
xml_data is a raw string (not Unicode)
This is so much trickier than it sounds, it's not even funny.
According to RFC 3023 ('XML Media Types'), if the HTTP Content-Type
is application/xml, application/*+xml,
@ -3135,12 +3135,12 @@ def _getCharacterEncoding(http_headers, xml_data):
served with a Content-Type of text/* and no charset parameter
must be treated as us-ascii. (We now do this.) And also that it
must always be flagged as non-well-formed. (We now do this too.)
If Content-Type is unspecified (input was local file or non-HTTP source)
or unrecognized (server just got it totally wrong), then go by the
encoding given in the XML prefix of the document and default to
'iso-8859-1' as per the HTTP specification (RFC 2616).
Then, assuming we didn't find a character encoding in the HTTP headers
(and the HTTP Content-type allowed us to look in the body), we need
to sniff the first few bytes of the XML data and try to determine
@ -3246,7 +3246,7 @@ def _getCharacterEncoding(http_headers, xml_data):
else:
true_encoding = xml_encoding or 'utf-8'
return true_encoding, http_encoding, xml_encoding, sniffed_xml_encoding, acceptable_content_type
def _toUTF8(data, encoding):
'''Changes an XML data stream on the fly to specify a new encoding
@ -3309,7 +3309,7 @@ def _stripDoctype(data):
start = re.search('<\w',data)
start = start and start.start() or -1
head,data = data[:start+1], data[start+1:]
entity_pattern = re.compile(r'^\s*<!ENTITY([^>]*?)>', re.MULTILINE)
entity_results=entity_pattern.findall(head)
head = entity_pattern.sub('', head)
@ -3331,7 +3331,7 @@ def _stripDoctype(data):
data = doctype_pattern.sub(replacement, head) + data
return version, data, dict(replacement and safe_pattern.findall(replacement))
def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=[]):
'''Parse a feed from a URL, file, stream, or string'''
result = FeedParserDict()
@ -3403,7 +3403,7 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
bozo_message = 'no Content-type specified'
result['bozo'] = 1
result['bozo_exception'] = NonXMLContentType(bozo_message)
result['version'], data, entities = _stripDoctype(data)
baseuri = http_headers.get('content-location', result.get('href'))
@ -3557,7 +3557,7 @@ class TextSerializer(Serializer):
stream.write('\n')
except:
pass
class PprintSerializer(Serializer):
def write(self, stream=sys.stdout):
if self.results.has_key('href'):
@ -3565,7 +3565,7 @@ class PprintSerializer(Serializer):
from pprint import pprint
pprint(self.results, stream)
stream.write('\n')
if __name__ == '__main__':
try:
from optparse import OptionParser

View File

@ -1,9 +1,9 @@
####
# Copyright 2000,2001 by Timothy O'Malley <timo@alum.mit.edu>
#
#
# All Rights Reserved
#
#
# Permission to use, copy, modify, and distribute this software
# and its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
@ -11,8 +11,8 @@
# notice appear in supporting documentation, and that the name of
# Timothy O'Malley not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# prior permission.
#
# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
@ -20,7 +20,7 @@
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# PERFORMANCE OF THIS SOFTWARE.
#
####
@ -42,7 +42,7 @@ timeout:
The timeout applies to the socket functions that normally block on
execution: read, write, connect, and accept. If any of these
execution: read, write, connect, and accept. If any of these
operations exceeds the specified timeout, the exception Timeout
will be raised.
@ -57,7 +57,7 @@ This module implements two classes: TimeoutSocket and TimeoutFile.
The TimeoutSocket class defines a socket-like object that attempts to
avoid the condition where a socket may block indefinitely. The
TimeoutSocket class raises a Timeout exception whenever the
current operation delays too long.
current operation delays too long.
The TimeoutFile class defines a file-like object that uses the TimeoutSocket
class. When the makefile() method of TimeoutSocket is called, it returns
@ -162,7 +162,7 @@ class TimeoutSocket:
_copies = 0
_blocking = 1
def __init__(self, sock, timeout):
self._sock = sock
self._timeout = timeout
@ -193,7 +193,7 @@ class TimeoutSocket:
errcode = why[0]
return errcode
# end connect_ex
def connect(self, addr, port=None, dumbhack=None):
# In case we were called as connect(host, port)
if port != None: addr = (addr, port)
@ -212,11 +212,11 @@ class TimeoutSocket:
except Error, why:
# Set the socket's blocking mode back
sock.setblocking(blocking)
# If we are not blocking, re-raise
if not blocking:
raise
# If we are already connected, then return success.
# If we got a genuine error, re-raise it.
errcode = why[0]
@ -224,7 +224,7 @@ class TimeoutSocket:
return
elif errcode not in _ConnectBusy:
raise
# Now, wait for the connect to happen
# ONLY if dumbhack indicates this is pass number one.
# If select raises an error, we pass it on.
@ -262,12 +262,12 @@ class TimeoutSocket:
# If we are not supposed to block, then re-raise
if not blocking:
raise
# If we got a genuine error, re-raise it.
errcode = why[0]
if errcode not in _AcceptBusy:
raise
# Now, wait for the accept to happen
# ONLY if dumbhack indicates this is pass number one.
# If select raises an error, we pass it on.
@ -318,7 +318,7 @@ class TimeoutFile:
"""TimeoutFile object
Implements a file-like object on top of TimeoutSocket.
"""
def __init__(self, sock, mode="r", bufsize=4096):
self._sock = sock
self._bufsize = 4096
@ -335,7 +335,7 @@ class TimeoutFile:
self._sock.close()
self._sock = None
# end close
def write(self, data):
self.send(data)
# end write

View File

@ -127,11 +127,11 @@ class RootDirectory(Directory):
return redirect(get_publisher().get_root_url())
ident_methods = get_cfg('identification', {}).get('methods', [])
if not 'idp' in ident_methods:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
if not get_session().lasso_identity_provider_id:
get_session_manager().expire_session()
get_session_manager().expire_session()
return redirect(get_publisher().get_root_url())
# add settings to disable single logout?

View File

@ -476,7 +476,7 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
continue
if role.emails:
addresses.extend(role.emails)
if not addresses:
return