diff --git a/gluon/tools.py b/gluon/tools.py index 35f65d0a..330b375c 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -287,30 +287,29 @@ class Mail(object): self.result = {} self.error = None - def send( - self, - 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 - ): + def send(self, + 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 + ): """ Sends an email using data specified in constructor @@ -662,9 +661,9 @@ class Mail(object): msg_bio = BIO.MemoryBuffer(payload_in.as_string()) s = SMIME.SMIME() - # SIGN + # SIGN if sign: - #key for signing + # key for signing try: keyfile_bio = BIO.openfile(x509_sign_keyfile)\ if os.path.isfile(x509_sign_keyfile)\ @@ -699,7 +698,7 @@ class Mail(object): str(e), str(flags)) return False - # ENCRYPT + # ENCRYPT if encrypt: try: sk = X509.X509_Stack() @@ -725,7 +724,7 @@ class Mail(object): self.error = "Something went wrong on encrypting: <%s>" % str(e) return False - # Final stage in sign and encryption + # Final stage in sign and encryption out = BIO.MemoryBuffer() if encrypt: s.write(out, p7) @@ -796,7 +795,7 @@ class Mail(object): subject=subject, body=text, **xcc) else: smtp_args = self.settings.server.split(':') - kwargs = dict(timeout = self.settings.timeout) + kwargs = dict(timeout=self.settings.timeout) if self.settings.ssl: server = smtplib.SMTP_SSL(*smtp_args, **kwargs) else: @@ -839,18 +838,17 @@ class Recaptcha(DIV): API_SERVER = 'http://www.google.com/recaptcha/api' VERIFY_SERVER = 'http://www.google.com/recaptcha/api/verify' - def __init__( - self, - request=None, - public_key='', - private_key='', - use_ssl=False, - error=None, - error_message='invalid', - label='Verify:', - options='', - comment = '', - ajax=False + def __init__(self, + request=None, + public_key='', + private_key='', + use_ssl=False, + error=None, + error_message='invalid', + label='Verify:', + options='', + comment='', + ajax=False ): request = request or current.request self.request_vars = request and request.vars or current.request.vars @@ -942,7 +940,7 @@ class Recaptcha(DIV): jQuery.getScript('%(url)s',function() { Recaptcha.create('%(public_key)s', 'recaptcha',jQuery.extend(RecaptchaOptions,{'callback':Recaptcha.focus_response_field})) - }) """ % ({'options':RecaptchaOptions,'url':url_recaptcha_js,'public_key':public_key}) + }) """ % ({'options': RecaptchaOptions, 'url': url_recaptcha_js, 'public_key': public_key}) captcha = DIV( SCRIPT( script, @@ -963,6 +961,7 @@ class Recaptcha(DIV): captcha.append(DIV(self.errors['captcha'], _class='error')) return XML(captcha).xml() + # this should only be used for catcha and perhaps not even for that def addrow(form, a, b, c, style, _id, position=-1): if style == "divs": @@ -1050,14 +1049,14 @@ class Auth(object): profile_fields=None, email_case_sensitive=True, username_case_sensitive=True, - update_fields = ['email'], + update_fields=['email'], ondelete="CASCADE", - client_side = True, + client_side=True, renew_session_onlogin=True, renew_session_onlogout=True, keep_session_onlogin=True, keep_session_onlogout=False, - wiki = Settings(), + wiki=Settings(), ) # ## these are messages that can be customized default_messages = dict( @@ -1099,8 +1098,7 @@ class Auth(object): retrieve_username_subject='Username retrieve', retrieve_password='Your password is: %(password)s', retrieve_password_subject='Password retrieve', - reset_password= - 'Click on the link %(link)s to reset your password', + reset_password='Click on the link %(link)s to reset your password', reset_password_subject='Password reset', invalid_reset_password='Invalid reset password', profile_updated='Profile updated', @@ -1263,7 +1261,7 @@ class Auth(object): f=f, args=args, vars=vars, scheme=scheme) def here(self): - return URL(args=current.request.args,vars=current.request.get_vars) + return URL(args=current.request.args, vars=current.request.get_vars) def __init__(self, environment=None, db=None, mailer=True, hmac_key=None, controller='default', function='user', @@ -1365,14 +1363,15 @@ class Auth(object): # ## these are messages that can be customized messages = self.messages = Messages(current.T) messages.update(Auth.default_messages) - messages.update(ajax_failed_authentication=DIV(H4('NOT AUTHORIZED'), - 'Please ', - A('login', - _href=self.settings.login_url + - ('?_next=' + urllib.quote(current.request.env.http_web2py_component_location)) - if current.request.env.http_web2py_component_location else ''), - ' to view this content.', - _class='not-authorized alert alert-block')) + messages.update(ajax_failed_authentication= + DIV(H4('NOT AUTHORIZED'), + 'Please ', + A('login', + _href=self.settings.login_url + + ('?_next=' + urllib.quote(current.request.env.http_web2py_component_location)) + if current.request.env.http_web2py_component_location else ''), + ' to view this content.', + _class='not-authorized alert alert-block')) messages.lock_keys = True # for "remember me" option @@ -1392,7 +1391,7 @@ class Auth(object): return next def _get_user_id(self): - "accessor for auth.user_id" + """accessor for auth.user_id""" return self.user and self.user.id or None user_id = property(_get_user_id, doc="user.id or None") @@ -1545,10 +1544,10 @@ class Auth(object): self.bar[0][3].append((item['name'], False, item['href'])) def bootstrap3(): # Default web2py scaffolding - def rename(icon): return icon+' '+icon.replace('icon','glyphicon') + def rename(icon): return icon+' '+icon.replace('icon', 'glyphicon') self.bar = UL(LI(Anr(I(_class=rename('icon '+items[0]['icon'])), ' ' + items[0]['name'], - _href=items[0]['href'])),_class='dropdown-menu') + _href=items[0]['href'])), _class='dropdown-menu') del items[0] for item in items: self.bar.insert(-1, LI(Anr(I(_class=rename('icon '+item['icon'])), @@ -1557,13 +1556,13 @@ class Auth(object): self.bar.insert(-1, LI('', _class='divider')) if self.user_id: self.bar = LI(Anr(prefix, user_identifier, - _href='#',_class="dropdown-toggle", - data={'toggle':'dropdown'}), - self.bar,_class='dropdown') + _href='#', _class="dropdown-toggle", + data={'toggle': 'dropdown'}), + self.bar, _class='dropdown') else: self.bar = LI(Anr(T('Log In'), - _href='#',_class="dropdown-toggle", - data={'toggle':'dropdown'}), self.bar, + _href='#', _class="dropdown-toggle", + data={'toggle': 'dropdown'}), self.bar, _class='dropdown') def bare(): @@ -1714,7 +1713,7 @@ class Auth(object): """ current_record_label = current_record_label or current.T( - current_record.replace('_',' ').title()) + current_record.replace('_', ' ').title()) for table in tables: fieldnames = table.fields() if ('id' in fieldnames and @@ -1787,8 +1786,10 @@ class Auth(object): """ db = self.db - if migrate is None: migrate = db._migrate - if fake_migrate is None: fake_migrate = db._fake_migrate + if migrate is None: + migrate = db._migrate + if fake_migrate is None: + fake_migrate = db._fake_migrate settings = self.settings if username is None: username = settings.use_username @@ -1895,8 +1896,7 @@ class Auth(object): settings.table_group_name, Field('role', length=512, default='', label=self.messages.label_role, - requires=IS_NOT_IN_DB( - db, '%s.role' % settings.table_group_name)), + requires=IS_NOT_IN_DB(db, '%s.role' % settings.table_group_name)), Field('description', 'text', label=self.messages.label_description), *extra_fields, @@ -2116,8 +2116,7 @@ class Auth(object): basic_realm = unicode(basic_auth_realm) elif basic_auth_realm is True: basic_realm = u'' + current.request.application - http_401 = HTTP(401, u'Not Authorized', - **{'WWW-Authenticate': u'Basic realm="' + basic_realm + '"'}) + http_401 = HTTP(401, u'Not Authorized', **{'WWW-Authenticate': u'Basic realm="' + basic_realm + '"'}) if not basic or not basic[:6].lower() == 'basic ': if basic_auth_realm: raise http_401 @@ -2135,19 +2134,18 @@ class Auth(object): from gluon.settings import global_settings if global_settings.web2py_runtime_gae: user = Row(self.table_user()._filter_fields(user, id=True)) - delattr(user,'password') + delattr(user, 'password') else: user = Row(user) for key, value in user.items(): - if callable(value) or key=='password': - delattr(user,key) + if callable(value) or key == 'password': + delattr(user, key) if self.settings.renew_session_onlogin: current.session.renew(clear_session=not self.settings.keep_session_onlogin) - current.session.auth = Storage( - user = user, - last_visit=current.request.now, - expiration=self.settings.expiration, - hmac_key=web2py_uuid()) + current.session.auth = Storage(user=user, + last_visit=current.request.now, + expiration=self.settings.expiration, + hmac_key=web2py_uuid()) self.user = user self.update_groups() @@ -2178,8 +2176,7 @@ class Auth(object): else: # user not in database try other login methods for login_method in self.settings.login_methods: - if login_method != self and \ - login_method(username, password): + if login_method != self and login_method(username, password): self.user = username return username return False @@ -2196,26 +2193,20 @@ class Auth(object): elif not fields.get(settings.userfield): raise ValueError("register_bare: " + "userfield not provided or invalid") - fields[settings.passfield] = \ - settings.table_user[settings.passfield].validate( - fields[settings.passfield])[0] - user = self.get_or_create_user( - fields, login=False, get=False, - update_fields=self.settings.update_fields) + fields[settings.passfield] = settings.table_user[settings.passfield].validate(fields[settings.passfield])[0] + user = self.get_or_create_user(fields, login=False, get=False, update_fields=self.settings.update_fields) if not user: # get or create did not create a user (it ignores duplicate records) return False return user - - def cas_login( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - version=2, - ): + def cas_login(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + version=2, + ): request = current.request response = current.response session = current.session @@ -2303,23 +2294,22 @@ class Auth(object): raise HTTP(200, message) def _reset_two_factor_auth(self, session): - '''When two-step authentication is enabled, this function is used to + """When two-step authentication is enabled, this function is used to clear the session after successfully completing second challenge or when the maximum number of tries allowed has expired. - ''' + """ session.auth_two_factor_user = None session.auth_two_factor = None session.auth_two_factor_enabled = False # Allow up to 4 attempts (the 1st one plus 3 more) session.auth_two_factor_tries_left = 3 - def login( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def login(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a login form """ @@ -2424,7 +2414,7 @@ class Auth(object): if settings.remember_me_form: extra_fields = [ - Field('remember_me','boolean',default=False, + Field('remember_me', 'boolean', default=False, label = self.messages.label_remember_me)] else: extra_fields = [] @@ -2549,7 +2539,7 @@ class Auth(object): # auth.settings.two_factor_authentication_group if user and self.settings.two_factor_authentication_group: role = self.settings.two_factor_authentication_group - session.auth_two_factor_enabled = self.has_membership(user_id=user.id,role=role) + session.auth_two_factor_enabled = self.has_membership(user_id=user.id, role=role) # challenge if session.auth_two_factor_enabled: form = SQLFORM.factory( @@ -2673,13 +2663,12 @@ class Auth(object): if not next is None: redirect(next) - def register( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def register(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a registration form """ @@ -2728,7 +2717,7 @@ class Auth(object): if self.settings.register_verify_password: extra_fields = [ Field("password_two", "password", requires=IS_EQUAL_TO( - request.post_vars.get(passfield,None), + request.post_vars.get(passfield, None), error_message=self.messages.mismatched_password), label=current.T("Confirm Password"))] else: @@ -2772,7 +2761,7 @@ class Auth(object): link = self.url( self.settings.function, args=('verify_email', key), scheme=True) d = dict(form.vars) - d.update(dict(key=key, link=link,username=form.vars[username])) + d.update(dict(key=key, link=link, username=form.vars[username])) if not (self.settings.mailer and self.settings.mailer.send( to=form.vars.email, subject=self.messages.verify_email_subject, @@ -2813,12 +2802,11 @@ class Auth(object): return True return False - def verify_email( - self, - next=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def verify_email(self, + next=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Action used to verify the registration email """ @@ -2847,13 +2835,12 @@ class Auth(object): callback(onaccept, user) redirect(next) - def retrieve_username( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def retrieve_username(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a form to retrieve the user username (only if there is a username field) @@ -2904,9 +2891,8 @@ class Auth(object): redirect(self.url(args=request.args)) username = ', '.join(u.username for u in users) self.settings.mailer.send(to=form.vars.email, - subject=self.messages.retrieve_username_subject, - message=self.messages.retrieve_username - % dict(username=username)) + subject=self.messages.retrieve_username_subject, + message=self.messages.retrieve_username % dict(username=username)) session.flash = self.messages.email_sent for user in users: self.log_event(log, user) @@ -2931,13 +2917,12 @@ class Auth(object): password += random.choice(specials) return ''.join(random.sample(password, len(password))) - def reset_password_deprecated( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def reset_password_deprecated(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a form to reset the user password (deprecated) """ @@ -2990,9 +2975,8 @@ class Auth(object): user.update_record(**d) if self.settings.mailer and \ self.settings.mailer.send(to=form.vars.email, - subject=self.messages.retrieve_password_subject, - message=self.messages.retrieve_password - % dict(password=password)): + subject=self.messages.retrieve_password_subject, + message=self.messages.retrieve_password % dict(password=password)): session.flash = self.messages.email_sent else: session.flash = self.messages.unable_to_send_email @@ -3006,13 +2990,12 @@ class Auth(object): table_user.email.requires = old_requires return form - def reset_password( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def reset_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a form to reset the user password """ @@ -3071,13 +3054,12 @@ class Auth(object): redirect(next, client_side=self.settings.client_side) return form - def request_reset_password( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def request_reset_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a form to reset the user password """ @@ -3101,7 +3083,7 @@ class Auth(object): log = self.messages['reset_password_log'] userfield = self.settings.login_userfield or 'username' \ if 'username' in table_user.fields else 'email' - if userfield=='email': + if userfield == 'email': table_user.email.requires = [ IS_EMAIL(error_message=self.messages.invalid_email), IS_IN_DB(self.db, table_user.email, @@ -3169,25 +3151,23 @@ class Auth(object): return True return False - def retrieve_password( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def retrieve_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): if self.settings.reset_password_requires_verification: return self.request_reset_password(next, onvalidation, onaccept, log) else: return self.reset_password_deprecated(next, onvalidation, onaccept, log) - def change_password( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def change_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a form that lets the user change password """ @@ -3211,9 +3191,9 @@ class Auth(object): log = self.messages['change_password_log'] passfield = self.settings.password_field requires = table_user[passfield].requires - if not isinstance(requires,(list, tuple)): + if not isinstance(requires, (list, tuple)): requires = [requires] - requires = filter(lambda t:isinstance(t,CRYPT), requires) + requires = filter(lambda t: isinstance(t, CRYPT), requires) if requires: requires[0].min_length = 0 form = SQLFORM.factory( @@ -3237,7 +3217,7 @@ class Auth(object): onvalidation=onvalidation, hideerror=self.settings.hideerror): - current_user = s.select(limitby=(0,1), orderby_on_limitby=False).first() + current_user = s.select(limitby=(0, 1), orderby_on_limitby=False).first() if not form.vars['old_password'] == current_user[passfield]: form.errors['old_password'] = self.messages.invalid_password else: @@ -3253,13 +3233,12 @@ class Auth(object): redirect(next, client_side=self.settings.client_side) return form - def profile( - self, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - ): + def profile(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): """ Returns a form that lets the user change his/her profile """ @@ -3311,13 +3290,13 @@ class Auth(object): return form def run_login_onaccept(self): - onaccept = self.settings.login_onaccept - if onaccept: - form = Storage(dict(vars=self.user)) - if not isinstance(onaccept,(list, tuple)): - onaccept = [onaccept] - for callback in onaccept: - callback(form) + onaccept = self.settings.login_onaccept + if onaccept: + form = Storage(dict(vars=self.user)) + if not isinstance(onaccept, (list, tuple)): + onaccept = [onaccept] + for callback in onaccept: + callback(form) def is_impersonating(self): return self.is_logged_in() and 'impersonator' in current.session.auth @@ -3615,14 +3594,13 @@ class Auth(object): if group_id in self.user_groups: del self.user_groups[group_id] return ret - def has_permission( - self, - name='any', - table_name='', - record_id=0, - user_id=None, - group_id=None, - ): + def has_permission(self, + name='any', + table_name='', + record_id=0, + user_id=None, + group_id=None, + ): """ Checks if user_id or current logged in user is member of a group that has 'name' permission on 'table_name' and 'record_id' @@ -3668,13 +3646,12 @@ class Auth(object): table_name=table_name, record_id=record_id)) return r - def add_permission( - self, - group_id, - name='any', - table_name='', - record_id=0, - ): + def add_permission(self, + group_id, + name='any', + table_name='', + record_id=0, + ): """ Gives group_id 'name' access to 'table_name' and 'record_id' """ @@ -3683,7 +3660,7 @@ class Auth(object): if group_id == 0: group_id = self.user_group() record = self.db(permission.group_id == group_id)(permission.name == name)(permission.table_name == str(table_name))( - permission.record_id == long(record_id)).select(limitby=(0,1), orderby_on_limitby=False).first() + permission.record_id == long(record_id)).select(limitby=(0, 1), orderby_on_limitby=False).first() if record: id = record.id else: @@ -3696,13 +3673,12 @@ class Auth(object): record_id=record_id)) return id - def del_permission( - self, - group_id, - name='any', - table_name='', - record_id=0, - ): + def del_permission(self, + group_id, + name='any', + table_name='', + record_id=0, + ): """ Revokes group_id 'name' access to 'table_name' and 'record_id' """ @@ -3862,7 +3838,8 @@ class Auth(object): force_render=False, groups=None): - if controller and function: resolve = False + if controller and function: + resolve = False if not hasattr(self, '_wiki'): self._wiki = Wiki(self, render=render, @@ -3885,7 +3862,7 @@ class Auth(object): if resolve: if slug: wiki = self._wiki.read(slug, force_render) - if isinstance(wiki, dict) and wiki.has_key('content'): + if isinstance(wiki, dict) and wiki.has_key('content'): # FIXME: .has_key() is deprecated # We don't want to return a dict object, just the wiki wiki = wiki['content'] else: @@ -4006,27 +3983,26 @@ class Crud(object): def tables(self): return TABLE(*[TR(A(name, _href=self.url(args=('select', name)))) - for name in self.db.tables]) + for name in self.db.tables]) @staticmethod def archive(form, archive_table=None, current_record='current_record'): return Auth.archive(form, archive_table=archive_table, current_record=current_record) - def update( - self, - table, - record, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - ondelete=DEFAULT, - log=DEFAULT, - message=DEFAULT, - deletable=DEFAULT, - formname=DEFAULT, - **attributes - ): + def update(self, + table, + record, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + ondelete=DEFAULT, + log=DEFAULT, + message=DEFAULT, + deletable=DEFAULT, + formname=DEFAULT, + **attributes + ): if not (isinstance(table, Table) or table in self.db.tables) \ or (isinstance(record, str) and not str(record).isdigit()): raise HTTP(404) @@ -4075,7 +4051,7 @@ class Crud(object): upload=self.settings.download_url, formstyle=self.settings.formstyle, separator=self.settings.label_separator, - **attributes # contains hidden + **attributes # contains hidden ) self.accepted = False self.deleted = False @@ -4125,17 +4101,16 @@ class Crud(object): raise HTTP(401, serializers.json(dict(errors=form.errors))) return form - def create( - self, - table, - next=DEFAULT, - onvalidation=DEFAULT, - onaccept=DEFAULT, - log=DEFAULT, - message=DEFAULT, - formname=DEFAULT, - **attributes - ): + def create(self, + table, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + message=DEFAULT, + formname=DEFAULT, + **attributes + ): if next is DEFAULT: next = self.settings.create_next @@ -4182,13 +4157,12 @@ class Crud(object): return table._filter_fields(form.record, id=True) return form - def delete( - self, - table, - record_id, - next=DEFAULT, - message=DEFAULT, - ): + def delete(self, + table, + record_id, + next=DEFAULT, + message=DEFAULT, + ): if not (isinstance(table, Table) or table in self.db.tables): raise HTTP(404) if not isinstance(table, Table): @@ -4237,16 +4211,15 @@ class Crud(object): limitby=limitby)) return rows - def select( - self, - table, - query=None, - fields=None, - orderby=None, - limitby=None, - headers=None, - **attr - ): + def select(self, + table, + query=None, + fields=None, + orderby=None, + limitby=None, + headers=None, + **attr + ): headers = headers or {} rows = self.rows(table, query, fields, orderby, limitby) if not rows: @@ -4329,7 +4302,7 @@ class Crud(object): """ table = tables[0] fields = args.get('fields', table.fields) - validate = args.get('validate',True) + validate = args.get('validate', True) request = current.request db = self.db if not (isinstance(table, Table) or table in db.tables): @@ -4382,8 +4355,7 @@ class Crud(object): if request.post_vars and (chkval or field.type == 'id'): if txtval and opval != '': if field.type[0:10] == 'reference ': - refsearch.append(self.get_query(field, - opval, txtval, refsearch=True)) + refsearch.append(self.get_query(field, opval, txtval, refsearch=True)) elif validate: value, error = field.validate(txtval) if not error: @@ -4477,8 +4449,7 @@ def universal_caller(f, *a, **b): # Fill the arg_dict with name and value for the submitted, positional values for pos_index, pos_val in enumerate(a[:c]): - arg_dict[n[pos_index] - ] = pos_val # n[pos_index] is the name of the argument + arg_dict[n[pos_index]] = pos_val # n[pos_index] is the name of the argument # There might be pos_args left, that are sent as named_values. Gather them as well. # If a argument already is populated with values we simply replaces them. @@ -4856,7 +4827,6 @@ class Service(object): -32603: ("Internal error", "Internal JSON-RPC error."), -32099: ("Server error", "Reserved for implementation-defined server-errors.")} - def serve_jsonrpc(self): def return_response(id, result): return serializers.json({'version': '1.1', @@ -4886,7 +4856,7 @@ class Service(object): if not method in methods: return return_error(id, 100, 'method "%s" does not exist' % method) try: - if isinstance(params,dict): + if isinstance(params, dict): s = methods[method](**params) else: s = methods[method](*params) @@ -4952,15 +4922,13 @@ class Service(object): return True - - request = current.request response = current.response if not data: response.headers['Content-Type'] = 'application/json; charset=utf-8' try: data = json_parser.loads(request.body.read()) - except ValueError: # decoding error in json lib + except ValueError: # decoding error in json lib return return_error(None, -32700) # Batch handling @@ -4968,9 +4936,9 @@ class Service(object): retlist = [] for c in data: retstr = self.serve_jsonrpc2(c, batch_element=True) - if retstr: # do not add empty responses + if retstr: # do not add empty responses retlist.append(retstr) - if len(retlist) == 0: # return nothing + if len(retlist) == 0: # return nothing return '' else: return "[" + ','.join(retlist) + "]" @@ -4986,7 +4954,7 @@ class Service(object): if not method in methods: return return_error(id, -32601, data='Method "%s" does not exist' % method) try: - if isinstance(params,dict): + if isinstance(params, dict): s = methods[method](**params) else: s = methods[method](*params) @@ -5006,7 +4974,6 @@ class Service(object): logger.warning('%s: %s\n%s' % (etype.__name__, eval, traceback.format_tb(etb))) return return_error(id, -32099, data=data) - def serve_xmlrpc(self): request = current.request response = current.response @@ -5407,7 +5374,7 @@ class Expose(object): self.filenames = [f[len(path) - 1:] for f in sorted(glob.glob(path)) if not os.path.isdir(f) and not self.isprivate(f)] if 'README' in self.filenames: - readme = open(os.path.join(filename,'README')).read() + readme = open(os.path.join(filename, 'README')).read() self.paragraph = MARKMIN(readme) else: self.paragraph = None @@ -5464,7 +5431,8 @@ class Expose(object): class Wiki(object): everybody = 'everybody' rows_page = 25 - def markmin_base(self,body): + + def markmin_base(self, body): return MARKMIN(body, extra=self.settings.extra, url=True, environment=self.env, autolinks=lambda link: expand_one(link, {})).xml() @@ -5576,7 +5544,7 @@ class Wiki(object): table_definitions = [ ('wiki_page', { - 'args':[ + 'args': [ Field('slug', requires=[IS_SLUG(), IS_NOT_IN_DB(db, 'wiki_page.slug')], @@ -5601,20 +5569,20 @@ class Wiki(object): requires=IS_EMPTY_OR( IS_IN_SET(engines))), auth.signature], - 'vars':{'format':'%(title)s', 'migrate':migrate}}), + 'vars': {'format': '%(title)s', 'migrate': migrate}}), ('wiki_tag', { - 'args':[ + 'args': [ Field('name'), Field('wiki_page', 'reference wiki_page'), auth.signature], - 'vars':{'format':'%(title)s', 'migrate':migrate}}), + 'vars':{'format': '%(title)s', 'migrate': migrate}}), ('wiki_media', { - 'args':[ + 'args': [ Field('wiki_page', 'reference wiki_page'), Field('title', required=True), Field('filename', 'upload', required=True), auth.signature], - 'vars':{'format':'%(title)s', 'migrate':migrate}}), + 'vars': {'format': '%(title)s', 'migrate': migrate}}), ] # define only non-existent tables @@ -5633,7 +5601,7 @@ class Wiki(object): if self.settings.templates is None and not \ self.settings.manage_permissions: - self.settings.templates = db.wiki_page.tags.contains('template')&\ + self.settings.templates = db.wiki_page.tags.contains('template') & \ db.wiki_page.can_read.contains('everybody') def update_tags_insert(page, id, db=db): @@ -5643,7 +5611,7 @@ class Wiki(object): db.wiki_tag.insert(name=tag, wiki_page=id) def update_tags_update(dbset, page, db=db): - page = dbset.select(limitby=(0,1)).first() + page = dbset.select(limitby=(0, 1)).first() db(db.wiki_tag.wiki_page == page.id).delete() for tag in page.tags or []: tag = tag.strip().lower() @@ -5733,7 +5701,7 @@ class Wiki(object): elif not zero or not zero.startswith('_'): return self.read(zero) elif zero == '_edit': - return self.edit(request.args(1) or 'index',request.args(2) or 0) + return self.edit(request.args(1) or 'index', request.args(2) or 0) elif zero == '_editmedia': return self.editmedia(request.args(1) or 'index') elif zero == '_create': @@ -5804,7 +5772,7 @@ class Wiki(object): created_on=page.created_on, modified_on=page.modified_on) - def edit(self,slug,from_template=0): + def edit(self, slug, from_template=0): auth = self.auth db = auth.db page = db.wiki_page(slug=slug) @@ -5825,7 +5793,8 @@ class Wiki(object): db.wiki_page.body.default = \ '- Menu Item > @////index\n- - Submenu > http://web2py.com' else: - db.wiki_page.body.default = db(db.wiki_page.id==from_template).select(db.wiki_page.body)[0].body if int(from_template) > 0 else '## %s\n\npage content' % title_guess + db.wiki_page.body.default = db(db.wiki_page.id == from_template).select(db.wiki_page.body)[0].body \ + if int(from_template) > 0 else '## %s\n\npage content' % title_guess vars = current.request.post_vars if vars.body: vars.body = vars.body.replace('://%s' % self.host, '://HOSTNAME') @@ -5880,9 +5849,9 @@ class Wiki(object): } }) }) - """ % dict(url=URL(args=('_preview', slug)),link_media=('true' if page else 'false'), + """ % dict(url=URL(args=('_preview', slug)), link_media=('true' if page else 'false'), urlmedia=URL(extension='load', - args=('_editmedia',slug), + args=('_editmedia', slug), vars=dict(embedded=1))) return dict(content=TAG[''](form, SCRIPT(script))) @@ -5894,9 +5863,7 @@ class Wiki(object): return self.not_authorized(page) self.auth.db.wiki_media.id.represent = lambda id, row: \ id if not row.filename else \ - SPAN('@////%i/%s.%s' % - (id, IS_SLUG.urlify(row.title.split('.')[0]), - row.filename.split('.')[-1])) + SPAN('@////%i/%s.%s' % (id, IS_SLUG.urlify(row.title.split('.')[0]), row.filename.split('.')[-1])) self.auth.db.wiki_media.wiki_page.default = page.id self.auth.db.wiki_media.wiki_page.writable = False links = [] @@ -5907,16 +5874,16 @@ class Wiki(object): fragment = self.auth.db.wiki_media.id.represent csv = False create = False - links=[ + links= [ lambda row: A('copy into source', _href='#', _onclick=script % (fragment(row.id, row))) ] content = SQLFORM.grid( self.auth.db.wiki_media.wiki_page == page.id, orderby=self.auth.db.wiki_media.title, - links = links, - csv = csv, - create = create, + links=links, + csv=csv, + create=create, args=['_editmedia', slug], user_signature=False) return dict(content=content) @@ -5925,12 +5892,12 @@ class Wiki(object): if not self.can_edit(): return self.not_authorized() db = self.auth.db - slugs=db(db.wiki_page.id>0).select(db.wiki_page.id,db.wiki_page.slug) - options=[OPTION(row.slug,_value=row.id) for row in slugs] - options.insert(0, OPTION('',_value='')) + slugs = db(db.wiki_page.id > 0).select(db.wiki_page.id, db.wiki_page.slug) + options = [OPTION(row.slug, _value=row.id) for row in slugs] + options.insert(0, OPTION('', _value='')) fields = [Field("slug", default=current.request.args(1) or self.settings.force_prefix, - requires=(IS_SLUG(), IS_NOT_IN_DB(db,db.wiki_page.slug))),] + requires=(IS_SLUG(), IS_NOT_IN_DB(db, db.wiki_page.slug))),] if self.settings.templates: fields.append( Field("from_template", "reference wiki_page", @@ -5947,7 +5914,7 @@ class Wiki(object): if form.process().accepted: form.vars.from_template = 0 if not form.vars.from_template \ else form.vars.from_template - redirect(URL(args=('_edit', form.vars.slug,form.vars.from_template or 0))) # added param + redirect(URL(args=('_edit', form.vars.slug, form.vars.from_template or 0))) # added param return dict(content=form) def pages(self): @@ -5960,14 +5927,14 @@ class Wiki(object): wiki_table = self.auth.db.wiki_page content = SQLFORM.grid( wiki_table, - fields = [wiki_table.slug, - wiki_table.title, wiki_table.tags, - wiki_table.can_read, wiki_table.can_edit], + fields=[wiki_table.slug, + wiki_table.title, wiki_table.tags, + wiki_table.can_read, wiki_table.can_edit], links=[ lambda row: - A('edit', _href=URL(args=('_edit', row.slug)),_class='btn'), + A('edit', _href=URL(args=('_edit', row.slug)), _class='btn'), lambda row: - A('media', _href=URL(args=('_editmedia', row.slug)),_class='btn')], + A('media', _href=URL(args=('_editmedia', row.slug)), _class='btn')], details=False, editable=False, deletable=False, create=False, orderby=self.auth.db.wiki_page.title, args=['_pages'], @@ -5985,7 +5952,7 @@ class Wiki(object): return self.not_authorized(page) request.args = [media.filename] m = response.download(request, db) - current.session.forget() # get rid of the cookie + current.session.forget() # get rid of the cookie response.headers['Last-Modified'] = \ request.utcnow.strftime("%a, %d %b %Y %H:%M:%S GMT") if 'Content-Disposition' in response.headers: @@ -6089,10 +6056,10 @@ class Wiki(object): if self.settings.restrict_search and not self.manage(): query = query & (db.wiki_page.created_by == self.auth.user_id) pages = db(query).select(count, - *fields, **dict(orderby=orderby or ~count, - groupby=reduce(lambda a, b: a | b, fields), - distinct=True, - limitby=limitby)) + *fields, **dict(orderby=orderby or ~count, + groupby=reduce(lambda a, b: a | b, fields), + distinct=True, + limitby=limitby)) if request.extension in ('html', 'load'): if not pages: content.append(DIV(current.T("No results"), @@ -6151,6 +6118,7 @@ class Wiki(object): request.post_vars.render = None return render(request.post_vars) + class Config(object): def __init__( self, @@ -6166,7 +6134,7 @@ class Config(object): self.filename = filename def read(self): - if not( isinstance(current.session['settings_%s' % self.section], dict) ): + if not(isinstance(current.session['settings_%s' % self.section], dict)): settings = dict(self.config.items(self.section)) else: settings = current.session['settings_%s' % self.section] diff --git a/gluon/utils.py b/gluon/utils.py index e18edb8d..4df0cbc3 100644 --- a/gluon/utils.py +++ b/gluon/utils.py @@ -66,6 +66,7 @@ else: logger = logging.getLogger("web2py") + def AES_new(key, IV=None): """ Returns an AES cipher object and random IV if None specified """ if IV is None: @@ -88,6 +89,7 @@ def md5_hash(text): """ Generates a md5 hash with the given text """ return md5(text).hexdigest() + def simple_hash(text, key='', salt='', digest_alg='md5'): """ Generates hash with the given text using the specified diff --git a/gluon/validators.py b/gluon/validators.py index ec8b8224..d94f365d 100644 --- a/gluon/validators.py +++ b/gluon/validators.py @@ -190,9 +190,9 @@ class IS_MATCH(Validator): if not expression.endswith('$'): expression = '(%s)$' % expression if is_unicode: - if not isinstance(expression,unicode): + if not isinstance(expression, unicode): expression = expression.decode('utf8') - self.regex = re.compile(expression,re.UNICODE) + self.regex = re.compile(expression, re.UNICODE) else: self.regex = re.compile(expression) self.error_message = error_message @@ -200,7 +200,7 @@ class IS_MATCH(Validator): self.is_unicode = is_unicode def __call__(self, value): - if self.is_unicode and not isinstance(value,unicode): + if self.is_unicode and not isinstance(value, unicode): match = self.regex.search(str(value).decode('utf8')) else: match = self.regex.search(str(value)) @@ -348,6 +348,7 @@ class IS_LENGTH(Validator): return (value, translate(self.error_message) % dict(min=self.minsize, max=self.maxsize)) + class IS_JSON(Validator): """ Example: @@ -377,7 +378,7 @@ class IS_JSON(Validator): except JSONErrors: return (value, translate(self.error_message)) - def formatter(self,value): + def formatter(self, value): if value is None: return None if self.native_json: @@ -669,7 +670,7 @@ class IS_NOT_IN_DB(Validator): self.record_id = id def __call__(self, value): - if isinstance(value,unicode): + if isinstance(value, unicode): value = value.encode('utf8') else: value = str(value) @@ -696,7 +697,7 @@ class IS_NOT_IN_DB(Validator): def range_error_message(error_message, what_to_enter, minimum, maximum): - "build the error message for the number range validators" + """build the error message for the number range validators""" if error_message is None: error_message = 'Enter ' + what_to_enter if minimum is not None and maximum is not None: @@ -938,7 +939,7 @@ class IS_DECIMAL_IN_RANGE(Validator): def is_empty(value, empty_regex=None): - "test empty field" + """test empty field""" if isinstance(value, (str, unicode)): value = value.strip() if empty_regex is not None and empty_regex.match(value): @@ -1153,6 +1154,7 @@ class IS_EMAIL(Validator): return (value, None) return (value, translate(self.error_message)) + class IS_LIST_OF_EMAILS(object): """ Example: @@ -1166,7 +1168,8 @@ class IS_LIST_OF_EMAILS(object): ) """ split_emails = re.compile('[^,;\s]+') - def __init__(self, error_message = 'Invalid emails: %s'): + + def __init__(self, error_message='Invalid emails: %s'): self.error_message = error_message def __call__(self, value): @@ -1182,7 +1185,7 @@ class IS_LIST_OF_EMAILS(object): return (value, translate(self.error_message) % ', '.join(bad_emails)) - def formatter(self,value,row=None): + def formatter(self, value, row=None): return ', '.join(value or []) @@ -1334,7 +1337,7 @@ label_split_regex = re.compile(u'[\u002e\u3002\uff0e\uff61]') def escape_unicode(string): - ''' + """ Converts a unicode string into US-ASCII, using a simple conversion scheme. Each unicode character that does not have a US-ASCII equivalent is converted into a URL escaped form based on its hexadecimal value. @@ -1348,7 +1351,7 @@ def escape_unicode(string): string: the US-ASCII escaped form of the inputted string @author: Jonathan Benn - ''' + """ returnValue = StringIO() for character in string: @@ -1363,7 +1366,7 @@ def escape_unicode(string): def unicode_to_ascii_authority(authority): - ''' + """ Follows the steps in RFC 3490, Section 4 to convert a unicode authority string into its ASCII equivalent. For example, u'www.Alliancefran\xe7aise.nu' will be converted into @@ -1382,19 +1385,19 @@ def unicode_to_ascii_authority(authority): authority @author: Jonathan Benn - ''' - #RFC 3490, Section 4, Step 1 - #The encodings.idna Python module assumes that AllowUnassigned == True + """ + # RFC 3490, Section 4, Step 1 + # The encodings.idna Python module assumes that AllowUnassigned == True - #RFC 3490, Section 4, Step 2 + # RFC 3490, Section 4, Step 2 labels = label_split_regex.split(authority) - #RFC 3490, Section 4, Step 3 - #The encodings.idna Python module assumes that UseSTD3ASCIIRules == False + # RFC 3490, Section 4, Step 3 + # The encodings.idna Python module assumes that UseSTD3ASCIIRules == False - #RFC 3490, Section 4, Step 4 - #We use the ToASCII operation because we are about to put the authority - #into an IDN-unaware slot + # RFC 3490, Section 4, Step 4 + # We use the ToASCII operation because we are about to put the authority + # into an IDN-unaware slot asciiLabels = [] try: import encodings.idna @@ -1402,18 +1405,18 @@ def unicode_to_ascii_authority(authority): if label: asciiLabels.append(encodings.idna.ToASCII(label)) else: - #encodings.idna.ToASCII does not accept an empty string, but - #it is necessary for us to allow for empty labels so that we - #don't modify the URL + # encodings.idna.ToASCII does not accept an empty string, but + # it is necessary for us to allow for empty labels so that we + # don't modify the URL asciiLabels.append('') except: asciiLabels = [str(label) for label in labels] - #RFC 3490, Section 4, Step 5 + # RFC 3490, Section 4, Step 5 return str(reduce(lambda x, y: x + unichr(0x002E) + y, asciiLabels)) def unicode_to_ascii_url(url, prepend_scheme): - ''' + """ Converts the inputed unicode url into a US-ASCII equivalent. This function goes a little beyond RFC 3490, which is limited in scope to the domain name (authority) only. Here, the functionality is expanded to what was observed @@ -1443,23 +1446,23 @@ def unicode_to_ascii_url(url, prepend_scheme): string: a US-ASCII equivalent of the inputed url @author: Jonathan Benn - ''' - #convert the authority component of the URL into an ASCII punycode string, - #but encode the rest using the regular URI character encoding + """ + # convert the authority component of the URL into an ASCII punycode string, + # but encode the rest using the regular URI character encoding groups = url_split_regex.match(url).groups() - #If no authority was found + # If no authority was found if not groups[3]: - #Try appending a scheme to see if that fixes the problem + # Try appending a scheme to see if that fixes the problem scheme_to_prepend = prepend_scheme or 'http' groups = url_split_regex.match( unicode(scheme_to_prepend) + u'://' + url).groups() - #if we still can't find the authority + # if we still can't find the authority if not groups[3]: raise Exception('No authority component found, ' + 'could not decode unicode to US-ASCII') - #We're here if we found an authority, let's rebuild the URL + # We're here if we found an authority, let's rebuild the URL scheme = groups[1] authority = groups[3] path = groups[4] or '' @@ -2047,12 +2050,12 @@ class IS_URL(Validator): try: asciiValue = unicode_to_ascii_url(value, self.prepend_scheme) except Exception: - #If we are not able to convert the unicode url into a + # If we are not able to convert the unicode url into a # US-ASCII URL, then the URL is not valid return (value, translate(self.error_message)) methodResult = subMethod(asciiValue) - #if the validation of the US-ASCII version of the value failed + # if the validation of the US-ASCII version of the value failed if not methodResult[1] is None: # then return the original input value, not the US-ASCII version return (value, methodResult[1]) @@ -2120,7 +2123,7 @@ class IS_TIME(Validator): if not value.group('s') is None: s = int(value.group('s')) if value.group('d') == 'pm' and 0 < h < 12: - h = h + 12 + h += 12 if value.group('d') == 'am' and h == 12: h = 0 if not (h in range(24) and m in range(60) and s @@ -2134,18 +2137,23 @@ class IS_TIME(Validator): pass return (ivalue, translate(self.error_message)) + # A UTC class. class UTC(datetime.tzinfo): """UTC""" ZERO = datetime.timedelta(0) + def utcoffset(self, dt): return UTC.ZERO + def tzname(self, dt): return "UTC" + def dst(self, dt): return UTC.ZERO utc = UTC() + class IS_DATE(Validator): """ Examples: @@ -2159,7 +2167,7 @@ class IS_DATE(Validator): def __init__(self, format='%Y-%m-%d', error_message='Enter date as %(format)s', - timezone = None): + timezone=None): self.format = translate(format) self.error_message = str(error_message) self.timezone = timezone @@ -2402,7 +2410,7 @@ class IS_LIST_OF(Validator): new_value = [] other = self.other if self.other: - if not isinstance(other, (list,tuple)): + if not isinstance(other, (list, tuple)): other = [other] for item in ivalue: v = item @@ -2625,7 +2633,7 @@ class IS_EMPTY_OR(Validator): return self.other.formatter(value) return value -IS_NULL_OR = IS_EMPTY_OR # for backward compatibility +IS_NULL_OR = IS_EMPTY_OR # for backward compatibility class CLEANUP(Validator): @@ -2735,6 +2743,7 @@ class LazyCrypt(object): def __ne__(self, other): return not self.__eq__(other) + class CRYPT(object): """ Examples: @@ -2852,7 +2861,7 @@ otherset = frozenset( def calc_entropy(string): - " calculates a simple entropy for a given string " + """ calculates a simple entropy for a given string """ import math alphabet = 0 # alphabet size other = set() @@ -3374,6 +3383,7 @@ class IS_IPV4(Validator): return (value, None) return (value, translate(self.error_message)) + class IS_IPV6(Validator): """ Checks if field's value is an IP version 6 address. First attempts to diff --git a/gluon/widget.py b/gluon/widget.py index 6c2ef628..e9902899 100644 --- a/gluon/widget.py +++ b/gluon/widget.py @@ -143,7 +143,7 @@ class web2pyDialog(object): root.withdraw() self.root = Tkinter.Toplevel(root, bg=bg_color) - self.root.resizable(0,0) + self.root.resizable(0, 0) self.root.title(ProgramName) self.options = options @@ -151,7 +151,7 @@ class web2pyDialog(object): self.menu = Tkinter.Menu(self.root) servermenu = Tkinter.Menu(self.menu, tearoff=0) httplog = os.path.join(self.options.folder, 'httpserver.log') - iconphoto = os.path.join('extras','icons','web2py.gif') + iconphoto = os.path.join('extras', 'icons', 'web2py.gif') if os.path.exists(iconphoto): img = Tkinter.PhotoImage(file=iconphoto) self.root.tk.call('wm', 'iconphoto', self.root._w, img) @@ -206,7 +206,7 @@ class web2pyDialog(object): self.logoarea.grid(row=0, column=0, columnspan=4, sticky=sticky) self.logoarea.after(1000, self.update_canvas) - logo = os.path.join('extras','icons','splashlogo.gif') + logo = os.path.join('extras', 'icons', 'splashlogo.gif') if os.path.exists(logo): img = Tkinter.PhotoImage(file=logo) pnl = Tkinter.Label(self.logoarea, image=img, background=bg_color, bd=0) @@ -261,8 +261,8 @@ class web2pyDialog(object): Tkinter.Label(self.root, text='Server Port:', bg=bg_color, justify=Tkinter.RIGHT).grid(row=shift, - column=1, pady=10, - sticky=sticky) + column=1, pady=10, + sticky=sticky) self.port_number = Tkinter.Entry(self.root) self.port_number.insert(Tkinter.END, self.options.port) @@ -272,8 +272,8 @@ class web2pyDialog(object): Tkinter.Label(self.root, text='Choose Password:', bg=bg_color, justify=Tkinter.RIGHT).grid(row=shift + 1, - column=1, - sticky=sticky) + column=1, + sticky=sticky) self.password = Tkinter.Entry(self.root, show='*') self.password.bind('', lambda e: self.start()) @@ -328,7 +328,7 @@ class web2pyDialog(object): if os.path.exists( 'applications/%s/models/scheduler.py' % arq)] if start: - #the widget takes care of starting the scheduler + # the widget takes care of starting the scheduler if self.options.scheduler and self.options.with_scheduler: apps = [app.strip() for app in self.options.scheduler.split(',') @@ -336,7 +336,7 @@ class web2pyDialog(object): for app in apps: self.try_start_scheduler(app) - #reset the menu + # reset the menu self.schedmenu.delete(0, len(available_apps)) for arq in available_apps: if arq not in self.scheduler_processes: @@ -413,7 +413,7 @@ class web2pyDialog(object): def connect_pages(self): """ Connects pages """ - #reset the menu + # reset the menu available_apps = [arq for arq in os.listdir('applications/') if os.path.exists( 'applications/%s/__init__.py' % arq)] @@ -939,19 +939,19 @@ def console(): if options.gae: if not os.path.exists('app.yaml'): name = raw_input("Your GAE app name: ") - content = open(os.path.join('examples','app.example.yaml'),'rb').read() - open('app.yaml','wb').write(content.replace("yourappname",name)) + content = open(os.path.join('examples', 'app.example.yaml'), 'rb').read() + open('app.yaml', 'wb').write(content.replace("yourappname", name)) else: print "app.yaml alreday exists in the web2py folder" if not os.path.exists('gaehandler.py'): - content = open(os.path.join('handlers','gaehandler.py'),'rb').read() - open('gaehandler.py','wb').write(content) + content = open(os.path.join('handlers', 'gaehandler.py'), 'rb').read() + open('gaehandler.py', 'wb').write(content) else: print "gaehandler.py alreday exists in the web2py folder" sys.exit(0) try: - options.ips = list(set( # no duplicates + options.ips = list(set( # no duplicates [addrinfo[4][0] for addrinfo in getipaddrinfo(socket.getfqdn()) if not is_loopback_ip_address(addrinfo=addrinfo)])) except socket.gaierror: @@ -1112,7 +1112,7 @@ def start(cron=True): if hasattr(options, key): setattr(options, key, getattr(options2, key)) - logfile0 = os.path.join('extras','examples','logging.example.conf') + logfile0 = os.path.join('extras', 'examples', 'logging.example.conf') if not os.path.exists('logging.conf') and os.path.exists(logfile0): import shutil sys.stdout.write("Copying logging.conf.example to logging.conf ... ") @@ -1183,7 +1183,7 @@ def start(cron=True): root = None - if not options.nogui and options.password=='': + if not options.nogui and options.password == '': try: import Tkinter havetk = True @@ -1263,6 +1263,7 @@ end tell # if the line was not found (under py2exe & when file was modified) import linecache py2exe_getline = linecache.getline + def getline(filename, lineno, *args, **kwargs): line = py2exe_getline(filename, lineno, *args, **kwargs) if not line: