Merge github.com:web2py/web2py
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 2.2.1 (2012-10-27 14:37:32) stable
|
Version 2.2.1 (2012-10-30 11:09:19) stable
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ class CacheInRam(CacheAbstract):
|
|||||||
def __init__(self, request=None):
|
def __init__(self, request=None):
|
||||||
self.initialized = False
|
self.initialized = False
|
||||||
self.request = request
|
self.request = request
|
||||||
|
self.storage = {}
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
if self.initialized:
|
if self.initialized:
|
||||||
@@ -303,6 +304,7 @@ class CacheOnDisk(CacheAbstract):
|
|||||||
self.initialized = False
|
self.initialized = False
|
||||||
self.request = request
|
self.request = request
|
||||||
self.folder = folder
|
self.folder = folder
|
||||||
|
self.storage = {}
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
if self.initialized:
|
if self.initialized:
|
||||||
|
|||||||
@@ -99,13 +99,21 @@ class DropboxAccount(object):
|
|||||||
redirect('https://www.dropbox.com/logout')
|
redirect('https://www.dropbox.com/logout')
|
||||||
return next
|
return next
|
||||||
|
|
||||||
|
def get_client(self):
|
||||||
|
access_token = current.session.dropbox_access_token
|
||||||
|
self.sess.set_token(access_token[0], access_token[1])
|
||||||
|
self.client = client.DropboxClient(self.sess)
|
||||||
|
|
||||||
def put(self, filename, file):
|
def put(self, filename, file):
|
||||||
|
if not hasattr(self,'client'): self.get_client()
|
||||||
return json.loads(self.client.put_file(filename, file))['bytes']
|
return json.loads(self.client.put_file(filename, file))['bytes']
|
||||||
|
|
||||||
def get(self, filename, file):
|
def get(self, filename, file):
|
||||||
|
if not hasattr(self,'client'): self.get_client()
|
||||||
return self.client.get_file(filename)
|
return self.client.get_file(filename)
|
||||||
|
|
||||||
def dir(self, path):
|
def dir(self, path):
|
||||||
|
if not hasattr(self,'client'): self.get_client()
|
||||||
return json.loads(self.client.metadata(path))
|
return json.loads(self.client.metadata(path))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+33
-2
@@ -26,6 +26,7 @@ including:
|
|||||||
- DB2
|
- DB2
|
||||||
- Interbase
|
- Interbase
|
||||||
- Ingres
|
- Ingres
|
||||||
|
- Informix
|
||||||
- SapDB (experimental)
|
- SapDB (experimental)
|
||||||
- Cubrid (experimental)
|
- Cubrid (experimental)
|
||||||
- CouchDB (experimental)
|
- CouchDB (experimental)
|
||||||
@@ -179,7 +180,7 @@ if PYTHON_VERSION == 2:
|
|||||||
bytes, unicode = str, unicode
|
bytes, unicode = str, unicode
|
||||||
else:
|
else:
|
||||||
import pickle
|
import pickle
|
||||||
from io import StringIO as StringIO
|
from io import StringIO as StringIO
|
||||||
import copyreg
|
import copyreg
|
||||||
long = int
|
long = int
|
||||||
hashlib_md5 = lambda s: hashlib.md5(bytes(s,'utf8'))
|
hashlib_md5 = lambda s: hashlib.md5(bytes(s,'utf8'))
|
||||||
@@ -255,6 +256,7 @@ REGEX_STORE_PATTERN = re.compile('\.(?P<e>\w{1,5})$')
|
|||||||
REGEX_QUOTES = re.compile("'[^']*'")
|
REGEX_QUOTES = re.compile("'[^']*'")
|
||||||
REGEX_ALPHANUMERIC = re.compile('^[0-9a-zA-Z]\w*$')
|
REGEX_ALPHANUMERIC = re.compile('^[0-9a-zA-Z]\w*$')
|
||||||
REGEX_PASSWORD = re.compile('\://([^:@]*)\:')
|
REGEX_PASSWORD = re.compile('\://([^:@]*)\:')
|
||||||
|
REGEX_NOPASSWD = re.compile('(?<=\:)([^:@/]+)(?=@.+)')
|
||||||
|
|
||||||
# list of drivers will be built on the fly
|
# list of drivers will be built on the fly
|
||||||
# and lists only what is available
|
# and lists only what is available
|
||||||
@@ -2105,7 +2107,7 @@ class SQLiteAdapter(BaseAdapter):
|
|||||||
dbpath = pjoin(
|
dbpath = pjoin(
|
||||||
self.folder.decode(path_encoding).encode('utf8'), dbpath)
|
self.folder.decode(path_encoding).encode('utf8'), dbpath)
|
||||||
else:
|
else:
|
||||||
dbpath = pjoin(self.folder, dbpath)
|
dbpath = pjoin(self.folder, dbpath)
|
||||||
if not 'check_same_thread' in driver_args:
|
if not 'check_same_thread' in driver_args:
|
||||||
driver_args['check_same_thread'] = False
|
driver_args['check_same_thread'] = False
|
||||||
if not 'detect_types' in driver_args:
|
if not 'detect_types' in driver_args:
|
||||||
@@ -6660,6 +6662,35 @@ class DAL(object):
|
|||||||
"""
|
"""
|
||||||
BaseAdapter.set_folder(folder)
|
BaseAdapter.set_folder(folder)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_instances():
|
||||||
|
"""
|
||||||
|
Returns a dictionary with uri as key with timings and defined tables
|
||||||
|
{'sqlite://storage.sqlite': {
|
||||||
|
'dbstats': [(select auth_user.email from auth_user, 0.02009)],
|
||||||
|
'dbtables': {
|
||||||
|
'defined': ['auth_cas', 'auth_event', 'auth_group',
|
||||||
|
'auth_membership', 'auth_permission', 'auth_user'],
|
||||||
|
'lazy': '[]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
dbs = getattr(THREAD_LOCAL,'db_instances',{}).items()
|
||||||
|
infos = {}
|
||||||
|
for db_uid, db_group in dbs:
|
||||||
|
for db in db_group:
|
||||||
|
if not db._uri:
|
||||||
|
continue
|
||||||
|
k = REGEX_NOPASSWD.sub('******',db._uri)
|
||||||
|
infos[k] = dict(dbstats = [(row[0], row[1]) for row in db._timings],
|
||||||
|
dbtables = {'defined':
|
||||||
|
sorted(list(set(db.tables) -
|
||||||
|
set(db._LAZY_TABLES.keys()))),
|
||||||
|
'lazy': sorted(db._LAZY_TABLES.keys())}
|
||||||
|
)
|
||||||
|
return infos
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def distributed_transaction_begin(*instances):
|
def distributed_transaction_begin(*instances):
|
||||||
if not instances:
|
if not instances:
|
||||||
|
|||||||
+15
-19
@@ -48,7 +48,6 @@ except ImportError:
|
|||||||
have_minify = False
|
have_minify = False
|
||||||
|
|
||||||
regex_session_id = re.compile('^([\w\-]+/)?[\w\-\.]+$')
|
regex_session_id = re.compile('^([\w\-]+/)?[\w\-\.]+$')
|
||||||
regex_nopasswd = re.compile('(?<=\:)([^:@/]+)(?=@.+)')
|
|
||||||
|
|
||||||
__all__ = ['Request', 'Response', 'Session']
|
__all__ = ['Request', 'Response', 'Session']
|
||||||
|
|
||||||
@@ -127,7 +126,10 @@ class Request(Storage):
|
|||||||
If request comes in over HTTP, redirect it to HTTPS
|
If request comes in over HTTP, redirect it to HTTPS
|
||||||
and secure the session.
|
and secure the session.
|
||||||
"""
|
"""
|
||||||
if not global_settings.cronjob and not self.is_https:
|
cmd_opts = global_settings.cmd_options
|
||||||
|
#checking if this is called within the scheduler or within the shell
|
||||||
|
#in addition to checking if it's not a cronjob
|
||||||
|
if not cmd_opts.shell and not cmd_opts.scheduler and not global_settings.cronjob and not self.is_https:
|
||||||
current.session.forget()
|
current.session.forget()
|
||||||
redirect(URL(scheme='https', args=self.args, vars=self.vars))
|
redirect(URL(scheme='https', args=self.args, vars=self.vars))
|
||||||
|
|
||||||
@@ -434,22 +436,16 @@ class Response(Storage):
|
|||||||
BUTTON = TAG.button
|
BUTTON = TAG.button
|
||||||
admin = URL("admin", "default", "design",
|
admin = URL("admin", "default", "design",
|
||||||
args=current.request.application)
|
args=current.request.application)
|
||||||
from gluon.dal import THREAD_LOCAL
|
from gluon.dal import DAL
|
||||||
if hasattr(THREAD_LOCAL, 'instances'):
|
dbstats = []
|
||||||
dbstats = [TABLE(*[TR(PRE(row[0]), '%.2fms' % (row[1] * 1000))
|
dbtables = {}
|
||||||
for row in i.db._timings])
|
infos = DAL.get_instances()
|
||||||
for i in THREAD_LOCAL.instances]
|
for k,v in infos.iteritems():
|
||||||
dbtables = dict([(regex_nopasswd.sub('******', i.uri),
|
dbstats.append(TABLE(*[TR(PRE(row[0]),'%.2fms' %
|
||||||
{'defined':
|
(row[1]*1000))
|
||||||
sorted(list(set(i.db.tables) -
|
for row in v['dbstats']]))
|
||||||
set(i.db._LAZY_TABLES.keys()))) or
|
dbtables[k] = dict(defined=v['dbtables']['defined'] or '[no defined tables]',
|
||||||
'[no defined tables]',
|
lazy=v['dbtables']['lazy'] or '[no lazy tables]')
|
||||||
'lazy': sorted(i.db._LAZY_TABLES.keys()) or
|
|
||||||
'[no lazy tables]'})
|
|
||||||
for i in THREAD_LOCAL.instances])
|
|
||||||
else:
|
|
||||||
dbstats = [] # if no db or on GAE
|
|
||||||
dbtables = {}
|
|
||||||
u = web2py_uuid()
|
u = web2py_uuid()
|
||||||
backtotop = A('Back to top', _href="#totop-%s" % u)
|
backtotop = A('Back to top', _href="#totop-%s" % u)
|
||||||
return DIV(
|
return DIV(
|
||||||
@@ -507,7 +503,7 @@ class Session(Storage):
|
|||||||
request = current.request
|
request = current.request
|
||||||
if response is None:
|
if response is None:
|
||||||
response = current.response
|
response = current.response
|
||||||
if separate == True:
|
if separate is True:
|
||||||
separate = lambda session_name: session_name[-2:]
|
separate = lambda session_name: session_name[-2:]
|
||||||
self._unlock(response)
|
self._unlock(response)
|
||||||
if not masterapp:
|
if not masterapp:
|
||||||
|
|||||||
+6
-1
@@ -140,7 +140,7 @@ class HTTP(BaseException):
|
|||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
def redirect(location, how=303, client_side=False):
|
def redirect(location='', how=303, client_side=False):
|
||||||
if location:
|
if location:
|
||||||
from gluon import current
|
from gluon import current
|
||||||
loc = location.replace('\r', '%0D').replace('\n', '%0A')
|
loc = location.replace('\r', '%0D').replace('\n', '%0A')
|
||||||
@@ -150,3 +150,8 @@ def redirect(location, how=303, client_side=False):
|
|||||||
raise HTTP(how,
|
raise HTTP(how,
|
||||||
'You are being redirected <a href="%s">here</a>' % loc,
|
'You are being redirected <a href="%s">here</a>' % loc,
|
||||||
Location=loc)
|
Location=loc)
|
||||||
|
else:
|
||||||
|
from gluon import current
|
||||||
|
if client_side and current.request.ajax:
|
||||||
|
raise HTTP(200, **{'web2py-component-command': 'window.location.reload(true)'})
|
||||||
|
|
||||||
+44
-23
@@ -1365,13 +1365,13 @@ class Auth(object):
|
|||||||
archive_names='%(tablename)s_archive',
|
archive_names='%(tablename)s_archive',
|
||||||
current_record='current_record'):
|
current_record='current_record'):
|
||||||
"""
|
"""
|
||||||
to enable full record vernionioning (including auth tables):
|
to enable full record versioning (including auth tables):
|
||||||
|
|
||||||
auth = Auth(db)
|
auth = Auth(db)
|
||||||
auth.define_tables(signature=True)
|
auth.define_tables(signature=True)
|
||||||
# define our own tables
|
# define our own tables
|
||||||
db.define_table('mything',Field('name'),auth.signature)
|
db.define_table('mything',Field('name'),auth.signature)
|
||||||
auth.enable_record_vernining(tables=db)
|
auth.enable_record_versioning(tables=db)
|
||||||
|
|
||||||
tables can be the db (all table) or a list of tables.
|
tables can be the db (all table) or a list of tables.
|
||||||
only tables with modified_by and modified_on fiels (as created
|
only tables with modified_by and modified_on fiels (as created
|
||||||
@@ -1386,7 +1386,7 @@ class Auth(object):
|
|||||||
|
|
||||||
Important: If you use auth.enable_record_versioning,
|
Important: If you use auth.enable_record_versioning,
|
||||||
do not use auth.archive or you will end up with duplicates.
|
do not use auth.archive or you will end up with duplicates.
|
||||||
auth.archive does explicitely what enable_record_versioning
|
auth.archive does explicitly what enable_record_versioning
|
||||||
does automatically.
|
does automatically.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -1489,7 +1489,7 @@ class Auth(object):
|
|||||||
IS_NOT_IN_DB(db, '%s.username' % settings.table_user_name)]
|
IS_NOT_IN_DB(db, '%s.username' % settings.table_user_name)]
|
||||||
if not settings.username_case_sensitive:
|
if not settings.username_case_sensitive:
|
||||||
is_unique_username.insert(1, IS_LOWER())
|
is_unique_username.insert(1, IS_LOWER())
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_user_name,
|
settings.table_user_name,
|
||||||
Field('first_name', length=128, default='',
|
Field('first_name', length=128, default='',
|
||||||
label=self.messages.label_first_name,
|
label=self.messages.label_first_name,
|
||||||
@@ -1522,7 +1522,7 @@ class Auth(object):
|
|||||||
fake_migrate=fake_migrate,
|
fake_migrate=fake_migrate,
|
||||||
format='%(username)s'))
|
format='%(username)s'))
|
||||||
else:
|
else:
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_user_name,
|
settings.table_user_name,
|
||||||
Field('first_name', length=128, default='',
|
Field('first_name', length=128, default='',
|
||||||
label=self.messages.label_first_name,
|
label=self.messages.label_first_name,
|
||||||
@@ -1555,7 +1555,7 @@ class Auth(object):
|
|||||||
if not settings.table_group_name in db.tables:
|
if not settings.table_group_name in db.tables:
|
||||||
extra_fields = settings.extra_fields.get(
|
extra_fields = settings.extra_fields.get(
|
||||||
settings.table_group_name, []) + signature_list
|
settings.table_group_name, []) + signature_list
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_group_name,
|
settings.table_group_name,
|
||||||
Field('role', length=512, default='',
|
Field('role', length=512, default='',
|
||||||
label=self.messages.label_role,
|
label=self.messages.label_role,
|
||||||
@@ -1573,7 +1573,7 @@ class Auth(object):
|
|||||||
if not settings.table_membership_name in db.tables:
|
if not settings.table_membership_name in db.tables:
|
||||||
extra_fields = settings.extra_fields.get(
|
extra_fields = settings.extra_fields.get(
|
||||||
settings.table_membership_name, []) + signature_list
|
settings.table_membership_name, []) + signature_list
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_membership_name,
|
settings.table_membership_name,
|
||||||
Field('user_id', reference_table_user,
|
Field('user_id', reference_table_user,
|
||||||
label=self.messages.label_user_id),
|
label=self.messages.label_user_id),
|
||||||
@@ -1587,7 +1587,7 @@ class Auth(object):
|
|||||||
if not settings.table_permission_name in db.tables:
|
if not settings.table_permission_name in db.tables:
|
||||||
extra_fields = settings.extra_fields.get(
|
extra_fields = settings.extra_fields.get(
|
||||||
settings.table_permission_name, []) + signature_list
|
settings.table_permission_name, []) + signature_list
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_permission_name,
|
settings.table_permission_name,
|
||||||
Field('group_id', reference_table_group,
|
Field('group_id', reference_table_group,
|
||||||
label=self.messages.label_group_id),
|
label=self.messages.label_group_id),
|
||||||
@@ -1605,7 +1605,7 @@ class Auth(object):
|
|||||||
settings.table_permission_name, migrate),
|
settings.table_permission_name, migrate),
|
||||||
fake_migrate=fake_migrate))
|
fake_migrate=fake_migrate))
|
||||||
if not settings.table_event_name in db.tables:
|
if not settings.table_event_name in db.tables:
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_event_name,
|
settings.table_event_name,
|
||||||
Field('time_stamp', 'datetime',
|
Field('time_stamp', 'datetime',
|
||||||
default=current.request.now,
|
default=current.request.now,
|
||||||
@@ -1629,7 +1629,7 @@ class Auth(object):
|
|||||||
now = current.request.now
|
now = current.request.now
|
||||||
if settings.cas_domains:
|
if settings.cas_domains:
|
||||||
if not settings.table_cas_name in db.tables:
|
if not settings.table_cas_name in db.tables:
|
||||||
table = db.define_table(
|
db.define_table(
|
||||||
settings.table_cas_name,
|
settings.table_cas_name,
|
||||||
Field('user_id', reference_table_user, default=None,
|
Field('user_id', reference_table_user, default=None,
|
||||||
label=self.messages.label_user_id),
|
label=self.messages.label_user_id),
|
||||||
@@ -1773,8 +1773,6 @@ class Auth(object):
|
|||||||
"""
|
"""
|
||||||
logins user as specified by usernname (or email) and password
|
logins user as specified by usernname (or email) and password
|
||||||
"""
|
"""
|
||||||
request = current.request
|
|
||||||
session = current.session
|
|
||||||
table_user = self.table_user()
|
table_user = self.table_user()
|
||||||
if self.settings.login_userfield:
|
if self.settings.login_userfield:
|
||||||
userfield = self.settings.login_userfield
|
userfield = self.settings.login_userfield
|
||||||
@@ -2669,7 +2667,6 @@ class Auth(object):
|
|||||||
redirect(self.settings.login_url)
|
redirect(self.settings.login_url)
|
||||||
db = self.db
|
db = self.db
|
||||||
table_user = self.table_user()
|
table_user = self.table_user()
|
||||||
usern = self.settings.table_user_name
|
|
||||||
s = db(table_user.id == self.user.id)
|
s = db(table_user.id == self.user.id)
|
||||||
|
|
||||||
request = current.request
|
request = current.request
|
||||||
@@ -2717,7 +2714,7 @@ class Auth(object):
|
|||||||
next = self.url(args=request.args)
|
next = self.url(args=request.args)
|
||||||
else:
|
else:
|
||||||
next = replace_id(next, form)
|
next = replace_id(next, form)
|
||||||
redirect(next)
|
redirect(next)
|
||||||
return form
|
return form
|
||||||
|
|
||||||
def profile(
|
def profile(
|
||||||
@@ -2990,10 +2987,12 @@ class Auth(object):
|
|||||||
return self.id_group(self.user_group_role(user_id))
|
return self.id_group(self.user_group_role(user_id))
|
||||||
|
|
||||||
def user_group_role(self, user_id=None):
|
def user_group_role(self, user_id=None):
|
||||||
|
if not self.settings.create_user_groups:
|
||||||
|
return None
|
||||||
if user_id:
|
if user_id:
|
||||||
user = self.table_user()[user_id]
|
user = self.table_user()[user_id]
|
||||||
else:
|
else:
|
||||||
user = self.user
|
user = self.user
|
||||||
return self.settings.create_user_groups % user
|
return self.settings.create_user_groups % user
|
||||||
|
|
||||||
def has_membership(self, group_id=None, user_id=None, role=None):
|
def has_membership(self, group_id=None, user_id=None, role=None):
|
||||||
@@ -4139,12 +4138,13 @@ class Service(object):
|
|||||||
return '<NULL>'
|
return '<NULL>'
|
||||||
return value
|
return value
|
||||||
if args and args[0] in self.run_procedures:
|
if args and args[0] in self.run_procedures:
|
||||||
|
import types
|
||||||
r = universal_caller(self.run_procedures[args[0]],
|
r = universal_caller(self.run_procedures[args[0]],
|
||||||
*args[1:], **dict(request.vars))
|
*args[1:], **dict(request.vars))
|
||||||
s = cStringIO.StringIO()
|
s = cStringIO.StringIO()
|
||||||
if hasattr(r, 'export_to_csv_file'):
|
if hasattr(r, 'export_to_csv_file'):
|
||||||
r.export_to_csv_file(s)
|
r.export_to_csv_file(s)
|
||||||
elif r and isinstance(r[0], (dict, Storage)):
|
elif r and not isinstance(r, types.GeneratorType) and isinstance(r[0], (dict, Storage)):
|
||||||
import csv
|
import csv
|
||||||
writer = csv.writer(s)
|
writer = csv.writer(s)
|
||||||
writer.writerow(r[0].keys())
|
writer.writerow(r[0].keys())
|
||||||
@@ -4656,7 +4656,7 @@ class Wiki(object):
|
|||||||
html = page.body
|
html = page.body
|
||||||
# @///function -> http://..../function
|
# @///function -> http://..../function
|
||||||
html = replace_at_urls(html, URL)
|
html = replace_at_urls(html, URL)
|
||||||
# http://...jpg -> <img src="http://...jpg/> or oembed
|
# http://...jpg -> <img src="http://...jpg/> or embed
|
||||||
html = replace_autolinks(html, lambda link: expand_one(link, {}))
|
html = replace_autolinks(html, lambda link: expand_one(link, {}))
|
||||||
# @{component:name} -> <script>embed component name</script>
|
# @{component:name} -> <script>embed component name</script>
|
||||||
html = replace_components(html, self.env)
|
html = replace_components(html, self.env)
|
||||||
@@ -4898,14 +4898,15 @@ class Wiki(object):
|
|||||||
% self.force_prefix
|
% self.force_prefix
|
||||||
redirect(URL(args=('_edit', self.force_prefix + slug)))
|
redirect(URL(args=('_edit', self.force_prefix + slug)))
|
||||||
db.wiki_page.can_read.default = [Wiki.everybody]
|
db.wiki_page.can_read.default = [Wiki.everybody]
|
||||||
db.wiki_page.can_edit.default = [auth.user_group_role()]
|
user_group_role = auth.user_group_role()
|
||||||
|
db.wiki_page.can_edit.default = [user_group_role]
|
||||||
db.wiki_page.title.default = title_guess
|
db.wiki_page.title.default = title_guess
|
||||||
db.wiki_page.slug.default = slug
|
db.wiki_page.slug.default = slug
|
||||||
if slug == 'wiki-menu':
|
if slug == 'wiki-menu':
|
||||||
db.wiki_page.body.default = \
|
db.wiki_page.body.default = \
|
||||||
'- Menu Item > @////index\n- - Submenu > http://web2py.com'
|
'- Menu Item > @////index\n- - Submenu > http://web2py.com'
|
||||||
else:
|
else:
|
||||||
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
db.wiki_page.body.default = '## %s\n\npage content\n\n[[new page @////new_page]]\n' % title_guess
|
||||||
vars = current.request.post_vars
|
vars = current.request.post_vars
|
||||||
if vars.body:
|
if vars.body:
|
||||||
vars.body = vars.body.replace('://%s' % self.host, '://HOSTNAME')
|
vars.body = vars.body.replace('://%s' % self.host, '://HOSTNAME')
|
||||||
@@ -4924,12 +4925,20 @@ class Wiki(object):
|
|||||||
pagecontent.css('font-family',
|
pagecontent.css('font-family',
|
||||||
'Monaco,Menlo,Consolas,"Courier New",monospace');
|
'Monaco,Menlo,Consolas,"Courier New",monospace');
|
||||||
var prevbutton = $('<button class="btn nopreview">Preview</button>');
|
var prevbutton = $('<button class="btn nopreview">Preview</button>');
|
||||||
|
var mediabutton = $('<button class="btn nopreview">Media</button>');
|
||||||
var preview = $('<div id="preview"></div>').hide();
|
var preview = $('<div id="preview"></div>').hide();
|
||||||
|
var previewmedia = $('<div id="previewmedia"></div>');
|
||||||
var table = $('form');
|
var table = $('form');
|
||||||
prevbutton.insertBefore(table);
|
|
||||||
preview.insertBefore(table);
|
preview.insertBefore(table);
|
||||||
prevbutton.on('click', function(e) {
|
prevbutton.insertBefore(table);
|
||||||
e.preventDefault();
|
mediabutton.insertBefore(table);
|
||||||
|
previewmedia.insertBefore(table);
|
||||||
|
mediabutton.toggle(function() {
|
||||||
|
web2py_component('%(urlmedia)s', 'previewmedia');
|
||||||
|
}, function() {
|
||||||
|
previewmedia.empty();
|
||||||
|
});
|
||||||
|
prevbutton.click(function() {
|
||||||
if (prevbutton.hasClass('nopreview')) {
|
if (prevbutton.hasClass('nopreview')) {
|
||||||
prevbutton.addClass('preview').removeClass(
|
prevbutton.addClass('preview').removeClass(
|
||||||
'nopreview').html('Edit Source');
|
'nopreview').html('Edit Source');
|
||||||
@@ -4942,7 +4951,7 @@ class Wiki(object):
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
""" % dict(url=URL(args=('_preview')))
|
""" % dict(url=URL(args=('_preview')), urlmedia=URL(extension='load',args=('_editmedia'),vars=dict(embedded=1)))
|
||||||
return dict(content=TAG[''](form, SCRIPT(script)))
|
return dict(content=TAG[''](form, SCRIPT(script)))
|
||||||
|
|
||||||
def editmedia(self, slug):
|
def editmedia(self, slug):
|
||||||
@@ -4958,9 +4967,21 @@ class Wiki(object):
|
|||||||
row.filename.split('.')[-1]))
|
row.filename.split('.')[-1]))
|
||||||
self.auth.db.wiki_media.wiki_page.default = page.id
|
self.auth.db.wiki_media.wiki_page.default = page.id
|
||||||
self.auth.db.wiki_media.wiki_page.writable = False
|
self.auth.db.wiki_media.wiki_page.writable = False
|
||||||
|
links = []
|
||||||
|
csv = True
|
||||||
|
if current.request.vars.embedded:
|
||||||
|
script = "var c = $('#wiki_page_body'); c.val(c.val() + $('%s').text()); return false;"
|
||||||
|
fragment = self.auth.db.wiki_media.id.represent
|
||||||
|
csv = False
|
||||||
|
links=[
|
||||||
|
lambda row:
|
||||||
|
A('copy into source', _href='#', _onclick=script % (fragment(row.id, row)))
|
||||||
|
]
|
||||||
content = SQLFORM.grid(
|
content = SQLFORM.grid(
|
||||||
self.auth.db.wiki_media.wiki_page == page.id,
|
self.auth.db.wiki_media.wiki_page == page.id,
|
||||||
orderby=self.auth.db.wiki_media.title,
|
orderby=self.auth.db.wiki_media.title,
|
||||||
|
links = links,
|
||||||
|
csv = csv,
|
||||||
args=['_editmedia', slug],
|
args=['_editmedia', slug],
|
||||||
user_signature=False)
|
user_signature=False)
|
||||||
return dict(content=content)
|
return dict(content=content)
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from .aes import AES
|
from .aes import AES
|
||||||
except ImportError:
|
except (ImportError, ValueError):
|
||||||
from contrib.aes import AES
|
from contrib.aes import AES
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -778,6 +778,8 @@ class IS_FLOAT_IN_RANGE(Validator):
|
|||||||
return (value, self.error_message)
|
return (value, self.error_message)
|
||||||
|
|
||||||
def formatter(self, value):
|
def formatter(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
return str2dec(value).replace('.', self.dot)
|
return str2dec(value).replace('.', self.dot)
|
||||||
|
|
||||||
|
|
||||||
@@ -882,6 +884,8 @@ class IS_DECIMAL_IN_RANGE(Validator):
|
|||||||
return (value, self.error_message)
|
return (value, self.error_message)
|
||||||
|
|
||||||
def formatter(self, value):
|
def formatter(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
return str2dec(value).replace('.', self.dot)
|
return str2dec(value).replace('.', self.dot)
|
||||||
|
|
||||||
|
|
||||||
@@ -2170,6 +2174,8 @@ class IS_DATE(Validator):
|
|||||||
return (value, translate(self.error_message) % self.extremes)
|
return (value, translate(self.error_message) % self.extremes)
|
||||||
|
|
||||||
def formatter(self, value):
|
def formatter(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
format = self.format
|
format = self.format
|
||||||
year = value.year
|
year = value.year
|
||||||
y = '%.4i' % year
|
y = '%.4i' % year
|
||||||
@@ -2228,6 +2234,8 @@ class IS_DATETIME(Validator):
|
|||||||
return (value, translate(self.error_message) % self.extremes)
|
return (value, translate(self.error_message) % self.extremes)
|
||||||
|
|
||||||
def formatter(self, value):
|
def formatter(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
format = self.format
|
format = self.format
|
||||||
year = value.year
|
year = value.year
|
||||||
y = '%.4i' % year
|
y = '%.4i' % year
|
||||||
|
|||||||
@@ -95,8 +95,9 @@ class SessionSetDb(SessionSet):
|
|||||||
"""Return list of SessionDb instances for existing sessions."""
|
"""Return list of SessionDb instances for existing sessions."""
|
||||||
sessions = []
|
sessions = []
|
||||||
table = current.response.session_db_table
|
table = current.response.session_db_table
|
||||||
for row in table._db(table.id > 0).select():
|
if table:
|
||||||
sessions.append(SessionDb(row))
|
for row in table._db(table.id > 0).select():
|
||||||
|
sessions.append(SessionDb(row))
|
||||||
return sessions
|
return sessions
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+39
-32
@@ -7,14 +7,10 @@ import sys
|
|||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from gluon.languages import findT, utf8_repr
|
from gluon.languages import findT
|
||||||
|
|
||||||
sys.path.insert(0, '.')
|
sys.path.insert(0, '.')
|
||||||
|
|
||||||
file = sys.argv[1]
|
|
||||||
apps = sys.argv[2:]
|
|
||||||
|
|
||||||
|
|
||||||
def sync_language(d, data):
|
def sync_language(d, data):
|
||||||
''' this function makes sure a translated string will be prefered over an untranslated
|
''' this function makes sure a translated string will be prefered over an untranslated
|
||||||
string when syncing languages between apps. when both are translated, it prefers the
|
string when syncing languages between apps. when both are translated, it prefers the
|
||||||
@@ -37,35 +33,46 @@ def sync_language(d, data):
|
|||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
d = {}
|
def sync_main(file, apps):
|
||||||
for app in apps:
|
d = {}
|
||||||
path = 'applications/%s/' % app
|
for app in apps:
|
||||||
findT(path, file)
|
path = 'applications/%s/' % app
|
||||||
langfile = open(os.path.join(path, 'languages', '%s.py' % file))
|
findT(path, file)
|
||||||
|
langfile = open(os.path.join(path, 'languages', '%s.py' % file))
|
||||||
|
try:
|
||||||
|
data = eval(langfile.read())
|
||||||
|
finally:
|
||||||
|
langfile.close()
|
||||||
|
|
||||||
|
d = sync_language(d, data)
|
||||||
|
|
||||||
|
|
||||||
|
path = 'applications/%s/' % apps[-1]
|
||||||
|
file1 = os.path.join(path, 'languages', '%s.py' % file)
|
||||||
|
|
||||||
|
f = open(file1, 'w')
|
||||||
try:
|
try:
|
||||||
data = eval(langfile.read())
|
f.write('# coding: utf8\n')
|
||||||
|
f.write('{\n')
|
||||||
|
keys = d.keys()
|
||||||
|
keys.sort()
|
||||||
|
for key in keys:
|
||||||
|
f.write("'''%s''':'''%s''',\n" % (key.replace("'", "\\'"), str(d[key].replace("'", "\\'"))))
|
||||||
|
f.write('}\n')
|
||||||
finally:
|
finally:
|
||||||
langfile.close()
|
f.close()
|
||||||
|
|
||||||
|
oapps = reversed(apps[:-1])
|
||||||
|
for app in oapps:
|
||||||
|
path2 = 'applications/%s/' % app
|
||||||
|
file2 = os.path.join(path2, 'languages', '%s.py' % file)
|
||||||
|
if file1 != file2:
|
||||||
|
shutil.copyfile(file1, file2)
|
||||||
|
|
||||||
d = sync_language(d, data)
|
if __name__ == "__main__":
|
||||||
|
|
||||||
path = 'applications/%s/' % apps[-1]
|
file = sys.argv[1]
|
||||||
file1 = os.path.join(path, 'languages', '%s.py' % file)
|
apps = sys.argv[2:]
|
||||||
|
|
||||||
f = open(file1, 'w')
|
sync_main(file, apps)
|
||||||
try:
|
|
||||||
f.write('# coding: utf8\n')
|
|
||||||
f.write('{\n')
|
|
||||||
keys = d.keys()
|
|
||||||
keys.sort()
|
|
||||||
for key in keys:
|
|
||||||
f.write('%s:%s,\n' % (utf8_repr(key), utf8_repr(str(d[key]))))
|
|
||||||
f.write('}\n')
|
|
||||||
finally:
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
oapps = reversed(apps[:-1])
|
|
||||||
for app in oapps:
|
|
||||||
path2 = 'applications/%s/' % app
|
|
||||||
file2 = os.path.join(path2, 'languages', '%s.py' % file)
|
|
||||||
shutil.copyfile(file1, file2)
|
|
||||||
Reference in New Issue
Block a user